32 位或 64 位操作系统??






4.08/5 (9投票s)
一种在程序中检测操作系统位数的简单方法。(提供了 C# 和 C++ 示例)
一直以来,都存在关于检测操作系统位数的最佳方法的争论。大多数情况下,获取系统信息被认为可以通过互操作服务或 P/Invoke 来解决。为此,所遵循的方法如下所示实际上,在 C# 中实现这一点很简单。C# 提供了一个非常有用的结构体
机器上编译的程序中,指针的大小为 4 字节。在 64 位编译的程序中,大小会发生变化,变为 8 字节。那么为什么不比较整数的大小呢?指针本质上就是一个整数,而 以下示例演示了
public enum Platform
{
X86,
X64,
Unknown
}
internal const ushort PROCESSOR_ARCHITECTURE_INTEL = 0;
internal const ushort PROCESSOR_ARCHITECTURE_IA64 = 6;
internal const ushort PROCESSOR_ARCHITECTURE_AMD64 = 9;
internal const ushort PROCESSOR_ARCHITECTURE_UNKNOWN = 0xFFFF;
[StructLayout(LayoutKind.Sequential)]
internal struct SYSTEM_INFO
{
public ushort wProcessorArchitecture;
public ushort wReserved;
public uint dwPageSize;
public IntPtr lpMinimumApplicationAddress;
public IntPtr lpMaximumApplicationAddress;
public UIntPtr dwActiveProcessorMask;
public uint dwNumberOfProcessors;
public uint dwProcessorType;
public uint dwAllocationGranularity;
public ushort wProcessorLevel;
public ushort wProcessorRevision;
};
[DllImport("kernel32.dll")]
internal static extern void GetNativeSystemInfo(ref SYSTEM_INFO lpSystemInfo);
[DllImport("kernel32.dll")]
internal static extern void GetSystemInfo(ref SYSTEM_INFO lpSystemInfo);
public static Platform GetPlatform()
{
SYSTEM_INFO sysInfo = new SYSTEM_INFO();
if(System.Environment.OSVersion.Version.Major > 5 ||
(System.Environment.OSVersion.Version.Major == 5 && System.Environment.OSVersion.Version.Minor >= 1))
{
GetNativeSystemInfo(ref sysInfo);
}
else
{
GetSystemInfo(ref sysInfo);
}
switch(sysInfo.wProcessorArchitecture)
{
case PROCESSOR_ARCHITECTURE_IA64:
case PROCESSOR_ARCHITECTURE_AMD64:
return Platform.X64;
case PROCESSOR_ARCHITECTURE_INTEL:
return Platform.X86;
default:
return Platform.Unknown;
}
}
IntPtr
。64 位与 32 位关于指针
我们都知道,在 32 位IntPtr
在 C# 中为我们提供了相同的功能。IntPtr
的简单用法。(更新:由于 Win64 遵循 LLP64 模型(有关 LLP64 模型的更多信息,请参阅 Technet 文章[^]),正如 CodeProject 成员 Ajay Vijayvargiya[^] 指出的那样)if(IntPtr.size == 4) { //Your logic for 32-Bit. } else { // Your logic for 64-Bit. }之前的代码检查程序是在 32 位还是 64 位模式下运行。这并不能告知操作系统的位数。如果使用 C++/Win32:
IntPtr
在 C++ 中不可用。 相反,sizeof(int)
具有相同的功能。BOOL Is64BitOS() { BOOL bIs64Bit = FALSE; #if defined(_WIN64) bIs64Bit = TRUE; // 64-bit programs run only on Win64 #elif defined(_WIN32) // Note that 32-bit programs run on both 32-bit and 64-bit Windows typedef BOOL (WINAPI *LPFNISWOW64PROCESS) (HANDLE, PBOOL); LPFNISWOW64PROCESS pfnIsWow64Process = (LPFNISWOW64PROCESS)GetProcAddress(GetModuleHandle(_T("kernel32")), "IsWow64Process"); if (pfnIsWow64Process) pfnIsWow64Process(GetCurrentProcess(), &bIs64Bit); #endif return bIs64Bit; }64 位操作系统支持另一个显著的功能:“虚拟化”。
虚拟化(仅适用于 Windows Vista 和 7 x64 平台)
虚拟化技术仅由 Windows Vista 和 7 x64 平台使用。它们充当虚拟机,就像 VMWare 或类似应用程序一样。这里的优势是运行遗留应用程序,例如 32 位应用程序。在没有虚拟化的情况下,在 64 位操作系统上运行 32 位应用程序会变得困难,因为这些应用程序通常没有被编写为在单个执行环境中同时存在。64 位应用程序绝不会被虚拟化运行,32 位或 64 位服务和驱动程序也不会。虚拟化在 WOW64 下运行遗留 32 位交互式应用程序时变为激活状态。因此,如果操作系统支持虚拟化,那么它一定是 64 位。您可以使用以下代码来检查应用程序是否正在以虚拟化方式运行[DllImport("advapi32.dll", EntryPoint = "GetTokenInformation",
SetLastError = true)]
static extern bool GetTokenInformationNative(
IntPtr TokenHandle,
int TokenInformationClass,
ref int TokenInformation,
int TokenInformationLength,
out int ReturnLength);
public bool IsVirtualized(IntPtr token)
{
bool virtualized = false;
int len = 4;
int info = 0;
if (!GetTokenInformationNative(token, 24, ref info, len, out
len)) // 24 = TokenVirtualizationEnabled
{
string s = "Win32 error " +
Marshal.GetLastWin32Error().ToString();
throw new Exception(s);
}
if(info != 0)
virtualized = true;
return virtualized;
}
// usage...
if(IsVirtualized(WindowsIdentity.GetCurrent().Toke n))
// better add a manifest to your application if you end here ;-)
感谢 Luc Pattyn[^] 和 Ajay Vijayvargiya[^] 指出错误。:)