[英]Detect 32-bit or 64-bit of Windows
我想检测当前的 Windows 操作系统是 32 位还是 64 位。 如何使用 C++ 实现它? 我不想要处理器类型我想要操作系统的位类型。 这是因为您可以在 64 位处理器上安装 32 位操作系统。
要调用的 function 是IsWow64Process
或IsWow64Process2
。 它会告诉您的 32 位应用程序是否在 64 位 Windows 上运行。
如果程序编译为 64 位,它就已经知道了。
如果您的代码是 64 位并且正在运行,那么 Windows 是 64 位的 - 无需检查。 如果您的进程是 32 位调用IsWow64Process()
- 32 位进程在 64 位 Windows 上的 WOW64 中运行,否则没有 WOW64。
bool getWindowsBit(bool & isWindows64bit)
{
#if _WIN64
isWindows64bit = true;
return true;
#elif _WIN32
BOOL isWow64 = FALSE;
//IsWow64Process is not available on all supported versions of Windows.
//Use GetModuleHandle to get a handle to the DLL that contains the function
//and GetProcAddress to get a pointer to the function if available.
LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)
GetProcAddress(GetModuleHandle(TEXT("kernel32")),"IsWow64Process");
if(fnIsWow64Process)
{
if (!fnIsWow64Process(GetCurrentProcess(), &isWow64))
return false;
if(isWow64)
isWindows64bit = true;
else
isWindows64bit = false;
return true;
}
else
return false;
#else
assert(0);
return false;
#endif
}
如果您的应用程序是 32 位应用程序,则可以使用IsWow64Process ,如果您是在 x64 操作系统上运行,则为 32 位
您需要使用GetNativeSystemInfo
。 鉴于您希望这适用于 32 位操作系统,您需要使用LoadLibrary
+ GetProcAddress
以便您可以处理此 function 不可用的问题。 所以如果失败了,你就知道它是一个 32 位操作系统。 如果没有, SYSTEM_INFO.wProcessorArchitecture
会为您提供真正的处理器类型,而不是模拟的。
使用GetNativeSystemInfo
function。 它得到一个LPSYSTEM_INFO
参数来得到你想要的。
SYSTEM_INFO
结构:
wProcessorArchitecture
已安装操作系统的处理器架构。
这是另一种方式: GetSystemWow64Directory - “检索 WOW64 使用的系统目录的路径。此目录在 32 位 Windows 上不存在。” 和“在 32 位 Windows 上,function 总是失败,并且扩展错误设置为ERROR_CALL_NOT_IMPLEMENTED
。”
我个人不确定IsWow64Process
IsWow64Process
描述中有文字“请注意,这种技术不是检测操作系统是否是 Windows 的 64 位版本的可靠方法,因为 Kernel32当前版本的 32 位 Windows 中的 .dll 也包含此 function。”
您可以在程序中将 windows 命令systeminfo
作为进程运行。
#include <stdlib.h>
system("systeminfo");
返回类别之一是系统类型。
其 output 读取: System Type: x86-based PC
,或System Type: x64-based PC
这可能是一个比其他人提供的更复杂的解决方案,但我想我会添加它作为一种可能性。 (也许您也在寻求其他信息。)
bool IsX64win()
{
UINT x64test = GetSystemWow64DirectoryA(NULL, 0);
if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) return FALSE;
else return TRUE;
}
Windows 较新版本的答案
虽然有几个人和 Microsoft Docs 为此建议了 IsWow64Process2 ,但我在研究中没有看到任何代码示例。 这就是为什么我想将这个答案贡献给社区。
根据正在运行的 32 位应用程序文档页面,Microsoft 建议对 Windows 10 使用IsWow64Process2而不是IsWow64Process :
32 位应用程序可以通过调用 IsWow64Process function 来检测它是否在 WOW64 下运行(如果针对 Windows 10,则使用 IsWow64Process2)。
此 function 适用于 Windows 10 版本 1511(客户端)和 Windows Server 2016 及更高版本。
这有两个参数,通过它们返回信息:pProcessMachine 和 pNativeMachine。 两者都返回图像文件机器常量
pProcessMachine 返回有关目标进程是否在 WOW64 模拟器下运行的信息,如果是,它是什么类型的进程。
pNativeMachine 返回有关 Windows 主机架构的信息。
使用这两个返回值,可以确定 Windows 是 32 位还是 64 位(这是 OP 要求的),以及进程是否在 WOW64 下运行,以及进程是 32 位还是 64 位。
这是我为此目的编写的 function:
BOOL getBits(BOOL& windowsIs32Bit, BOOL& isWOW64, BOOL& processIs32Bit)
{
USHORT ProcessMachine;
USHORT NativeMachine;
if (!IsWow64Process2(GetCurrentProcess(), &ProcessMachine, &NativeMachine)) {
std::cerr << "IsWOW64Process2 returned FALSE (failed). GetLastError returned: " << GetLastError() << std::endl;
return FALSE;
}
if (ProcessMachine == IMAGE_FILE_MACHINE_UNKNOWN) {
isWOW64 = FALSE;
if (NativeMachine == IMAGE_FILE_MACHINE_IA64 || NativeMachine == IMAGE_FILE_MACHINE_AMD64 || NativeMachine == IMAGE_FILE_MACHINE_ARM64) {
windowsIs32Bit = FALSE;
processIs32Bit = FALSE;
return TRUE;
}
if (NativeMachine == IMAGE_FILE_MACHINE_I386 || NativeMachine == IMAGE_FILE_MACHINE_ARM) {
windowsIs32Bit = TRUE;
processIs32Bit = TRUE;
return TRUE;
}
std::cerr << "Unknown Windows Architecture." << std::endl;
return FALSE;
}
windowsIs32Bit = FALSE;
isWOW64 = TRUE;
processIs32Bit = TRUE;
return TRUE;
}
以下是上述 function 的示例用法:
int main() {
BOOL windowsIs32Bit;
BOOL isWOW64;
BOOL processIs32Bit;
if (!getBits(windowsIs32Bit, isWOW64, processIs32Bit)) {
return -1;
}
std::cout << (windowsIs32Bit ? "Windows is 32 bit" : "Windows is 64 bit") << std::endl;
std::cout << (isWOW64 ? "This process *is* running under WOW64" : "This process is *not* running under WOW64") << std::endl;
std::cout << (processIs32Bit ? "This process is 32 bit" : "This process is 64 bit") << std::endl;
return 0;
}
我只能测试上述代码的两个场景,因为我在 64 位机器上只有 64 位 Windows。 我没有 32 位机器,也没有 32 位 Windows,也没有任何 ARM 机器。 如果有人可以测试其他场景,我会很感激一些关于我所做的设计是否适合他们的反馈。
我写了一篇文章,更深入地解释了上述代码的工作原理。
或者,最简单的方法是使用sizeof(int *)
检查 integer 指针的大小。
如果是 4 那么它的 32 位
如果是 8,那么它的 64 位
这是一个未记录的方法...
bool _Is64BitOS(void);
bool _Is64BitOS(void) {
unsigned int version = *((unsigned int)*)0x7FFE026C;
unsigned int address = version == 10 ? 0x7FFE0308 : 0x7FFE0300;
//printf("Running %u-bit system",*((void*)*)address ? 32 : 64);
return (*((void*)*)address ? false,true);
};
static bool is64bitOS()
{
SYSTEM_INFO si;
GetSystemInfo(&si);
if((si.wProcessorArchitecture & PROCESSOR_ARCHITECTURE_IA64)||(si.wProcessorArchitecture & PROCESSOR_ARCHITECTURE_AMD64)==64)
{
return true;
}
else
{
return false;
}
}
一个简单的检查是如果 EXE 没有运行,那么它是在 32 位机器上运行的 64 位可执行文件。 64 位机器将始终运行 32 位可执行文件。
来自微软,
大多数为 32 位版本的 Windows 设计的程序都可以在 64 位版本的 Windows 上运行。 值得注意的例外是许多防病毒程序。
为 32 位版本的 Windows 设计的设备驱动程序在运行 64 位版本的 Windows 的计算机上不起作用。 如果您尝试安装只有 32 位驱动程序可用的打印机或其他设备,它在 Windows 的 64 位版本上将无法正常工作。
但是,在 Windows 中,您还可以检查是否存在 Program Files (x86) 文件夹作为另一个简单检查。 没必要花里胡哨。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.