diff --git a/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs b/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs index 3903015fc..32e1842a0 100644 --- a/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs +++ b/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs @@ -1853,23 +1853,15 @@ namespace Microsoft.PowerShell.Commands else if ((requiredProcessorArchitecture != ProcessorArchitecture.None) && (requiredProcessorArchitecture != ProcessorArchitecture.MSIL)) { - bool isRunningOnArm = false; - ProcessorArchitecture currentArchitecture = PsUtils.GetProcessorArchitecture(out isRunningOnArm); + ProcessorArchitecture currentArchitecture = typeof(object).Assembly.GetName().ProcessorArchitecture; - // For ARM Architectures, we need to do additional string-level comparison - if ((currentArchitecture != requiredProcessorArchitecture && !isRunningOnArm) || - (isRunningOnArm && - !requiredProcessorArchitecture.ToString() - .Equals(PsUtils.ArmArchitecture, StringComparison.OrdinalIgnoreCase))) + if (currentArchitecture != requiredProcessorArchitecture) { containedErrors = true; if (writingErrors) { - string actualCurrentArchitecture = isRunningOnArm - ? PsUtils.ArmArchitecture - : currentArchitecture.ToString(); message = StringUtil.Format(Modules.InvalidProcessorArchitecture, - actualCurrentArchitecture, moduleManifestPath, requiredProcessorArchitecture); + currentArchitecture, moduleManifestPath, requiredProcessorArchitecture); InvalidOperationException ioe = new InvalidOperationException(message); ErrorRecord er = new ErrorRecord(ioe, "Modules_InvalidProcessorArchitecture", ErrorCategory.ResourceUnavailable, moduleManifestPath); diff --git a/src/System.Management.Automation/utils/PsUtils.cs b/src/System.Management.Automation/utils/PsUtils.cs index ced3c5791..447564d01 100644 --- a/src/System.Management.Automation/utils/PsUtils.cs +++ b/src/System.Management.Automation/utils/PsUtils.cs @@ -8,15 +8,11 @@ using System.IO; using System.Linq; using System.Management.Automation.Language; using System.Net.NetworkInformation; -using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using System.Security; using System.Text; using System.Xml; -using Microsoft.Win32; - namespace System.Management.Automation { /// @@ -24,8 +20,6 @@ namespace System.Management.Automation /// internal static class PsUtils { - internal static string ArmArchitecture = "ARM"; - /// /// Safely retrieves the MainModule property of a /// process. Version 2.0 and below of the .NET Framework are @@ -135,41 +129,6 @@ namespace System.Management.Automation } } - /// - /// Returns processor architecture for the current process. - /// If powershell is running inside Wow64, then is returned. - /// - /// Processor architecture for the current process. - internal static ProcessorArchitecture GetProcessorArchitecture(out bool isRunningOnArm) - { - var sysInfo = new NativeMethods.SYSTEM_INFO(); - NativeMethods.GetSystemInfo(ref sysInfo); - ProcessorArchitecture result; - isRunningOnArm = false; - switch (sysInfo.wProcessorArchitecture) - { - case NativeMethods.PROCESSOR_ARCHITECTURE_IA64: - result = ProcessorArchitecture.IA64; - break; - case NativeMethods.PROCESSOR_ARCHITECTURE_AMD64: - result = ProcessorArchitecture.Amd64; - break; - case NativeMethods.PROCESSOR_ARCHITECTURE_INTEL: - result = ProcessorArchitecture.X86; - break; - case NativeMethods.PROCESSOR_ARCHITECTURE_ARM: - result = ProcessorArchitecture.None; - isRunningOnArm = true; - break; - - default: - result = ProcessorArchitecture.None; - break; - } - - return result; - } - /// /// Return true/false to indicate whether the processor architecture is ARM. /// @@ -233,31 +192,6 @@ namespace System.Management.Automation private static class NativeMethods { - internal const ushort PROCESSOR_ARCHITECTURE_INTEL = 0; - internal const ushort PROCESSOR_ARCHITECTURE_ARM = 5; - internal const ushort PROCESSOR_ARCHITECTURE_IA64 = 6; - internal const ushort PROCESSOR_ARCHITECTURE_AMD64 = 9; - internal const ushort PROCESSOR_ARCHITECTURE_UNKNOWN = 0xFFFF; - - [StructLayout(LayoutKind.Sequential)] - internal struct SYSTEM_INFO - { - public ushort wProcessorArchitecture; - public ushort wReserved; - public uint dwPageSize; - public IntPtr lpMinimumApplicationAddress; - public IntPtr lpMaximumApplicationAddress; - public UIntPtr dwActiveProcessorMask; - public uint dwNumberOfProcessors; - public uint dwProcessorType; - public uint dwAllocationGranularity; - public ushort wProcessorLevel; - public ushort wProcessorRevision; - }; - - [DllImport(PinvokeDllNames.GetSystemInfoDllName)] - internal static extern void GetSystemInfo(ref SYSTEM_INFO lpSystemInfo); - [DllImport(PinvokeDllNames.GetCurrentThreadIdDllName)] internal static extern uint GetCurrentThreadId(); } diff --git a/test/powershell/engine/Module/NewModuleManifest.Tests.ps1 b/test/powershell/engine/Module/NewModuleManifest.Tests.ps1 index 8b86ecb14..c287065a7 100644 --- a/test/powershell/engine/Module/NewModuleManifest.Tests.ps1 +++ b/test/powershell/engine/Module/NewModuleManifest.Tests.ps1 @@ -117,4 +117,69 @@ Describe "New-ModuleManifest tests" -tags "CI" { { New-ModuleManifest -Path $manifestPath -ProjectUri $testUri -LicenseUri $testUri -IconUri $testUri } | Should -Throw -ErrorId "System.InvalidOperationException,Microsoft.PowerShell.Commands.NewModuleManifestCommand" } + + # We skip the test on Unix-s because there Roslyn compilation works in another way. + It "New-ModuleManifest works with assembly architecture: " -Skip:(!$IsWindows) -TestCases @( + # All values from [System.Reflection.ProcessorArchitecture] + @{ moduleArch = "None" }, + @{ moduleArch = "MSIL" }, + @{ moduleArch = "X86" }, + @{ moduleArch = "IA64" }, + @{ moduleArch = "Amd64" }, + @{ moduleArch = "Arm" } + ) { + param($moduleArch) + + $roslynArch = [System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture + + switch ($moduleArch) + { + "None" { Set-ItResult -Skipped -Because "the test assembly architecture can not be tested"; return } + "MSIL" { Set-ItResult -Skipped -Because "the test assembly architecture can not be tested"; return } + "IA64" { $roslynArch = 'Itanium' } + } + + $arch = [int].Assembly.GetName().ProcessorArchitecture + + # Skip tests if the module architecture does not match the platform architecture + # but X86 works on Amd64/X64 and Arm works on Arm64. + if ($moduleArch -ne $arch -and -not ($moduleArch -eq "X86" -and $arch -eq "Amd64") -and -not ($moduleArch -eq "Arm" -and $arch -eq "Arm64")) + { + Set-ItResult -Skipped -Because "the $moduleArch assembly architecture is not supported on the $arch platform" + return + } + + $a=@" + using System; + using System.Management.Automation; + + namespace Test.Manifest { + + [Cmdlet(VerbsCommon.Get, "TP")] + public class TPCommand0 : PSCmdlet + { + protected override void EndProcessing() + { + WriteObject("$arch"); + } + } + } +"@ + try { + # We can not unload the module assembly and so we can not use Pester TestDrive without cleanup error reporting + $testFolder = Join-Path $([System.IO.Path]::GetTempPath()) $([System.IO.Path]::GetRandomFileName()) + New-Item -Type Directory -Path $testFolder -Force > $null + + $assemblyPath = Join-Path $testFolder "TP_$arch.dll" + $modulePath = Join-Path $testFolder "TP_$arch.psd1" + Add-Type -TypeDefinition $a -CompilerOptions "/platform:$roslynArch" -OutputAssembly $assemblyPath + New-ModuleManifest -Path $modulePath -NestedModules "TP_$arch.dll" -RequiredAssemblies "TP_$arch.dll" -ProcessorArchitecture $arch -CmdletsToExport "Get-TP" + Import-Module $modulePath + + Get-TP -ErrorAction SilentlyContinue | Should -BeExactly "$arch" + } finally { + Remove-Module "TP_$arch" -Force + Remove-Item -LiteralPath $testFolder -Recurse -Force -ErrorAction SilentlyContinue > $null + } + } }