如何检测Windows 64位平台与。net ?

在一个net 2.0 c#应用程序中,我使用以下代码来检测操作系统平台:

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

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

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

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

221006 次浏览

最快的方式:

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

< em >注意:< / em >这是非常直接的,只有当程序不强制作为32位进程执行时(例如,通过项目设置中的<Prefer32Bit>true</Prefer32Bit>),才能在64位上正确工作。

正如Joel Coehoorn和其他人建议的那样,从。net Framework 4.0开始,你可以只检查Environment.Is64BitOperatingSystem


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

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

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

我的解决方案:

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;
}
}

下面是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;
}

完整的答案是这样的(摘自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。

你也可以检查PROCESSOR_ARCHITECTURE环境变量。

它要么不存在,要么在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);
}

一切都很好,但这也应该在env中工作:

PROCESSOR_ARCHITECTURE=x86

..

PROCESSOR_ARCHITECTURE=AMD64

可能太简单了;-)

这只是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;
}

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

使用以下两个环境变量(伪代码):

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: Detect Process Bitness

OSInfo。位

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();
}
}
}

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

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版本(用于测试远程机器)。

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

我使用以下版本:

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

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

下面是一些可能的用法:

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);
}

我需要这样做,但我也需要能够作为一个管理员远程做到这一点,无论是哪种情况下,这似乎很适合我:

    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;
}
}

我使用:

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

这将获取应用程序启动的路径,以防您将其安装在计算机上的不同位置。此外,你也可以只执行一般的C:\路径,因为99.9%的计算机都在C:\中安装了Windows。

我正在使用以下代码。注意:它是为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);
}

下面是一个Windows管理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:

@foobar:你是对的,这太简单了;)

在99%的情况下,具有较弱系统管理员背景的开发人员最终无法意识到微软一直为任何人提供的枚举Windows的功能。

在这种情况下,系统管理员总是会编写更好、更简单的代码。

然而,有一件事要注意,构建配置必须是AnyCPU,这个环境变量才能在正确的系统上返回正确的值:

System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")

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

使用此命令获取已安装的Windows体系结构:

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

如果你使用net框架 4.0,这很简单:

Environment.Is64BitOperatingSystem

参见环境。Is64BitOperatingSystem属性 . Is64BitOperatingSystem属性 . Is64BitOperatingSystem属性 (MSDN)。

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

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

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

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

试试这个:

Environment.Is64BitOperatingSystem


Environment.Is64BitProcess

享受;-)

Function Is64Bit() As Boolean


Return My.Computer.FileSystem.SpecialDirectories.ProgramFiles.Contains("Program Files (x86)")


End Function

来自Chriz Yuen的博客

c# .Net 4.0引入两个新的环境属性 Environment.Is64BitOperatingSystem; Environment.Is64BitProcess; < / p > 当你使用这两个属性时请小心。 测试Windows 7 64位机器

//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

使用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();

在你的项目中包含以下代码:

    [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或更高版本。

鉴于公认的答案非常复杂。还有更简单的方法。我的答案是亚历山德鲁库的。 假定64位windows在Program Files (x86)中安装32位应用程序,您可以使用环境变量(弥补不同的本地化)

检查该文件夹是否存在

如。

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

这对我来说更快更简单。鉴于我也希望访问基于OS版本的文件夹下的特定路径。

这个问题是针对。net 2.0的,但仍然会在谷歌搜索中出现,这里没有人提到,自从。net标准1.1 / .NET核心1.0以来,现在有一个更好的方法来了解CPU架构:

System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture

理论上,这应该能够区分x64和Arm64,尽管我自己没有测试它。

看到的文档

对不起,VB的代码。NET,但是很容易移植到c#。 它可以在Win7, x64和.Net Framework 4.8上正常工作:

Dim r As String = ""
Using searcher As ManagementObjectSearcher = New System.Management.ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem")
Dim Information As ManagementObjectCollection = searcher.Get()
If Information IsNot Nothing Then
For Each obj As ManagementObject In Information
r = obj("Caption").ToString() & _
" - " & _
obj("OSArchitecture").ToString() ' <--- !!! "64-bit" shown here
Next
End If
MessageBox.Show(r)
End Using