Sean Asadipour
Sean Asadipour

Reputation: 49

Get Windows Version

How can I accurately detect the current Windows operating system on a native (C/C++) project in Visual Studio 2012.3 for operating systems past Windows 8.1?

I've looked in to VersionHelperAPI under MS recommendation, but this solution only applies to VS2013.

Previously we used GetVersionEx(), but I'd like a solution that is more stable and future-proof in a way. It seems like MS is planning to deprecate this in the future.

Upvotes: 2

Views: 3383

Answers (1)

Barmak Shemirani
Barmak Shemirani

Reputation: 31599

The important thing is to include compatibility flags in manifest file:
Targeting your application for Windows

Here are the relevant parts:

<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> 
    <application> 
        <!-- Windows 10 --> 
        <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
        <!-- Windows 8.1 -->
        <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
        <!-- Windows Vista -->
        <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> 
        <!-- Windows 7 -->
        <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
        <!-- Windows 8 -->
        <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
    </application> 
</compatibility>

Without the above tags, when running on Windows 10, GetVersionEx and VerifyVersionInfoW will see Windows 8

Microsoft insists you should use VerifyVersionInfoW, not GetVersionEx

There are some helper functions which are not available in earlier VS version. But you may find them on your computer in this directory:

"C:\Program Files (x86)\Windows Kits\8.1\Include\um\VersionHelpers.h"

Here is what they are (I modified them slightly because they were too long, and tested it for Windows 10, you should double-check for older Windows versions)

#define _WIN32_WINNT_NT4      0x0400
#define _WIN32_WINNT_WIN2K    0x0500
#define _WIN32_WINNT_WINXP    0x0501
#define _WIN32_WINNT_WS03     0x0502
#define _WIN32_WINNT_WIN6     0x0600
#define _WIN32_WINNT_VISTA    0x0600
#define _WIN32_WINNT_WS08     0x0600
#define _WIN32_WINNT_LONGHORN 0x0600
#define _WIN32_WINNT_WIN7     0x0601
#define _WIN32_WINNT_WIN8     0x0602
#define _WIN32_WINNT_WINBLUE  0x0603
#define _WIN32_WINNT_WIN10    0x0A00

BOOL IsWinVersionOrGreater(DWORD id, WORD wServicePackMajor)
{
    WORD wMajorVersion = HIBYTE(id);
    WORD wMinorVersion = LOBYTE(id);

    OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0,{ 0 }, 0, 0 };
    DWORDLONG const dwlConditionMask =
        VerSetConditionMask(
            VerSetConditionMask(
                VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL),
                VER_MINORVERSION, VER_GREATER_EQUAL),
            VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);

    osvi.dwMajorVersion = wMajorVersion;
    osvi.dwMinorVersion = wMinorVersion;
    osvi.wServicePackMajor = wServicePackMajor;

    return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
}

BOOL IsWindowsXPOrGreater()      {  return IsWinVersionOrGreater(_WIN32_WINNT_WINXP, 0);}
BOOL IsWindowsXPSP1OrGreater()   {  return IsWinVersionOrGreater(_WIN32_WINNT_WINXP, 1);}
BOOL IsWindowsXPSP2OrGreater()   {  return IsWinVersionOrGreater(_WIN32_WINNT_WINXP, 2);}
BOOL IsWindowsXPSP3OrGreater()   {  return IsWinVersionOrGreater(_WIN32_WINNT_WINXP, 3);}
BOOL IsWindowsVistaOrGreater()   {  return IsWinVersionOrGreater(_WIN32_WINNT_VISTA, 0);}
BOOL IsWindowsVistaSP1OrGreater(){  return IsWinVersionOrGreater(_WIN32_WINNT_VISTA, 1);}
BOOL IsWindowsVistaSP2OrGreater(){  return IsWinVersionOrGreater(_WIN32_WINNT_VISTA, 2);}
BOOL IsWindows7OrGreater()       {  return IsWinVersionOrGreater(_WIN32_WINNT_WIN7,  0);}
BOOL IsWindows7SP1OrGreater()    {  return IsWinVersionOrGreater(_WIN32_WINNT_WIN7,  1);}
BOOL IsWindows8OrGreater()       {  return IsWinVersionOrGreater(_WIN32_WINNT_WIN8,  0);}
BOOL IsWindows8Point1OrGreater() {  return IsWinVersionOrGreater(_WIN32_WINNT_WINBLUE, 0); }
BOOL IsWindows10OrGreater()      {  return IsWinVersionOrGreater(_WIN32_WINNT_WIN10, 0); }

BOOL IsWindowsServer()
{
    OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0,{ 0 }, 0, 0, 0, VER_NT_WORKSTATION };
    DWORDLONG const dwlConditionMask = VerSetConditionMask(0, VER_PRODUCT_TYPE, VER_EQUAL);
    return !VerifyVersionInfoW(&osvi, VER_PRODUCT_TYPE, dwlConditionMask);
}

Upvotes: 2

Related Questions