繁体   English   中英

检测 Windows 的 32 位或 64 位

[英]Detect 32-bit or 64-bit of Windows

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

要调用的 function 是IsWow64ProcessIsWow64Process2 它会告诉您的 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM