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

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

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

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

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


当前回答

我使用以下版本:

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

其他回答

考虑到公认的答案非常复杂。还有更简单的方法。我的答案是亚历山德鲁库的。 考虑到64位windows在Program Files (x86)中安装32位应用程序,您可以使用环境变量检查该文件夹是否存在(以弥补不同的本地化)

如。

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

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

更新:正如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上

我的解决方案:

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

一切都很好,但这也应该在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;
}

对不起,是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