检测Windows的32位或64位版本

51

我想检测当前Windows操作系统是32位还是64位。如何使用C ++实现? 我不想要处理器类型,而是想要操作系统的位类型。这是因为您可以在64位处理器上安装32位操作系统。


可能是重复的问题: https://dev59.com/JXI_5IYBdhLWcg3wJfkM - user72424
他并不是在询问代码是否以32位或64位编译,而是试图找到安装的操作系统版本。 - Hayri Uğur Koltuk
重复的问题,已有更完整的答案,请参考https://dev59.com/EEvSa4cB1Zd3GeqPfZKO。 - Fabio Zadrozny
14个回答

48

需要调用的函数是IsWow64ProcessIsWow64Process2。它可以告诉你的32位应用程序是否在64位Windows上运行。

如果编译的程序是64位的,则已经知道。


如果函数存在,那就足以表明它是64位Windows了,对吧?你甚至不需要调用它。 - GetFree
4
MSDN称函数的存在并不意味着它适用于64位Windows。"为了兼容不支持此函数的操作系统,请调用GetProcAddress检测是否在Kernel32.dll中实现了IsWow64Process。如果GetProcAddress成功,则可以安全地调用该函数。否则,WOW64不存在。请注意,这种技术不是一种可靠的方法来检测操作系统是否是64位版本的Windows,因为当前32位Windows的Kernel32.dll也包含此函数。" - bronze man
3
“如果这个函数存在,那就足以表明它是64位的Windows系统了,对吗?” - 不对。IsWow64Process()在32位的XP SP2及更高版本中存在。 - Remy Lebeau

17

如果你的代码是64位的并且正在运行,那么Windows就是64位的 - 没有什么需要检查的。如果你的进程是32位的,请调用IsWow64Process() - 32位进程在64位Windows上运行时会在WOW64中,否则不包含WOW64。


调用这个函数会影响我的32位进程的虚拟化吗? - Wolf
@Wolf:你能否提供更多细节信息? - sharptooth
特别是,我担心在调用“IsWow64Process()”后,应用程序可能会失去对HKLM注册表键(或类似内容)的自动翻译。 - Wolf
2
@Wolf:据我所知,这个函数不会改变程序状态 - 它只返回一个布尔值,仅此而已。MSDN从未提到调用此函数会导致任何程序状态的更改。 - sharptooth

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

需要这个。typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);LPFN_ISWOW64PROCESS fnIsWow64Process; - Angus Connell
6
从http://msdn.microsoft.com/en-gb/library/windows/desktop/ms684139(v=vs.85).aspx获取 - Angus Connell
4
为避免被怀疑剽窃,您应该添加您的来源。 - Wolf

8

如果您的应用程序是32位应用程序,则可以使用IsWow64Process。如果返回值为true,则表示您正在运行于x64操作系统上,否则为32位。


6
使用 GetNativeSystemInfo 函数。使用 LPSYSTEM_INFO 参数获取所需内容。 SYSTEM_INFO 结构体:

wProcessorArchitecture
已安装操作系统的处理器架构。


3
微软的文档是错误的,实际上 wProcessorArchitecture 并不返回已安装的操作系统处理器架构,而是返回应用程序构建时使用的架构。 - ThreeBit
4
@ThreeBit:这个答案很好。你所说的对于GetSystemInfo是正确的,但这个答案需要调用GetNativeSystemInfo - Ben Voigt
老实说,我对这个完全不确定。 在Parallels上运行Windows 11 ARM版本似乎返回了AMD的数据。 - DreTaX

6
你需要使用GetNativeSystemInfo函数。考虑到你希望它在32位操作系统上工作,你需要使用LoadLibrary+GetProcAddress来处理这个函数不可用的情况。如果失败了,那么你就知道它是一个32位操作系统。否则,SYSTEM_INFO.wProcessorArchitecture会给出真实的处理器类型而不是模拟的处理器类型。

1
这里还有一种方法:GetSystemWow64Directory - "检索WOW64使用的系统目录的路径。此目录在32位Windows上不存在。"和"在32位Windows上,该函数总是失败,扩展错误设置为ERROR_CALL_NOT_IMPLEMENTED。"
个人对IsWow64Process的使用不确定,因为在MSDN中,在IsWow64Process的描述中有文本“请注意,这种技术不是可靠的方法来检测操作系统是否为64位版本的Windows,因为当前版本的32位Windows中的Kernel32.dll也包含此功能。”

这是我见过最简单的方式 - BattleTested_закалённый в бою

1

另外一种最简单的方法是使用sizeof(int *)检查整数指针的大小。

如果是4,则为32位
如果是8,则为64位


1
bool IsX64win()
{
    UINT x64test = GetSystemWow64DirectoryA(NULL, 0);
    if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)  return FALSE;
    else return TRUE;
}

另一种方法是使用“GetNativeSystemInfo”。 - TheMaster Moh

0

这里有一个未记录的方法...

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接