mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Added WindowsPS version check for WinCompat (#11148)
This commit is contained in:
committed by
Aditya Patwardhan
parent
9649a85ce9
commit
0c46e3e71d
@@ -1881,13 +1881,22 @@ namespace Microsoft.PowerShell.Commands
|
||||
|
||||
internal override IList<PSModuleInfo> ImportModulesUsingWinCompat(IEnumerable<string> moduleNames, IEnumerable<ModuleSpecification> moduleFullyQualifiedNames, ImportModuleOptions importModuleOptions)
|
||||
{
|
||||
IList<PSModuleInfo> moduleProxyList = new List<PSModuleInfo>();
|
||||
#if !UNIX
|
||||
var winPSVersionString = Utils.GetWindowsPowerShellVersionFromRegistry();
|
||||
if (!winPSVersionString.StartsWith("5.1", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
string errorMessage = string.Format(CultureInfo.InvariantCulture, Modules.WinCompatRequredVersionError, winPSVersionString);
|
||||
throw new InvalidOperationException(errorMessage);
|
||||
}
|
||||
|
||||
PSSession WindowsPowerShellCompatRemotingSession = CreateWindowsPowerShellCompatResources();
|
||||
if (WindowsPowerShellCompatRemotingSession == null)
|
||||
{
|
||||
return new List<PSModuleInfo>();
|
||||
}
|
||||
|
||||
var moduleProxyList = ImportModule_RemotelyViaPsrpSession(importModuleOptions, moduleNames, moduleFullyQualifiedNames, WindowsPowerShellCompatRemotingSession, usingWinCompat: true);
|
||||
moduleProxyList = ImportModule_RemotelyViaPsrpSession(importModuleOptions, moduleNames, moduleFullyQualifiedNames, WindowsPowerShellCompatRemotingSession, usingWinCompat: true);
|
||||
foreach(PSModuleInfo moduleProxy in moduleProxyList)
|
||||
{
|
||||
moduleProxy.IsWindowsPowerShellCompatModule = true;
|
||||
@@ -1896,7 +1905,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
string message = StringUtil.Format(Modules.WinCompatModuleWarning, moduleProxy.Name, WindowsPowerShellCompatRemotingSession.Name);
|
||||
WriteWarning(message);
|
||||
}
|
||||
|
||||
#endif
|
||||
return moduleProxyList;
|
||||
}
|
||||
|
||||
|
||||
@@ -446,6 +446,41 @@ namespace System.Management.Automation
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string s_windowsPowerShellVersion = null;
|
||||
|
||||
/// <summary>
|
||||
/// Get the Windows PowerShell version from registry.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// String of Windows PowerShell version from registry.
|
||||
/// </returns>
|
||||
internal static string GetWindowsPowerShellVersionFromRegistry()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(InternalTestHooks.TestWindowsPowerShellVersionString))
|
||||
{
|
||||
return InternalTestHooks.TestWindowsPowerShellVersionString;
|
||||
}
|
||||
|
||||
if (s_windowsPowerShellVersion != null)
|
||||
{
|
||||
return s_windowsPowerShellVersion;
|
||||
}
|
||||
|
||||
string engineKeyPath = RegistryStrings.MonadRootKeyPath + "\\" +
|
||||
PSVersionInfo.RegistryVersionKey + "\\" + RegistryStrings.MonadEngineKey;
|
||||
|
||||
using (RegistryKey engineKey = Registry.LocalMachine.OpenSubKey(engineKeyPath))
|
||||
{
|
||||
if (engineKey != null)
|
||||
{
|
||||
s_windowsPowerShellVersion = engineKey.GetValue(RegistryStrings.MonadEngine_MonadVersion) as string;
|
||||
return s_windowsPowerShellVersion;
|
||||
}
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
#endif
|
||||
|
||||
internal static string DefaultPowerShellAppBase => GetApplicationBase(DefaultPowerShellShellID);
|
||||
@@ -2036,6 +2071,9 @@ namespace System.Management.Automation.Internal
|
||||
// since we can't manipulate the System32 directory in a test
|
||||
internal static string TestWindowsPowerShellPSHomeLocation;
|
||||
|
||||
// A version of Windows PS that is installed on the system; normally this is retrieved from a reg key that is write-protected.
|
||||
internal static string TestWindowsPowerShellVersionString;
|
||||
|
||||
internal static bool ShowMarkdownOutputBypass;
|
||||
|
||||
/// <summary>This member is used for internal test purposes.</summary>
|
||||
|
||||
@@ -1160,8 +1160,9 @@ namespace Microsoft.PowerShell.Commands
|
||||
|
||||
NewProcessConnectionInfo connectionInfo = new NewProcessConnectionInfo(this.Credential);
|
||||
connectionInfo.AuthenticationMechanism = this.Authentication;
|
||||
#if !UNIX
|
||||
connectionInfo.PSVersion = new Version(5, 1);
|
||||
|
||||
#endif
|
||||
var typeTable = TypeTable.LoadDefaultTypeFiles();
|
||||
string runspaceName = GetRunspaceName(0, out int runspaceIdUnused);
|
||||
remoteRunspaces.Add(RunspaceFactory.CreateRunspace(connectionInfo: connectionInfo,
|
||||
|
||||
@@ -513,6 +513,9 @@
|
||||
<data name="WinCompatModuleWarning" xml:space="preserve">
|
||||
<value>Module {0} is loaded in Windows PowerShell using {1} remoting session; please note that all input and output of commands from this module will be deserialized objects. If you want to load this module into PowerShell Core please use 'Import-Module -SkipEditionCheck' syntax.</value>
|
||||
</data>
|
||||
<data name="WinCompatRequredVersionError" xml:space="preserve">
|
||||
<value>Detected Windows PowerShell version {0}. Windows PowerShell 5.1 is required to load modules using Windows PowerShell compatibility feature. Install Windows Management Framework (WMF) 5.1 from https://aka.ms/WMF5Download to enable this feature.</value>
|
||||
</data>
|
||||
<data name="PsModuleOverCimSessionError" xml:space="preserve">
|
||||
<value>The module {0} cannot be imported over a CimSession. Try using the PSSession parameter of the Import-Module cmdlet.</value>
|
||||
</data>
|
||||
|
||||
+28
-1
@@ -246,7 +246,16 @@ Describe "Import-Module from CompatiblePSEditions-checked paths" -Tag "CI" {
|
||||
New-TestModules -TestCases $successCases -BaseDir $basePath
|
||||
New-TestModules -TestCases $failCases -BaseDir $basePath
|
||||
|
||||
$allModules = ($successCases + $failCases).ModuleName
|
||||
$allCases = $successCases + $failCases
|
||||
$allModules = $allCases.ModuleName
|
||||
$versionTestCases = @()
|
||||
foreach($versionString in @('1.0','2.0','3.0','4.0','5.0','5.1','5.1.14393.0'))
|
||||
{
|
||||
foreach($case in $allCases)
|
||||
{
|
||||
$versionTestCases += $case + @{WinPSVersion = $versionString}
|
||||
}
|
||||
}
|
||||
|
||||
# make sure there are no ImplicitRemoting leftovers from previous tests
|
||||
Get-Module | Where-Object {$_.PrivateData.ImplicitRemoting} | Remove-Module -Force
|
||||
@@ -300,6 +309,24 @@ Describe "Import-Module from CompatiblePSEditions-checked paths" -Tag "CI" {
|
||||
Import-Module $ModuleName -UseWindowsPowerShell -Force
|
||||
& "Test-${ModuleName}PSEdition" | Should -Be 'Desktop'
|
||||
}
|
||||
|
||||
It "WinCompat works only with Windows PS 5.1 (when PSEdition <Editions> and WinPSVersion <WinPSVersion>)" -TestCases $versionTestCases -Skip:(-not $IsWindows) {
|
||||
param($Editions, $ModuleName, $Result, $WinPSVersion)
|
||||
|
||||
try {
|
||||
[System.Management.Automation.Internal.InternalTestHooks]::SetTestHook("TestWindowsPowerShellVersionString", $WinPSVersion)
|
||||
if ($WinPSVersion.StartsWith('5.1')) {
|
||||
Import-Module $ModuleName -UseWindowsPowerShell -Force
|
||||
& "Test-${ModuleName}PSEdition" | Should -Be 'Desktop'
|
||||
}
|
||||
else {
|
||||
{ Import-Module $ModuleName -UseWindowsPowerShell -Force } | Should -Throw -ErrorId "InvalidOperationException"
|
||||
}
|
||||
}
|
||||
finally {
|
||||
[System.Management.Automation.Internal.InternalTestHooks]::SetTestHook("TestWindowsPowerShellVersionString", $null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Context "Imports from absolute path" {
|
||||
|
||||
Reference in New Issue
Block a user