使用C#识别CPU体系结构类型

我想检查用户正在运行的CPU架构,是i386还是X64或AMD64。 我想用C#做。 我知道我可以尝试WMI或注册表。 除了这两个之外还有其他方法吗? 我的项目面向.NET 2.0!

你也可以尝试(只有在没有被操纵的情况下才有效):

System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE") 

这里的原因是检查32位与64位操作系统。 评分最高的答案是查看当前流程的设置。 找不到答案后,我发现了以下设置。 希望这对你有用。

 bool is64 = System.Environment.Is64BitOperatingSystem 

这是一段似乎有用的代码(基于P / Invoke):

  public static ProcessorArchitecture GetProcessorArchitecture() { SYSTEM_INFO si = new SYSTEM_INFO(); GetNativeSystemInfo(ref si); switch (si.wProcessorArchitecture) { case PROCESSOR_ARCHITECTURE_AMD64: return ProcessorArchitecture.Amd64; case PROCESSOR_ARCHITECTURE_IA64: return ProcessorArchitecture.IA64; case PROCESSOR_ARCHITECTURE_INTEL: return ProcessorArchitecture.X86; default: return ProcessorArchitecture.None; // that's weird :-) } } 

  [DllImport("kernel32.dll")] private static extern void GetNativeSystemInfo(ref SYSTEM_INFO lpSystemInfo); private const int PROCESSOR_ARCHITECTURE_AMD64 = 9; private const int PROCESSOR_ARCHITECTURE_IA64 = 6; private const int PROCESSOR_ARCHITECTURE_INTEL = 0; [StructLayout(LayoutKind.Sequential)] private struct SYSTEM_INFO { public short wProcessorArchitecture; public short wReserved; public int dwPageSize; public IntPtr lpMinimumApplicationAddress; public IntPtr lpMaximumApplicationAddress; public IntPtr dwActiveProcessorMask; public int dwNumberOfProcessors; public int dwProcessorType; public int dwAllocationGranularity; public short wProcessorLevel; public short wProcessorRevision; } 

请注意,此代码重用现有CLR的ProcessorArchitecture枚举,并支持.NET framework 2及更高版本。

Win32_Processor WMI类将完成这项工作。 使用MgmtClassGen.exe生成强类型包装器。

最后,解决C#中当前运行的CLR运行时的平台/处理器体系结构的最短技巧是:

 PortableExecutableKinds peKind; ImageFileMachine machine; typeof(object).Module.GetPEKind(out peKind, out machine); 

这里Module.GetPEKind返回一个ImageFileMachine枚举,它存在于.NET v2之后:

 public enum ImageFileMachine { I386 = 0x014C, IA64 = 0x0200, AMD64 = 0x8664, ARM = 0x01C4 // new in .NET 4.5 } 

为什么不使用new AssemblyName(fullName)typeof(object).Assembly.GetName()
那么在ASP.NET MVC源代码中有这个HACK注释(从1.0开始):

 private static string GetMvcVersionString() { // DevDiv 216459: // This code originally used Assembly.GetName(), but that requires FileIOPermission, which isn't granted in // medium trust. However, Assembly.FullName *is* accessible in medium trust. return new AssemblyName(typeof(MvcHttpHandler).Assembly.FullName).Version.ToString(2); } 

看到他们为自己使用一些隐藏的技巧。 遗憾的是, AssemblyName构造函数没有正确设置ProcessorArchitecture字段,它对于任何新的AssemblyName都只是None

因此,对于未来的读者,我建议您使用带有ImageFileMachine的丑陋的GetPEKind!

笔记:

  • 这将返回当前运行的运行时体系结构 ,而不是底层系统体系结
    也就是说,唯一的例外是I386运行时可能在AMD64系统上运行。
  • 在mono / ubuntu 14.04 / AMD64和.NET / Win7 / I386上测试。

我知道这个问题来自过去,但截至2017年,现在有一种简单的方法可以在.net标准中了解当前流程的架构:

 System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture 

返回的值是X86,X64,ARM,ARM64之一,并提供其运行的进程的体系结构OSArchitecture返回已安装操作系统的体系结构。

指向文档的链接(虽然很无用……):

RuntimeInformation.ProcessArchitecture: https ://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.runtimeinformation.processarchitecture ? view = netstandard-1.4

架构枚举: https : //docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.architecture?view = netstandard-1.4

也许这个 CodeProject文章可以帮助? 它使用System.Management命名空间中的ManagementObjectSearcher来搜索硬件信息。

根据您想知道的原因,您可能会发现检查IntPtr结构的大小是最简单的方法。

你可以问用户吗?

开个玩笑当然……我认为WMI就是你用来做的。 但也许还有其他一些方法呢?

如果您选择WMI,那么LinqToWmi可能会有用。 我试了一次,看起来很直接=) – > http://www.codeplex.com/linq2wmi

我相信你应该避免像WMI和LINQ那样的臃肿……你最终还是要获得更多的信息,这些都不会被臃肿的apis和框架所满足。

只需调用一个调用和提取CPUID信息的DLL即可。 C ++ / CLI或pinvoke可以获得供应商所需的所有信息。 首先,您需要查看指令是否受支持(99%的时间)。

要快速启动并运行,请检查intel站点的wincpuid示例,并从那里从cpuid.h中提取该块。 只有2个供应商,其中一个是内存延迟,另一个不是(如本机与托管代码)。 因此,你会遇到其他架构上的Mono问题(谁没有btw)。 至于x64你已经知道它或只是得到corflags(它已经存在并用.NET发行版杀死你的客户硬盘)..

http://software.intel.com/en-us/articles/api-detects-ia-32-and-x64-platform-cpu-characteristics/

这对我来说似乎最简单:

 System.Environment.Is64BitOperatingSystem 

这个怎么样?

 switch (typeof(string).Assembly.GetName().ProcessorArchitecture) { case System.Reflection.ProcessorArchitecture.X86: break; case System.Reflection.ProcessorArchitecture.Amd64: break; case System.Reflection.ProcessorArchitecture.Arm: break; } 

但是case *.Arm:尚未测试。

这是我做的:

 public static bool Isx86() { return (Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%").Length == 0); } 

如果你使用64位架构,你将拥有两个程序文件env变量。 如果您使用的是x86,那么您将只拥有一个。