如何检测与.NET的Windows 64位平台?

在.NET 2.0 C#应用程序中,我使用以下代码来检测操作系统平台:

string os_platform = System.Environment.OSVersion.Platform.ToString(); 

这返回“Win32NT”。 问题是,即使在Windows Vista 64位上运行,它也会返回“Win32NT”。

有没有其他方法知道正确的平台(32或64位)?

请注意,它应该在Windows 64位上作为32位应用程序运行时检测到64位。

如果在64位Windows上运行32位.NET Framework 2.0(它将返回32位),IntPtr.Size将不会返回正确的值。

正如微软的Raymond Chen所描述的,你必须首先检查是否在64位进程中运行(我认为在.NET中你可以通过检查IntPtr.Size来实现),如果你正在运行一个32位的进程,必须调用Win API函数IsWow64Process。 如果这返回true,则在64位Windows上运行32位进程。

微软的Raymond Chen: 如何以编程方式检测您是否在64位Windows上运行

我的解决scheme

 static bool is64BitProcess = (IntPtr.Size == 8); static bool is64BitOperatingSystem = is64BitProcess || InternalCheckIsWow64(); [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool IsWow64Process( [In] IntPtr hProcess, [Out] out bool wow64Process ); public static bool InternalCheckIsWow64() { if ((Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1) || Environment.OSVersion.Version.Major >= 6) { using (Process p = Process.GetCurrentProcess()) { bool retVal; if (!IsWow64Process(p.Handle, out retVal)) { return false; } return retVal; } } else { return false; } } 

.NET 4在Environment类中有两个新的属性, Is64BitProcess和Is64BitOperatingSystem 。 有趣的是,如果你使用Reflector,你可以看到它们在32位和64位版本的mscorlib中以不同的方式实现。 32位版本为Is64BitProcess返回false,并通过P / Invoke调用Is64BitOperatingSystem来调用IsWow64Process。 64位版本对两者都返回true。

如果您使用的是.NET Framework 4.0,那很简单:

 Environment.Is64BitOperatingSystem 

请参阅Environment.Is64BitOperatingSystem属性 (MSDN)。

这只是Bruno Lopez上面提到的一个实现,但是可以在Win2k +所有的WinXP服务包上运行。 只是觉得我会张贴,所以其他人没有手卷。 (将张贴作为评论,但我是一个新的用户!)

 [DllImport("kernel32", SetLastError = true, CallingConvention = CallingConvention.Winapi)] public extern static IntPtr LoadLibrary(string libraryName); [DllImport("kernel32", SetLastError = true, CallingConvention = CallingConvention.Winapi)] public extern static IntPtr GetProcAddress(IntPtr hwnd, string procedureName); private delegate bool IsWow64ProcessDelegate([In] IntPtr handle, [Out] out bool isWow64Process); public static bool IsOS64Bit() { if (IntPtr.Size == 8 || (IntPtr.Size == 4 && Is32BitProcessOn64BitProcessor())) { return true; } else { return false; } } private static IsWow64ProcessDelegate GetIsWow64ProcessDelegate() { IntPtr handle = LoadLibrary("kernel32"); if ( handle != IntPtr.Zero) { IntPtr fnPtr = GetProcAddress(handle, "IsWow64Process"); if (fnPtr != IntPtr.Zero) { return (IsWow64ProcessDelegate)Marshal.GetDelegateForFunctionPointer((IntPtr)fnPtr, typeof(IsWow64ProcessDelegate)); } } return null; } private static bool Is32BitProcessOn64BitProcessor() { IsWow64ProcessDelegate fnDelegate = GetIsWow64ProcessDelegate(); if (fnDelegate == null) { return false; } bool isWow64; bool retVal = fnDelegate.Invoke(Process.GetCurrentProcess().Handle, out isWow64); if (retVal == false) { return false; } return isWow64; } 

完整的答案是(取自stefan-mg,ripper234和BobbyShaftoe的回答):

  [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool IsWow64Process([In] IntPtr hProcess, [Out] out bool lpSystemInfo); private bool Is64Bit() { if (IntPtr.Size == 8 || (IntPtr.Size == 4 && Is32BitProcessOn64BitProcessor())) { return true; } else { return false; } } private bool Is32BitProcessOn64BitProcessor() { bool retVal; IsWow64Process(Process.GetCurrentProcess().Handle, out retVal); return retVal; } 

首先检查你是否在一个64位的进程。 如果你不是,检查32位进程是否是一个Wow64Process。

微软已经为此提供了一个代码示例:

http://1code.codeplex.com/SourceControl/changeset/view/39074#842775

它看起来像这样:

  /// <summary> /// The function determines whether the current operating system is a /// 64-bit operating system. /// </summary> /// <returns> /// The function returns true if the operating system is 64-bit; /// otherwise, it returns false. /// </returns> public static bool Is64BitOperatingSystem() { if (IntPtr.Size == 8) // 64-bit programs run only on Win64 { return true; } else // 32-bit programs run on both 32-bit and 64-bit Windows { // Detect whether the current process is a 32-bit process // running on a 64-bit system. bool flag; return ((DoesWin32MethodExist("kernel32.dll", "IsWow64Process") && IsWow64Process(GetCurrentProcess(), out flag)) && flag); } } /// <summary> /// The function determins whether a method exists in the export /// table of a certain module. /// </summary> /// <param name="moduleName">The name of the module</param> /// <param name="methodName">The name of the method</param> /// <returns> /// The function returns true if the method specified by methodName /// exists in the export table of the module specified by moduleName. /// </returns> static bool DoesWin32MethodExist(string moduleName, string methodName) { IntPtr moduleHandle = GetModuleHandle(moduleName); if (moduleHandle == IntPtr.Zero) { return false; } return (GetProcAddress(moduleHandle, methodName) != IntPtr.Zero); } [DllImport("kernel32.dll")] static extern IntPtr GetCurrentProcess(); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] static extern IntPtr GetModuleHandle(string moduleName); [DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)] static extern IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)]string procName); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool IsWow64Process(IntPtr hProcess, out bool wow64Process); 

还有一个WMI版本(用于testing远程机器)。

你也可以检查PROCESSOR_ARCHITECTURE环境variables。

它或者不存在,或者在32位Windows上设置为“x86”。

 private int GetOSArchitecture() { string pa = Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE"); return ((String.IsNullOrEmpty(pa) || String.Compare(pa, 0, "x86", 0, 3, true) == 0) ? 32 : 64); } 

@ foobar:你说得对,太容易了;)

在99%的案例中,系统pipe理员背景薄弱的开发人员最终未能认识到微软一直提供给任何人枚举Windows的权力。

当涉及到这一点时,系统pipe理员总是会写出更好,更简单的代码。

不过,有一点需要注意,构buildconfiguration的环境variables必须是AnyCPU才能在正确的系统上返回正确的值:

 System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE") 

这将在32位Windows上返回“X86”,在64位Windows上返回“AMD64”。

来自Chriz Yuen的博客

C#.Net 4.0引入了两个新的环境属性Environment.Is64BitOperatingSystem; Environment.Is64BitProcess;

使用这两个属性时请小心。 在Windows 7 64位机器上testing

 //Workspace: Target Platform x86 Environment.Is64BitOperatingSystem True Environment.Is64BitProcess False //Workspace: Target Platform x64 Environment.Is64BitOperatingSystem True Environment.Is64BitProcess True //Workspace: Target Platform Any Environment.Is64BitOperatingSystem True Environment.Is64BitProcess True 

尝试这个:

 Environment.Is64BitOperatingSystem Environment.Is64BitProcess 

最快的方法:

 if(IntPtr.Size == 8) { // 64 bit machine } else if(IntPtr.Size == 4) { // 32 bit machine } 

注意:这是非常直接的。

使用这两个环境variables(伪代码):

 if (PROCESSOR_ARCHITECTURE = x86 && isDefined(PROCESSOR_ARCHITEW6432) && PROCESSOR_ARCHITEW6432 = AMD64) { //64 bit OS } else if (PROCESSOR_ARCHITECTURE = AMD64) { //64 bit OS } else if (PROCESSOR_ARCHITECTURE = x86) { //32 bit OS } 

请参阅博客文章HOWTO:检测进程比特率

使用dotPeek有助于了解框架是如何实现的。 考虑到这一点,下面是我所想到的:

 public static class EnvironmentHelper { [DllImport("kernel32.dll")] static extern IntPtr GetCurrentProcess(); [DllImport("kernel32.dll")] static extern IntPtr GetModuleHandle(string moduleName); [DllImport("kernel32")] static extern IntPtr GetProcAddress(IntPtr hModule, string procName); [DllImport("kernel32.dll")] static extern bool IsWow64Process(IntPtr hProcess, out bool wow64Process); public static bool Is64BitOperatingSystem() { // Check if this process is natively an x64 process. If it is, it will only run on x64 environments, thus, the environment must be x64. if (IntPtr.Size == 8) return true; // Check if this process is an x86 process running on an x64 environment. IntPtr moduleHandle = GetModuleHandle("kernel32"); if (moduleHandle != IntPtr.Zero) { IntPtr processAddress = GetProcAddress(moduleHandle, "IsWow64Process"); if (processAddress != IntPtr.Zero) { bool result; if (IsWow64Process(GetCurrentProcess(), out result) && result) return true; } } // The environment must be an x86 environment. return false; } } 

用法示例:

 EnvironmentHelper.Is64BitOperatingSystem(); 

我需要做到这一点,但我也需要能够作为pipe理员远程执行,无论是哪种情况下,这似乎对我很好:

  public static bool is64bit(String host) { using (var reg = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, host)) using (var key = reg.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\")) { return key.GetValue("ProgramFilesDir (x86)") !=null; } } 

这是一个基于微软的代码在http://1code.codeplex.com/SourceControl/changeset/view/39074#842775的解决scheme。; 它使用扩展方法来简化代码重用。

一些可能的用法如下所示:

 bool bIs64BitOS = System.Environment.OSVersion.IsWin64BitOS(); bool bIs64BitProc = System.Diagnostics.Process.GetCurrentProcess().Is64BitProc(); //Hosts the extension methods public static class OSHelperTools { /// <summary> /// The function determines whether the current operating system is a /// 64-bit operating system. /// </summary> /// <returns> /// The function returns true if the operating system is 64-bit; /// otherwise, it returns false. /// </returns> public static bool IsWin64BitOS(this OperatingSystem os) { if (IntPtr.Size == 8) // 64-bit programs run only on Win64 return true; else// 32-bit programs run on both 32-bit and 64-bit Windows { // Detect whether the current process is a 32-bit process // running on a 64-bit system. return Process.GetCurrentProcess().Is64BitProc(); } } /// <summary> /// Checks if the process is 64 bit /// </summary> /// <param name="os"></param> /// <returns> /// The function returns true if the process is 64-bit; /// otherwise, it returns false. /// </returns> public static bool Is64BitProc(this System.Diagnostics.Process p) { // 32-bit programs run on both 32-bit and 64-bit Windows // Detect whether the current process is a 32-bit process // running on a 64-bit system. bool result; return ((DoesWin32MethodExist("kernel32.dll", "IsWow64Process") && IsWow64Process(p.Handle, out result)) && result); } /// <summary> /// The function determins whether a method exists in the export /// table of a certain module. /// </summary> /// <param name="moduleName">The name of the module</param> /// <param name="methodName">The name of the method</param> /// <returns> /// The function returns true if the method specified by methodName /// exists in the export table of the module specified by moduleName. /// </returns> static bool DoesWin32MethodExist(string moduleName, string methodName) { IntPtr moduleHandle = GetModuleHandle(moduleName); if (moduleHandle == IntPtr.Zero) return false; return (GetProcAddress(moduleHandle, methodName) != IntPtr.Zero); } [DllImport("kernel32.dll")] static extern IntPtr GetCurrentProcess(); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] static extern IntPtr GetModuleHandle(string moduleName); [DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)] static extern IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)]string procName); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool IsWow64Process(IntPtr hProcess, out bool wow64Process); } 

这里是直接的方法在C#中使用DllImport从这个页面 。

 [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool IsWow64Process([In] IntPtr hProcess, [Out] out bool lpSystemInfo); public static bool Is64Bit() { bool retVal; IsWow64Process(Process.GetCurrentProcess().Handle, out retVal); return retVal; } 

我正在使用以下代码。 注意:它是用于AnyCPU项目的。

  public static bool Is32bitProcess(Process proc) { if (!IsThis64bitProcess()) return true; // We're in 32-bit mode, so all are 32-bit. foreach (ProcessModule module in proc.Modules) { try { string fname = Path.GetFileName(module.FileName).ToLowerInvariant(); if (fname.Contains("wow64")) { return true; } } catch { // What on earth is going on here? } } return false; } public static bool Is64bitProcess(Process proc) { return !Is32bitProcess(proc); } public static bool IsThis64bitProcess() { return (IntPtr.Size == 8); } 

我发现这是检查系统平台和进程的最佳方法:

 bool 64BitSystem = Environment.Is64BitOperatingSystem; bool 64BitProcess = Environment.Is64BitProcess; 

第一个属性对于64位系统返回true,对于32位则返回false。 第二个属性对于64位进程返回true,对于32位则返回false。

这两个属性的需要是因为您可以在64位系统上运行32位进程,因此您需要检查系统和进程。

一切都好,但这也应该从env工作:

 PROCESSOR_ARCHITECTURE=x86 

..

 PROCESSOR_ARCHITECTURE=AMD64 

太容易了,也许;-)

这是一个Windows Management Instrumentation (WMI)方法:

 string _osVersion = ""; string _osServicePack = ""; string _osArchitecture = ""; ManagementObjectSearcher searcher = new ManagementObjectSearcher("select * from Win32_OperatingSystem"); ManagementObjectCollection collection = searcher.Get(); foreach (ManagementObject mbo in collection) { _osVersion = mbo.GetPropertyValue("Caption").ToString(); _osServicePack = string.Format("{0}.{1}", mbo.GetPropertyValue("ServicePackMajorVersion").ToString(), mbo.GetPropertyValue("ServicePackMinorVersion").ToString()); try { _osArchitecture = mbo.GetPropertyValue("OSArchitecture").ToString(); } catch { // OSArchitecture only supported on Windows 7/Windows Server 2008 } } Console.WriteLine("osVersion : " + _osVersion); Console.WriteLine("osServicePack : " + _osServicePack); Console.WriteLine("osArchitecture: " + _osArchitecture); ///////////////////////////////////////// // Test on Windows 7 64-bit // // osVersion : Microsoft Windows 7 Professional // osservicePack : 1.0 // osArchitecture: 64-bit ///////////////////////////////////////// // Test on Windows Server 2008 64-bit // --The extra r's come from the registered trademark // // osVersion : Microsoftr Windows Serverr 2008 Standard // osServicePack : 1.0 // osArchitecture: 64-bit ///////////////////////////////////////// // Test on Windows Server 2003 32-bit // --OSArchitecture property not supported on W2K3 // // osVersion : Microsoft(R) Windows(R) Server 2003, Standard Edition // osServicePack : 2.0 // osArchitecture: 

OSInfo.Bits

 using System; namespace CSharp411 { class Program { static void Main( string[] args ) { Console.WriteLine( "Operation System Information" ); Console.WriteLine( "----------------------------" ); Console.WriteLine( "Name = {0}", OSInfo.Name ); Console.WriteLine( "Edition = {0}", OSInfo.Edition ); Console.WriteLine( "Service Pack = {0}", OSInfo.ServicePack ); Console.WriteLine( "Version = {0}", OSInfo.VersionString ); Console.WriteLine( "Bits = {0}", OSInfo.Bits ); Console.ReadLine(); } } } 

使用它来获得已安装的Windows体系结构:

 string getOSArchitecture() { string architectureStr; if (Directory.Exists(Environment.GetFolderPath( Environment.SpecialFolder.ProgramFilesX86))) { architectureStr ="64-bit"; } else { architectureStr = "32-bit"; } return architectureStr; } 

将以下代码包含到项目的类中:

  [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool IsWow64Process([In] IntPtr hProcess, [Out] out bool wow64Process); public static int GetBit() { int MethodResult = ""; try { int Architecture = 32; if ((Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1) || Environment.OSVersion.Version.Major >= 6) { using (Process p = Process.GetCurrentProcess()) { bool Is64Bit; if (IsWow64Process(p.Handle, out Is64Bit)) { if (Is64Bit) { Architecture = 64; } } } } MethodResult = Architecture; } catch //(Exception ex) { //ex.HandleException(); } return MethodResult; } 

像这样使用它:

 string Architecture = "This is a " + GetBit() + "bit machine"; 

我在许多操作系统上使用这个检查成功:

 private bool Is64BitSystem { get { return Directory.Exists(Environment.ExpandEnvironmentVariables(@"%windir%\SysWOW64")); } } 

无论操作系统的语言如何,该文件夹总是被命名为“SysWOW64”。 这适用于.NET Framework 1.1或更高版本。

鉴于接受的答案是非常复杂的。 有更简单的方法。 我是alexandrudicu的anaswer的变种。 鉴于64位Windows在Program Files(x86)中安装32位应用程序,您可以使用环境variables(以弥补不同的本地化)来检查该文件夹是否存在,

例如

 private bool Is64BitSystem { get { return Directory.Exists(Environment.ExpandEnvironmentVariables(@"%PROGRAMFILES(X86)%")); } } 

这对我来说更快,更简单。 鉴于我也希望访问基于操作系统版本该文件夹下的特定path。

只要看看是否存在“C:\ Program Files(x86)”。 如果没有,那么你是在一个32位的操作系统。 如果是这样,那么操作系统是64位(Windows Vista或Windows 7)。 这似乎很简单…

请享用 ;-)

 Function Is64Bit() As Boolean Return My.Computer.FileSystem.SpecialDirectories.ProgramFiles.Contains("Program Files (x86)") End Function 

我用:

 Dim drivelet As String = Application.StartupPath.ToString If Directory.Exists(drivelet(0) & ":\Program Files (x86)") Then MsgBox("64bit") Else MsgBox("32bit") End if 

如果您的应用程序安装在计算机上的不同位置,则会获得启动应用程序的path。 此外,你可以做普通的C:\path,因为有99.9%的计算机安装了Windows的C:\

我使用以下版本:

  public static bool Is64BitSystem() { if (Directory.Exists(Environment.GetEnvironmentVariable("Program Files (x86)"))) return true; else return false; }