C++如何检测Windows Server 2019?

Mar*_* B. 9 c++ windows winapi

Microsoft于2018年10月2日发布了Windows Server 2019.从Windows 2000到Windows版本,您可以使用结构OSVERSIONINFOEX并根据变量调用WinAPI函数GetVersionEx,并确定Windows版本,例如Windows 8.1, Windows 10,Windows Server 2012 R2.每个人使用的代码都是这样的:dwMajorVersiondwMinorVersionwProductType

OSVERSIONINFOEX osvi;
SecureZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if (GetVersionEx(&osvi)) {
    if (osvi.dwMajorVersion == 10 &&
        osvi.dwMinorVersion == 0 &&
        osvi.wProductType != VER_NT_WORKSTATION) {
            Console->Log("We are running on Windows Server 2016");
        }
}
Run Code Online (Sandbox Code Playgroud)

维基百科来看,Windows Server 2019与Server 2016具有相同的NT 10.0版本号.因此上述代码不再起作用.

此外,Microsoft Docs包含以下注释:Windows 8.1之后的版本可能会更改或不可用GetVersionEx.而是使用版本助手功能.

不幸的是,版本助手功能没有检测服务器2019的功能.另外,奇怪的是,关于目标的文档页面在Windows 10停止,并且没有谈论服务器版本,而这些目标清单是检测操作系统必需的在Windows 8.1或Server 2012之上.

更新1. 由于@IInspectable和@RbMm评论了RtlGetVersion函数的用法.所以我运行了以下代码(取自这个答案):

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)

以下是Windows 10的结果:

  • dwMajorVersion = 10
  • dwMinorVersion = 0
  • dwBuildNumber = 17134
  • dwPlatformId = 2

Windows Server 2019:

  • dwMajorVersion = 10
  • dwMinorVersion = 0
  • dwBuildNumber = 17763
  • dwPlatformId = 2

UPDATE2.根据要求,从OSVERSIONINFOEX结构中发布完整信息,该结构通过GetVersionEx调用获得,其中包含直到Windows 10的所有目标的清单文件(请参阅上面的Targeting链接):

// Windows 10
osvi.dwOSVersionInfoSize = 284
osvi.dwMajorVersion = 10
osvi.dwMinorVersion = 0
osvi.dwBuildNumber = 17134
osvi.dwPlatformId = 2
osvi.szCSDVersion =
osvi.wServicePackMinor = 0
osvi.wServicePackMinor = 0
osvi.wSuiteMask = 256  // 0x100
osvi.wProductType = 1
osvi.wReserved = 0

// Windows Server 2016
osvi.dwOSVersionInfoSize = 284
osvi.dwMajorVersion = 10
osvi.dwMinorVersion = 0
osvi.dwBuildNumber = 14393
osvi.dwPlatformId = 2
osvi.szCSDVersion =
osvi.wServicePackMinor = 0
osvi.wServicePackMinor = 0
osvi.wSuiteMask = 400
osvi.wProductType = 3
osvi.wReserved = 0

// Windows Server 2019
osvi.dwOSVersionInfoSize = 284
osvi.dwMajorVersion = 10
osvi.dwMinorVersion = 0
osvi.dwBuildNumber = 17763
osvi.dwPlatformId = 2
osvi.szCSDVersion =
osvi.wServicePackMinor = 0
osvi.wServicePackMinor = 0
osvi.wSuiteMask = 400  // 0x190
osvi.wProductType = 3
osvi.wReserved = 0
Run Code Online (Sandbox Code Playgroud)

更新3.RtlGetVersion使用结构调用,RTL_OSVERSIONINFOEXW我们得到与Update 2中完全相同的结果.

小智 0

每个新的 Windows 版本都是同样的情况。Windows 2019 再次

您应该使用VerifyVersionInfoW ...但也要更新您的程序清单。

问题是:新的 Windows 版本的清单是什么......

Windows 2016 通过 id 与 Windows 10 链接:

请参阅此处:https://learn.microsoft.com/en-us/windows/desktop/sbscs/application-manifests