Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting Windows 10 version

Tags:

My objective is to detect Windows 10 in my code which has to work cross-platform as well as across different versions of Windows (atleast 7 & up). Windows provides IsWindows10OrGreater() to tackle this problem, but there's another issue with it, this function isn't present in previous windows versions.

You'll find countless blogs and SO questions regarding this as well as the manifest madness where functions like this and getversion and others return some different version rather than the correct one.

For example on my machine - the method IsWindows10OrGreater() doesn't compile(I would've to install Win10 SDK), and IsWindowsVersionOrGreater() reports 6 as major version.

So is there a sane multi-version way I could solve this problem?

like image 443
hg_git Avatar asked Apr 11 '16 08:04

hg_git


People also ask

How do I identify my Windows 10 version?

Windows® 10Click the Start or Windows button (usually in the lower-left corner of your computer screen). Click Settings. Click About (usually in the lower left of the screen). The resulting screen shows the edition of Windows.

What build of Windows 10 do I have?

Type "winver" in the search box and press Enter. You should see the About Windows box with your Windows version information appear.


1 Answers

The most straight-forward way to retrieve the true OS version is to call RtlGetVersion. It is what GetVersionEx and VerifyVersionInfo call, but doesn't employ the compatibility shims.

You can either use the DDK (by #including <ntddk.h> and linking against NtosKrnl.lib from kernel mode, or ntdll.lib from user mode), or use runtime dynamic linking as in the following snippet:

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

In case you need additional information you can pass an RTL_OSVERSIONINFOEXW structure in place of the RTL_OSVERSIONINFOW structure (properly assigning the dwOSVersionInfoSize member).

This returns the expected result on Windows 10, even when there is no manifest attached.


As an aside, it is commonly accepted as a better solution to provide different implementations based on available features rather than OS versions.
like image 181
IInspectable Avatar answered Sep 21 '22 12:09

IInspectable