GetVersionEx работает неправильно

302
26 ноября 2016, 18:57
OSVERSIONINFOEX ovi;
  ZeroMemory(&ovi, sizeof(OSVERSIONINFOEX));
  ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  GetVersionEx((OSVERSIONINFO*)&ovi);
  printf("dwMajorVersion = %d\n", ovi.dwMajorVersion);

Под Windows 10 выдаёт значение 6, хотя должно 10. Почему так?

P.S. Манифест отключил

Answer 1

Как - то так - код рабочий 100%:

tstring system_controll::SystemControll::getWindowsVersion()
{
    tstring versionOC;
    SYSTEM_INFO sysInfo{};
    typedef void(__stdcall *GETSYSTEMINFO) (LPSYSTEM_INFO);
    OSVERSIONINFOEX os_ver{};
    os_ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
    if (!GetVersionEx((LPOSVERSIONINFO)&os_ver)) { msg_er_full; return  versionOC; }
    DWORD major{};
    DWORD minor{};
    LPBYTE pinfoRawData{};
    if (NERR_Success == NetWkstaGetInfo(NULL, 100, &pinfoRawData))
    {
        WKSTA_INFO_100* pworkstationInfo = (WKSTA_INFO_100*)pinfoRawData;
        major = pworkstationInfo->wki100_ver_major;
        minor = pworkstationInfo->wki100_ver_minor;
        os_ver.dwMajorVersion = major;
        os_ver.dwMinorVersion = minor;
        if (NERR_Success != NetApiBufferFree(pinfoRawData)) { msg_er_full; }
    }
    else if (os_ver.dwMajorVersion == 6 && os_ver.dwMinorVersion == 2)
    {
        OSVERSIONINFOEXW osvi{};
        osvi.dwOSVersionInfoSize = sizeof(osvi);
        osvi.dwMinorVersion = 3;
        ULONGLONG cm{};
        cm = VerSetConditionMask(cm, VER_MINORVERSION, VER_EQUAL);
        if (VerifyVersionInfoW(&osvi, VER_MINORVERSION, cm))
        {
            os_ver.dwMinorVersion = 3;
        }
    }
    GETSYSTEMINFO getSysInfo = (GETSYSTEMINFO)GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "GetNativeSystemInfo");
    if (getSysInfo == NULL)  getSysInfo = ::GetSystemInfo;
    getSysInfo(&sysInfo);
    if (os_ver.dwMajorVersion == 10 && os_ver.dwMinorVersion >= 0 && os_ver.wProductType != VER_NT_WORKSTATION)  versionOC = _T("Windows 10 Server");
    if (os_ver.dwMajorVersion == 10 && os_ver.dwMinorVersion >= 0 && os_ver.wProductType == VER_NT_WORKSTATION)  versionOC = _T("Windows 10");
    if (os_ver.dwMajorVersion == 6 && os_ver.dwMinorVersion == 3 && os_ver.wProductType != VER_NT_WORKSTATION)  versionOC = _T("Windows Server 2012 R2");
    if (os_ver.dwMajorVersion == 6 && os_ver.dwMinorVersion == 3 && os_ver.wProductType == VER_NT_WORKSTATION)  versionOC = _T("Windows 8.1");
    if (os_ver.dwMajorVersion == 6 && os_ver.dwMinorVersion == 2 && os_ver.wProductType != VER_NT_WORKSTATION)  versionOC = _T("Windows Server 2012");
    if (os_ver.dwMajorVersion == 6 && os_ver.dwMinorVersion == 2 && os_ver.wProductType == VER_NT_WORKSTATION)  versionOC = _T("Windows 8");
    if (os_ver.dwMajorVersion == 6 && os_ver.dwMinorVersion == 1 && os_ver.wProductType != VER_NT_WORKSTATION)  versionOC = _T("Windows Server 2008 R2");
    if (os_ver.dwMajorVersion == 6 && os_ver.dwMinorVersion == 1 && os_ver.wProductType == VER_NT_WORKSTATION)  versionOC = _T("Windows 7");
    if (os_ver.dwMajorVersion == 6 && os_ver.dwMinorVersion == 0 && os_ver.wProductType != VER_NT_WORKSTATION)  versionOC = _T("Windows Server 2008");
    if (os_ver.dwMajorVersion == 6 && os_ver.dwMinorVersion == 0 && os_ver.wProductType == VER_NT_WORKSTATION)  versionOC = _T("Windows Vista");
    if (os_ver.dwMajorVersion == 5 && os_ver.dwMinorVersion == 2 && os_ver.wProductType == VER_NT_WORKSTATION &&  sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)  versionOC = _T("Windows XP x64");
    if (os_ver.dwMajorVersion == 5 && os_ver.dwMinorVersion == 2)   versionOC = _T("Windows Server 2003");
    if (os_ver.dwMajorVersion == 5 && os_ver.dwMinorVersion == 1)   versionOC = _T("Windows XP");
    if (os_ver.dwMajorVersion == 5 && os_ver.dwMinorVersion == 0)   versionOC = _T("Windows 2000");
    if (os_ver.dwMajorVersion < 5)   versionOC = _T("unknown");
    if (os_ver.wServicePackMajor != 0)
    {
        tstring sp;
        TCHAR buf[128]{};
        sp = _T(" Service Pack ");
#ifdef UNICODE
        swprintf_s(buf, sizeof(buf), _T("%hd"), os_ver.wServicePackMajor);
#else
        sprintf_s(buf, sizeof(buf), _T("%hd"), os_ver.wServicePackMajor);
#endif
        sp.append(buf);
        versionOC += sp;
    }
    return versionOC;
}
Answer 2

MSDN об этом сообщает английским по белому:

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 the GetVersionEx 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.

READ ALSO
Как передать шаблон функции в другую функцию?

Как передать шаблон функции в другую функцию?

Как правильно написать функцию test, чтобы ей в качестве аргумента (либо шаблонного параметра - не важно) можно было передать любую из функций...

241
Как отредактировать .idb файл?

Как отредактировать .idb файл?

Есть коммерческое ПО, при каждом запуске оно подключается к файлу базы данных, файл именуется как uchetatiidb

257
Аналог битового поля на C#

Аналог битового поля на C#

Есть следующий код на C++:

357
Погрешность std::chrono::steady_clock

Погрешность std::chrono::steady_clock

Мне необходимо каждый час выполнять какие то действияСоздаю что то типа таймера с помощью std::chrono::steady_clock, в while проверяю или пришло время выполнять...

271