C# 如何使用 .NET 检测 Windows 64 位平台?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/336633/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to detect Windows 64-bit platform with .NET?
提问by Marc
In a .NET2.0 C# application I use the following code to detect the operating system platform:
在.NET2.0 C# 应用程序中,我使用以下代码来检测操作系统平台:
string os_platform = System.Environment.OSVersion.Platform.ToString();
This returns "Win32NT". The problem is that it returns "Win32NT" even when running on Windows Vista 64-bit.
这将返回“Win32NT”。问题是即使在 Windows Vista 64 位上运行时它也会返回“Win32NT”。
Is there any other method to know the correct platform (32 or 64 bit)?
有没有其他方法可以知道正确的平台(32 位或 64 位)?
Note that it should also detect 64 bit when run as a 32 bit application on Windows 64 bit.
请注意,在 Windows 64 位上作为 32 位应用程序运行时,它还应该检测 64 位。
采纳答案by Stefan Schultze
IntPtr.Size won't return the correct value if running in 32-bit .NET Framework 2.0 on 64-bit Windows (it would return 32-bit).
如果在 64 位 Windows 上的 32 位 .NET Framework 2.0 中运行,IntPtr.Size 将不会返回正确的值(它将返回 32 位)。
As Microsoft's Raymond Chen describes, you have to first check if running in a 64-bit process (I think in .NET you can do so by checking IntPtr.Size), and if you are running in a 32-bit process, you still have to call the Win API function IsWow64Process. If this returns true, you are running in a 32-bit process on 64-bit Windows.
正如微软的 Raymond Chen 所描述的,你必须首先检查是否在 64 位进程中运行(我认为在 .NET 中你可以通过检查 IntPtr.Size 来做到这一点),如果你在 32 位进程中运行,你仍然必须调用 Win API 函数 IsWow64Process。如果返回 true,则您正在 64 位 Windows 上的 32 位进程中运行。
Microsoft's Raymond Chen: How to detect programmatically whether you are running on 64-bit Windows
微软的 Raymond Chen: 如何以编程方式检测您是否在 64 位 Windows 上运行
My solution:
我的解决方案:
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;
}
}
回答by BobbyShaftoe
Quickest way:
最快的方法:
if(IntPtr.Size == 8) {
// 64 bit machine
} else if(IntPtr.Size == 4) {
// 32 bit machine
}
Note:this is very direct and works correctly on 64-bit only if the program does not force execution as a 32-bit process (e.g. through <Prefer32Bit>true</Prefer32Bit>
in the project settings).
注意:这是非常直接的,并且仅当程序不强制作为 32 位进程执行时(例如通过<Prefer32Bit>true</Prefer32Bit>
项目设置)才能在 64 位上正常工作。
回答by ripper234
Here is the direct approach in C# using DllImport from this page.
这是使用此页面中的DllImport 在 C# 中的直接方法。
[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;
}
回答by Bruno Lopes
The full answer is this (taken from both stefan-mg, ripper234 and BobbyShaftoe's answer):
完整的答案是这样的(取自 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;
}
First check if you're in a 64 bit process. If you're not, check if the 32 bit process is a Wow64Process.
首先检查您是否在 64 位进程中。如果不是,请检查 32 位进程是否为 Wow64Process。
回答by Andrew Ensley
You can also check for the PROCESSOR_ARCHITECTURE
environment variable.
您还可以检查PROCESSOR_ARCHITECTURE
环境变量。
It either doesn't exist or is set to "x86" on 32-bit Windows.
它要么不存在,要么在 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);
}
回答by Andrew Ensley
All fine, but this should also work from env
:
一切都很好,但这也应该适用于env
:
PROCESSOR_ARCHITECTURE=x86
..
..
PROCESSOR_ARCHITECTURE=AMD64
Too easy, maybe ;-)
太容易了,也许;-)
回答by dwhiteho
This is just an implementation of what's suggested above by Bruno Lopez, but works on Win2k + all WinXP service packs. Just figured I'd post it so other people didn't have roll it by hand. (would have posted as a comment, but I'm a new user!)
这只是 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;
}
回答by Phil Devaney
.NET 4 has two new properties in the Environment class, Is64BitProcessand Is64BitOperatingSystem. Interestingly, if you use Reflector you can see they are implemented differently in the 32-bit & 64-bit versions of mscorlib. The 32-bit version returns false for Is64BitProcess and calls IsWow64Process via P/Invoke for Is64BitOperatingSystem. The 64-bit version just returns true for both.
.NET 4 在 Environment 类中有两个新属性,Is64BitProcess和Is64BitOperatingSystem。有趣的是,如果您使用 Reflector,您可以看到它们在 mscorlib 的 32 位和 64 位版本中的实现方式不同。32 位版本为 Is64BitProcess 返回 false,并通过 P/Invoke 为 Is64BitOperatingSystem 调用 IsWow64Process。64 位版本只对两者都返回 true。
回答by Santhosh
Use these two environment variables (pseudo code):
使用这两个环境变量(伪代码):
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
}
Refer to the blog post HOWTO: Detect Process Bitness.
请参阅博客文章HOWTO: Detect Process Bitness。
回答by Greg
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();
}
}
}