Microsoft released Windows Server 2019 on October 2, 2018. From Windows 2000 and up until this Windows version, you could call a WinAPI function GetVersionEx with a struct OSVERSIONINFOEX and depending on the variables of dwMajorVersion
, dwMinorVersion
and wProductType
determine Windows version, for example, Windows 8.1, Windows 10, Windows Server 2012 R2. The code everyone used was something like this:
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");
}
}
Judging from Wikipedia the Windows Server 2019 has the same version number of NT 10.0 as Server 2016. So the above code does not work anymore.
Also, Microsoft Docs contains the following note: GetVersionEx may be altered or unavailable for releases after Windows 8.1. Instead, use the Version Helper functions.
Unfortunately, the Version Helper functions does not have a function to detect Server 2019. Also, the strange thing is that Docs page about Targeting stops at the Windows 10, and does not talk about Server editions, while these Targeting manifests is mandatory for detecting OS above Windows 8.1 or Server 2012.
Update 1.
As @IInspectable and @RbMm commented about usage of RtlGetVersion
function. So I ran the following code (taken from this answer):
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;
}
And here are the results for Windows 10:
Windows Server 2019:
Update2. As requested, posting full info from OSVERSIONINFOEX struct that was obtained via GetVersionEx call with a manifest file containing all the Targets till Windows 10 (see the Targeting link above):
// 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
Update 3. Calling RtlGetVersion
with a struct RTL_OSVERSIONINFOEXW
we get exactly the same result as in Update 2.
According to discussions in Windows Server 2019 version info:
[Windows] Server 2019 Datacenter Edition build 17744, the ReleaseId field shows 1809.
So something like this should do the trick:
const auto isWinServer2019Plus =
IsWindowsServer() &&
IsWindowsVersionOrGreater(10, 0, 1803);
Apart from checking MajorVersion
, MinorVersion
and ProductType
you also have to check the ReleaseId
or BuildNumber
.
ReleaseId: 1809
and BuildNumber: 17763
are associated with the release versions of Windows Server 2019 and Windows Server, version 1809. So by checking for those numbers you should at least be sure that you're either dealing with
Windows Server 2019 or Windows Server, version 1809 (Semi-Annual Channel) (Datacenter Core, Standard Core).
See: Windows Server release information
Note: Insider Preview builds of Windows Server 2019 can have ReleaseId 1803 or BuildNumbers below 17763.
In this thread Mary Hoffman from Microsoft says:
ReleaseId
1809 is associated with Windows Server 2019 and Windows Server, version 1809 only. (post)
Windows Server 2016 will always be 1607. Once a product is released, that ID will not change. (post)
Following that logic Windows Server 2019 will also always be 1809
.
You can read the ReleaseId from this registry key:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion - ReleaseId
See: How to read a value from the Windows registry
BuildNumber
Windows Server 2019 stops at 17763. That was the final major build number.
Anything higher than that (>=17764) will be vNext builds. (post)
Windows Server 2016 will always be 10.0.14393.### where ### increments as cumulative updates are installed.
Windows Server 2019 will always be 10.0.17763.### where ### increments as cumulative updates are installed. (post)
So BuildNumber 17763
should always correspond to Window Server 2019 or Windows Server, version 1809 (or Windows 10 1809, but checking ProductType
tells you if its a server).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With