C++ How to detect Windows 10
I have written a PC auditing tool many years ago and have been keeping it up to date. One of basic functions is reporting the version of Windows running on the PC being audited for which I have always used the GetVersionEx call.
This works up to and including Windows 8 but is not supported under Windows 10 and indeed Windows 10 returns 8.2 just as windows 8 does. Microsoft do not seem to have introduced anything as a direct replacement suggesting instead that you check for specific features required rather than looking at the OS but for the purpose of the audit I actually want the OS name.
The 'scanner' is a C++ program which must run under non-privileged accounts so I don't think another suggestion I have read - picking up the version of a system DLL such as kernel32.dll will work as these folders are typically not accessible to users.
Any other suggestions/thoughts are most welcome!
Solution 1:
GetVersion and GetVersionEx were superseded by various version helper functions. The one you want is IsWindows10OrGreater. They can be found in VersionHelpers.h.
IsWindows10OrGreater is only available in the latest SDK/Visual Studio 2015. You can use IsWindowsVersionOrGreater in the general case however. For example on my 7 box I get TRUE for IsWindowsVersionOrGreater(6, 0, 0).
Remember that the parameters this function takes relate to Windows build number and NOT marketing name. So Windows 8 is build 6.2. Windows 7 is 6.0 etc.
Solution 2:
Starting in Windows 8.1, GetVersion()
and GetVersionEx()
are subject to application manifestation:
With the release of Windows 8.1, the behavior of the
GetVersionEx
API has changed in the value it will return for the operating system version. The value returned by theGetVersionEx
function now depends on how the application is manifested.Applications not manifested for Windows 8.1 or Windows 10 will return the Windows 8 OS version value (6.2). Once an application is manifested for a given operating system version,
GetVersionEx
will always return the version that the application is manifested for in future releases. To manifest your applications for Windows 8.1 or Windows 10, refer to Targeting your application for Windows.
The newer Version Helper functions are simply wrappers for VerifyVersionInfo()
. Starting in Windows 10, it is now subject to manifestation as well:
Windows 10:
VerifyVersionInfo
returns false when called by applications that do not have a compatibility manifest for Windows 8.1 or Windows 10 if thelpVersionInfo
parameter is set so that it specifies Windows 8.1 or Windows 10, even when the current operating system version is Windows 8.1 or Windows 10. Specifically,VerifyVersionInfo
has the following behavior:
- If the application has no manifest,
VerifyVersionInfo
behaves as if the operation system version is Windows 8 (6.2).- If the application has a manifest that contains the GUID that corresponds to Windows 8.1,
VerifyVersionInfo
behaves as if the operation system version is Windows 8.1 (6.3).- If the application has a manifest that contains the GUID that corresponds to Windows 10,
VerifyVersionInfo
behaves as if the operation system version is Windows 10 (10.0).The Version Helper functions use the
VerifyVersionInfo
function, so the behaviorIsWindows8Point1OrGreater
andIsWindows10OrGreater
are similarly affected by the presence and content of the manifest.To manifest your applications for Windows 8.1 or Windows 10, see Targeting your application for Windows.
To get the true OS version regardless of manifestation, Microsoft suggests querying the file version of a system DLL:
Getting the System Version
To obtain the full version number for the operating system, call the
GetFileVersionInfo
function on one of the system DLLs, such asKernel32.dll
, then callVerQueryValue
to obtain the\\StringFileInfo\\<lang><codepage>\\ProductVersion
subblock of the file version information.
Another way is to use RtlGetVersion()
, NetServerGetInfo()
, or NetWkstaGetInfo()
instead. They all report an accurate OS version and are not subject to manifestation (yet?).
Solution 3:
Use the following function:
double getSysOpType()
{
double ret = 0.0;
NTSTATUS(WINAPI *RtlGetVersion)(LPOSVERSIONINFOEXW);
OSVERSIONINFOEXW osInfo;
*(FARPROC*)&RtlGetVersion = GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion");
if (NULL != RtlGetVersion)
{
osInfo.dwOSVersionInfoSize = sizeof(osInfo);
RtlGetVersion(&osInfo);
ret = (double)osInfo.dwMajorVersion;
}
return ret;
}
It will return the Windows version as a double (7, 8, 8.1, 10).