当前位置:  开发笔记 > 编程语言 > 正文

如何使用.NET检测Windows 64位平台?

如何解决《如何使用.NET检测Windows64位平台?》经验,为你挑选了13个好方法。

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

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

这将返回"Win32NT".问题是,即使在Windows Vista 64位上运行,它也会返回"Win32NT".

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

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



1> Phil Devaney..:

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


而不是Reflector,为什么不下载源代码.然后你得到评论和其他"笔记".
尼斯.如果用户使用的是.NET 4.0,这绝对是正确答案(即Environment.Is64BitOperatingSystem). - 在.NET 3.5中,FYI属性似乎不存在.
这不能回答明确说明.Net 2.0的问题
根据参考源,它做的是这样的:`if(IntPtr.Size == 8)返回true; if(!DoesWin32MethodExist(...,"IsWow64Process"))返回false; 返回IsWow64Process(GetCurrentProcess());`(伪代码)

2> Stefan Schul..:

如果在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上运行

我的解决方案

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.0开始,您可以查看`System.Environment.Is64BitOperatingSystem`.您可以将此编辑到您的答案中,还是允许我将其编辑到您的答案中?
在32位操作系统上运行时,对IsWow64Process的任何调用都将引发异常,因为kernel32.dll中缺少该条目.您应该在http://1code.codeplex.com/SourceControl/changeset/view/39074#842775上查看codeplex中显示的解决方案.我还有一个基于本页底部列出的代码的解决方案,它使用扩展方法如果你关心重用代码.
IsWow64Process是在Win XP SP2中引入的.如果您需要XP SP2或任何更新版本,此代码可以正常工作.
您的解决方案在MacBook Pro上使用Widows 7 Ultimate分区运行Bootcamp的Intel i7-3720QM微处理器返回正确的值.+1
@dmihailescu,你可以在调用IsWow64Process之前使用DoesWin32MethodExist,这是is64BitOperatingSystem的.net 4.0实现.
伟大的代码,thnx!可能想要添加`静态`到属性虽然:)否则对我来说工作正常,测试32位,32on64和纯64位.

3> 小智..:

如果您使用的是.NET Framework 4.0,则很容易:

Environment.Is64BitOperatingSystem

请参见Environment.Is64BitOperatingSystem属性(MSDN).


绝对是最好的答案!
对于极客,使用IsWow64Process(...)的内部实现http://referencesource.microsoft.com/#mscorlib/system/environment.cs,75feca36cdd83149

4> dwhiteho..:

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



5> Bruno Lopes..:

完整的答案就是这个(取自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.


这将在Win2000和WinXP SP1及更早版本下失败.您需要在调用之前检查IsWow64Process()函数是否存在,因为它仅在XP SP2和Vista/Win7中引入.
此示例无法处置Process.GetCurrentProcess()返回的Process实例.
@ user9876,是否(还是有)任何人仍然瞄准那些古董系统?

6> synhershko..:

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

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

它看起来像这样:

    /// 
    /// The function determines whether the current operating system is a 
    /// 64-bit operating system.
    /// 
    /// 
    /// The function returns true if the operating system is 64-bit; 
    /// otherwise, it returns false.
    /// 
    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);
        }
    }

    /// 
    /// The function determins whether a method exists in the export 
    /// table of a certain module.
    /// 
    /// The name of the module
    /// The name of the method
    /// 
    /// The function returns true if the method specified by methodName 
    /// exists in the export table of the module specified by moduleName.
    /// 
    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版本(用于测试远程机器).



7> Andrew Ensle..:

您还可以检查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);
}


@David报告Windows的处理器架构; 不是CPU.请参阅本页"The Code"开头的详细说明:http://andrewensley.com/2009/06/c-detect-windows-os-part-1/

8> electricalba..:

来自Chriz Yuen博客

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

使用这两个属性时请小心.在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



9> BobbyShaftoe..:

最快的方式:

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

注意:这是非常直接的.


这不起作用 - 如果在64位Windows上运行32位.NET Framework 2.0,它将返回32位.

10> 小智..:

试试这个:

Environment.Is64BitOperatingSystem

Environment.Is64BitProcess


感谢您的意见,但请在发布之前阅读可用的答案,因为已经提供了此解决方案.另请注意,最初的问题是关于.net 2,它没有这两个属性,只有.net 4引入.
这是一个很好的答案,但它是一个差异.题 :)

11> 小智..:

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

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

在涉及到这一点时,系统管理员总是会编写更好,更简单的代码.

不过,有一点需要注意,构建配置必须是AnyCPU才能使此环境变量在正确的系统上返回正确的值:

System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")

这将在32位Windows上返回"X86",在64位Windows上返回"AMD64".


您的解决方案在MacBook Pro上返回x86,其中Intel i7-3720QM微处理器运行带有Widows 7 Ultimate分区的Bootcamp.Stefan Schultze的解决方案正确地将处理器识别为64位.我确信你的解决方案适用于99%的基于Windows的电脑.尝试+1.
stefan Schultze 1:系统管理员0 ;-)

12> Santhosh..:

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

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.



13> Alexandru..:

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

推荐阅读
有风吹过best
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有