Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Check if Windows 10

I am making an app to OS specific but I can't seem to narrow down Windows 10, it comes up as Windows 8. I have tested it on Window 10 Pro and the outcome is Major: 6 Min:2. Is there another way to check if it's windows 10 more efficiently?

EDIT: Found a properly working API RtlGetVersion() works for all OS's properly!

#include "windows.h"
#include <iostream>
using namespace std;
BOOL EqualsMajorVersion(DWORD majorVersion)
{
OSVERSIONINFOEX osVersionInfo;
::ZeroMemory(&osVersionInfo, sizeof(OSVERSIONINFOEX));
osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
osVersionInfo.dwMajorVersion = majorVersion;
ULONGLONG maskCondition = ::VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
return ::VerifyVersionInfo(&osVersionInfo, VER_MAJORVERSION, maskCondition);
}
BOOL EqualsMinorVersion(DWORD minorVersion)
{
OSVERSIONINFOEX osVersionInfo;
::ZeroMemory(&osVersionInfo, sizeof(OSVERSIONINFOEX));
osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
osVersionInfo.dwMinorVersion = minorVersion;
ULONGLONG maskCondition = ::VerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL);
return ::VerifyVersionInfo(&osVersionInfo, VER_MINORVERSION, maskCondition);
}
int main()
{
    if (EqualsMajorVersion(7) && EqualsMinorVersion(1))
        printf("Maj:7 Min:1");
    else if (EqualsMajorVersion(7) && EqualsMinorVersion(0))
        printf("Maj:7 Min:0");
    else if (EqualsMajorVersion(6) && EqualsMinorVersion(7))
        printf("Maj:6 Min:7");
    else if (EqualsMajorVersion(6) && EqualsMinorVersion(6))
        printf("Maj:6 Min:6");
    else if (EqualsMajorVersion(6) && EqualsMinorVersion(5))
        printf("Maj:6 Min:5");
    else if (EqualsMajorVersion(6) && EqualsMinorVersion(4))
        printf("Maj:6 Min:4");
    else if (EqualsMajorVersion(6) && EqualsMinorVersion(3))
        printf("Maj:6 Min:3");
    else if (EqualsMajorVersion(6) && EqualsMinorVersion(2))
        printf("Maj:6 Min:2");
    else if (EqualsMajorVersion(6) && EqualsMinorVersion(1))
        printf("Maj:6 Min:1");
    else if (EqualsMajorVersion(6) && EqualsMinorVersion(0))
        printf("Maj:6 Min:0");
    else if (EqualsMajorVersion(5) && EqualsMinorVersion(2))
        printf("Maj:5 Min:2");
    else if (EqualsMajorVersion(5) && EqualsMinorVersion(1))
        printf("Maj:5 Min:1");
    else
        printf("OS not on list...");
    getchar();
}
like image 367
user3732111 Avatar asked Aug 25 '15 00:08

user3732111


4 Answers

This is pretty ironic, but...

BOOL WINAPI IsWindows10OrGreater(void);

Docs here.

Edit: The geniuses from Redmond appear to have problems thinking with prototypes, or in other words, the OP gets an undefined symbol error as stated in the comments. There's also this function:

BOOL WINAPI IsWindowsVersionOrGreater(
    WORD wMajorVersion,
    WORD wMinorVersion,
    WORD wServicePackMajor
);

And, for Windows 10, wMajorVersion, wMinorVersion, and wServicePackMajor appear to be, respectively, 10, 0, and 0.

Docs for that function here.

Second edit: It's official: IsWindowsVersionOrGreater() and GetVersionEx() are broken from 8.1 onwards. Use IsWindowsXXXOrGreater() always instead, where XXX can be XP, XPSP1, XPSP2, XPSP3, Vista, VistaSP1, VistaSP2, 7, 7SP1, 8, 8Point1, 10, or Server.

like image 133
3442 Avatar answered Nov 14 '22 12:11

3442


Following worked for me :

.
.
.
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
.
.
.

typedef void (WINAPI * RtlGetVersion_FUNC) (OSVERSIONINFOEXW *);
BOOL GetVersion(OSVERSIONINFOEX * os) {
    HMODULE hMod;
    RtlGetVersion_FUNC func;
#ifdef UNICODE
    OSVERSIONINFOEXW * osw = os;
#else
    OSVERSIONINFOEXW o;
    OSVERSIONINFOEXW * osw = &o;
#endif

    hMod = LoadLibrary(TEXT("ntdll.dll"));
    if (hMod) {
        func = (RtlGetVersion_FUNC)GetProcAddress(hMod, "RtlGetVersion");
        if (func == 0) {
            FreeLibrary(hMod);
            return FALSE;
        }
        ZeroMemory(osw, sizeof (*osw));
        osw->dwOSVersionInfoSize = sizeof (*osw);
        func(osw);
#ifndef UNICODE
        os->dwBuildNumber = osw->dwBuildNumber;
        os->dwMajorVersion = osw->dwMajorVersion;
        os->dwMinorVersion = osw->dwMinorVersion;
        os->dwPlatformId = osw->dwPlatformId;
        os->dwOSVersionInfoSize = sizeof (*os);
        DWORD sz = sizeof (os->szCSDVersion);
        WCHAR * src = osw->szCSDVersion;
        unsigned char * dtc = (unsigned char *)os->szCSDVersion;
        while (*src)
            * Dtc++ = (unsigned char)* src++;
        *Dtc = '\ 0';
#endif

    } else
        return FALSE;
    FreeLibrary(hMod);
    return TRUE;
}

.
.
.

//check win10
void mymethod() {

OSVERSIONINFOEX os;

    if (GetVersion(&os) == TRUE && os.dwMajorVersion == 10)
    {
        isWin10 = TRUE;
    }

}

Ref. : ( http://yamatyuu.net/computer/program/vc2013/rtlgetversion/index.html )

like image 22
zeetit Avatar answered Nov 14 '22 10:11

zeetit


UPDATE: checked win7, win8.1 and win10. now everything determinating. So code:

#include <windows.h>
#include <VersionHelpers.h>
#include <string>

std::string getWinVerion() {

OSVERSIONINFO info;
ZeroMemory(&info, sizeof(OSVERSIONINFO));
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

GetVersionEx(&info);

std::string version = std::to_string(info.dwMajorVersion);
version.append(".").append(std::to_string(info.dwMinorVersion));

if (IsWindows7SP1OrGreater()) {
    if (version == "6.1")
        return "6.1";
}

if (IsWindows8Point1OrGreater())
    return "6.3";
else
    return "10.0";
}
like image 41
Mr.T Avatar answered Nov 14 '22 12:11

Mr.T


That is true , the only way to detect if this is Windows 10 is by using

BOOL WINAPI IsWindows10OrGreater(void);

Although you need to have the latest SDK using Visual Studio 2015. Be aware that

BOOL WINAPI IsWindowsVersionOrGreater(
WORD wMajorVersion,
WORD wMinorVersion,
WORD wServicePackMajor);

is NOT working on Windows 10, likewise the :

BOOL WINAPI GetVersionEx( _Inout_ LPOSVERSIONINFO lpVersionInfo);

Which is returning 6.2 or 6.3 sometimes. (Fully depricated on Windows 10).

like image 2
igoutas Avatar answered Nov 14 '22 11:11

igoutas