检测Windows 10版本

hg_*_*git 20 c++ windows winapi

我的目标是在我的代码中检测Windows 10,它必须跨平台以及不同版本的Windows(至少7及以上版本)工作.Windows提供IsWindows10OrGreater()了解决此问题的方法,但是还有另一个问题,此功能在以前的Windows版本中不存在.

你会发现无数的博客和SO问题,以及明显的疯狂,像这样和getversion等功能返回一些不同的版本,而不是正确的版本.

例如在我的机器上 - 该方法IsWindows10OrGreater()无法编译(我将安装Win10 SDK),并IsWindowsVersionOrGreater()报告6为主要版本.

那么有一种理智的多版本方式我可以解决这个问题吗?

IIn*_*ble 42

检索真实操作系统版本最直接的方法是调用RtlGetVersion.它是什么GetVersionExVerifyVersionInfo调用,但不使用兼容性垫片.

您可以使用DDK(通过#including <ntddk.h>并从内核模式链接NtosKrnl.lib,或从用户模式链接到ntdll.lib),或使用运行时动态链接,如下面的代码片段所示:

typedef LONG NTSTATUS, *PNTSTATUS;
#define STATUS_SUCCESS (0x00000000)

typedef NTSTATUS (WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);

RTL_OSVERSIONINFOW GetRealOSVersion() {
    HMODULE hMod = ::GetModuleHandleW(L"ntdll.dll");
    if (hMod) {
        RtlGetVersionPtr fxPtr = (RtlGetVersionPtr)::GetProcAddress(hMod, "RtlGetVersion");
        if (fxPtr != nullptr) {
            RTL_OSVERSIONINFOW rovi = { 0 };
            rovi.dwOSVersionInfoSize = sizeof(rovi);
            if ( STATUS_SUCCESS == fxPtr(&rovi) ) {
                return rovi;
            }
        }
    }
    RTL_OSVERSIONINFOW rovi = { 0 };
    return rovi;
}
Run Code Online (Sandbox Code Playgroud)

如果您需要其他信息,可以传递RTL_OSVERSIONINFOEXW结构来代替RTL_OSVERSIONINFOW结构(正确分配dwOSVersionInfoSize成员).

这将返回Windows 10上的预期结果,即使没有附加清单也是如此.


另外,它通常被认为是基于可用功能而不是OS版本提供不同实现的更好解决方案.

  • 呃...如何检测功能支持? (3认同)
  • @ Cu2S:这取决于功能.如果某个功能作为新导出引入(例如[GetDpiForMonitor](https://msdn.microsoft.com/en-us/library/windows/desktop/dn280510.aspx)),您可以使用运行时动态链接,如代码中所示以上.如果将某个功能添加为COM接口,则可以像往常一样调用`QueryInterface`.如果将某个功能作为新参数/标志引入函数,请使用它并观察返回值. (3认同)