Ошибка c4996 getversionexw объявлен deprecate

The basic question is «why are you calling GetVersionExW in the first place?» The answer to that question determines what you should do instead.

The deprecation warning is there to give developers a heads-up about the appcompat behavior change that started in Windows 8.1. See Windows and Windows Server compatibility cookbook: Windows 8, Windows 8.1, and Windows Server 2012. In short, that function doesn’t return what you think it returns by default.

Historically, badly written OS version checks are the primary source of appcompat bugs for Windows OS upgrades. There’ve been a number of different approaches to trying to mitigate this problem (the AppVerifier version lie, the VerifyVersionInfo API, etc.), and this is the most aggressive to date.

The VersionHelpers.h mentioned in the comments are in the Windows 8.1 SDK that comes with Visual Studio 2013. They are not a new API; they are just utility code that makes use of the VerifyVersionInfo API introduced back in Windows 2000. These functions are for doing «You must be this high to ride this ride» style checks which are the class of version checks that are most often badly written. The code is pretty simple. For example, the IsWindowsVistaSP2OrGreater test is:

VERSIONHELPERAPI
IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
{
    OSVERSIONINFOEXW osvi = {};
    osvi.dwOSVersionInfoSize = sizeof(osvi);
    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;
}

VERSIONHELPERAPI
IsWindowsVistaSP2OrGreater()
{
    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 2);
}

You don’t need to use VersionHelpers.h as you could just do this kind of code yourself, but they are convenient if you are already using the VS 2013 compiler. For games, I have an article What’s in a version number? which uses VerifyVersionInfo to do the kind of reasonable checks one should for game deployment.

Note if you are using VS 2013 with the v120_xp platform toolset to target Windows XP, you’ll actually be using the Windows 7.1A SDK and #include <VersionHelpers.h> won’t work. You can of course use VerifyVersionInfo directly.

The other major use of GetVersionExW is diagnostic logs and telemetry. In this case, one option is to continue to use that API and make sure you have the right manifest entries in your application to ensure reasonably accurate results. See Manifest Madness for details on what you do here to achieve this. The main thing to keep in mind is that unless you routinely update your code, you will eventually stop getting fully accurate information in a future version of the OS.

Note that it is recommended you put the <compatibility> section in an embedded manifest whether or not you care about the results of GetVersionEx as general best practice. This allows the OS to automatically apply future appcompat fixes based on knowing how the app was originally tested.

For diagnostic logs, another approach that might be a bit more robust is to grab the version number out of a system DLL like kernel32.dll using GetFileVersionInfoW. This approach has a major caveat: Do not try parsing, doing comparisons, or making code assumptions based on the file version you obtain this way; just write it out somewhere. Otherwise you risk recreating the same bad OS version check problem that is better solved with VerifyVersionInfo. This option is not available to Windows Store apps, Windows phone apps, etc. but should work for Win32 desktop apps.

#include <Windows.h>
#include <cstdint>
#include <memory>

#pragma comment(lib, "version.lib" )

bool GetOSVersionString( WCHAR* version, size_t maxlen )
{
    WCHAR path[ _MAX_PATH ] = {};
    if ( !GetSystemDirectoryW( path, _MAX_PATH ) )
        return false;

    wcscat_s( path, L"\kernel32.dll" );

    //
    // Based on example code from this article
    // http://support.microsoft.com/kb/167597
    //

    DWORD handle;
#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
    DWORD len = GetFileVersionInfoSizeExW( FILE_VER_GET_NEUTRAL, path, &handle );
#else
    DWORD len = GetFileVersionInfoSizeW( path, &handle );
#endif
    if ( !len )
        return false;

    std::unique_ptr<uint8_t> buff( new (std::nothrow) uint8_t[ len ] );
    if ( !buff )
        return false;

#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
    if ( !GetFileVersionInfoExW( FILE_VER_GET_NEUTRAL, path, 0, len, buff.get() ) )
#else
    if ( !GetFileVersionInfoW( path, 0, len, buff.get() ) )
#endif
        return false;

    VS_FIXEDFILEINFO *vInfo = nullptr;
    UINT infoSize;

    if ( !VerQueryValueW( buff.get(), L"\", reinterpret_cast<LPVOID*>( &vInfo ), &infoSize ) )
        return false;

    if ( !infoSize )
        return false;

    swprintf_s( version, maxlen, L"%u.%u.%u.%u",
                HIWORD( vInfo->dwFileVersionMS ),
                LOWORD(vInfo->dwFileVersionMS),
                HIWORD(vInfo->dwFileVersionLS),
                LOWORD(vInfo->dwFileVersionLS) );
    
    return true;
}

If there is some other reason you are calling GetVersionExW, you probably shouldn’t be calling it. Checking for a component that might be missing shouldn’t be tied to a version check. For example, if your application requires Media Foundation, you should set a «You must be this high to ride this ride check» like the VersionHelpers.h IsWindowsVistaOrGreater for deployment, but at runtime you should use explicit linking via LoadLibrary or LoadLibaryEx to report an error or use a fallback if MFPLAT.DLL is not found.

Explicit linking is not an option for Windows Store apps. Windows 8.x solves this
particular problem by having a stub MFPLAT.DLL and MFStartUp will return E_NOTIMPL.
See «Who moved my [Windows Media] Cheese»?

Another example: if your application wants to use Direct3D 11.2 if it is available and otherwise uses DirectX 11.0, you’d use set a IsWindowsVistaSP2OrGreater minimum bar for deployment perhaps using the D3D11InstallHelper. Then at runtime, you’d create the DirectX 11.0 device and if it fails, you’d report an error. If you obtain a ID3D11Device, then you’d QueryInterface for a ID3D11Device2 which if it succeeds means you are using an OS that supports DirectX 11.2. See Anatomy of Direct3D 11 Create Device.

If this hypothetical Direct3D application supports Windows XP, you’d use a deployment bar of IsWindowsXPSP2OrGreater or IsWindowsXPSP3OrGreater, and then at run time use explicit linking to try to find the D3D11.DLL. If it wasn’t present, you’d fall back to using Direct3D 9—since we set the minimum bar, we know that DirectX 9.0c or later is always present.

They key point here is that in most cases, you should not use GetVersionEx.

Note that with Windows 10, VerifyVersionInfo and getting the file version stamp via GetFileVersionInfo for kernel32.lib are now subject to the same manifest based behavior as GetVersionEx (i.e. without the manifest GUID for Windows 10, it returns results as if the OS version were 6.2 rather than 10.0).

For universal Windows apps on Windows 10, you can a new WinRT API AnalyticsInfo to get a version stamp string for diagnostic logs and telemetry.

The basic question is «why are you calling GetVersionExW in the first place?» The answer to that question determines what you should do instead.

The deprecation warning is there to give developers a heads-up about the appcompat behavior change that started in Windows 8.1. See Windows and Windows Server compatibility cookbook: Windows 8, Windows 8.1, and Windows Server 2012. In short, that function doesn’t return what you think it returns by default.

Historically, badly written OS version checks are the primary source of appcompat bugs for Windows OS upgrades. There’ve been a number of different approaches to trying to mitigate this problem (the AppVerifier version lie, the VerifyVersionInfo API, etc.), and this is the most aggressive to date.

The VersionHelpers.h mentioned in the comments are in the Windows 8.1 SDK that comes with Visual Studio 2013. They are not a new API; they are just utility code that makes use of the VerifyVersionInfo API introduced back in Windows 2000. These functions are for doing «You must be this high to ride this ride» style checks which are the class of version checks that are most often badly written. The code is pretty simple. For example, the IsWindowsVistaSP2OrGreater test is:

VERSIONHELPERAPI
IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
{
    OSVERSIONINFOEXW osvi = {};
    osvi.dwOSVersionInfoSize = sizeof(osvi);
    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;
}

VERSIONHELPERAPI
IsWindowsVistaSP2OrGreater()
{
    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 2);
}

You don’t need to use VersionHelpers.h as you could just do this kind of code yourself, but they are convenient if you are already using the VS 2013 compiler. For games, I have an article What’s in a version number? which uses VerifyVersionInfo to do the kind of reasonable checks one should for game deployment.

Note if you are using VS 2013 with the v120_xp platform toolset to target Windows XP, you’ll actually be using the Windows 7.1A SDK and #include <VersionHelpers.h> won’t work. You can of course use VerifyVersionInfo directly.

The other major use of GetVersionExW is diagnostic logs and telemetry. In this case, one option is to continue to use that API and make sure you have the right manifest entries in your application to ensure reasonably accurate results. See Manifest Madness for details on what you do here to achieve this. The main thing to keep in mind is that unless you routinely update your code, you will eventually stop getting fully accurate information in a future version of the OS.

Note that it is recommended you put the <compatibility> section in an embedded manifest whether or not you care about the results of GetVersionEx as general best practice. This allows the OS to automatically apply future appcompat fixes based on knowing how the app was originally tested.

For diagnostic logs, another approach that might be a bit more robust is to grab the version number out of a system DLL like kernel32.dll using GetFileVersionInfoW. This approach has a major caveat: Do not try parsing, doing comparisons, or making code assumptions based on the file version you obtain this way; just write it out somewhere. Otherwise you risk recreating the same bad OS version check problem that is better solved with VerifyVersionInfo. This option is not available to Windows Store apps, Windows phone apps, etc. but should work for Win32 desktop apps.

#include <Windows.h>
#include <cstdint>
#include <memory>

#pragma comment(lib, "version.lib" )

bool GetOSVersionString( WCHAR* version, size_t maxlen )
{
    WCHAR path[ _MAX_PATH ] = {};
    if ( !GetSystemDirectoryW( path, _MAX_PATH ) )
        return false;

    wcscat_s( path, L"\kernel32.dll" );

    //
    // Based on example code from this article
    // http://support.microsoft.com/kb/167597
    //

    DWORD handle;
#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
    DWORD len = GetFileVersionInfoSizeExW( FILE_VER_GET_NEUTRAL, path, &handle );
#else
    DWORD len = GetFileVersionInfoSizeW( path, &handle );
#endif
    if ( !len )
        return false;

    std::unique_ptr<uint8_t> buff( new (std::nothrow) uint8_t[ len ] );
    if ( !buff )
        return false;

#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
    if ( !GetFileVersionInfoExW( FILE_VER_GET_NEUTRAL, path, 0, len, buff.get() ) )
#else
    if ( !GetFileVersionInfoW( path, 0, len, buff.get() ) )
#endif
        return false;

    VS_FIXEDFILEINFO *vInfo = nullptr;
    UINT infoSize;

    if ( !VerQueryValueW( buff.get(), L"\", reinterpret_cast<LPVOID*>( &vInfo ), &infoSize ) )
        return false;

    if ( !infoSize )
        return false;

    swprintf_s( version, maxlen, L"%u.%u.%u.%u",
                HIWORD( vInfo->dwFileVersionMS ),
                LOWORD(vInfo->dwFileVersionMS),
                HIWORD(vInfo->dwFileVersionLS),
                LOWORD(vInfo->dwFileVersionLS) );
    
    return true;
}

If there is some other reason you are calling GetVersionExW, you probably shouldn’t be calling it. Checking for a component that might be missing shouldn’t be tied to a version check. For example, if your application requires Media Foundation, you should set a «You must be this high to ride this ride check» like the VersionHelpers.h IsWindowsVistaOrGreater for deployment, but at runtime you should use explicit linking via LoadLibrary or LoadLibaryEx to report an error or use a fallback if MFPLAT.DLL is not found.

Explicit linking is not an option for Windows Store apps. Windows 8.x solves this
particular problem by having a stub MFPLAT.DLL and MFStartUp will return E_NOTIMPL.
See «Who moved my [Windows Media] Cheese»?

Another example: if your application wants to use Direct3D 11.2 if it is available and otherwise uses DirectX 11.0, you’d use set a IsWindowsVistaSP2OrGreater minimum bar for deployment perhaps using the D3D11InstallHelper. Then at runtime, you’d create the DirectX 11.0 device and if it fails, you’d report an error. If you obtain a ID3D11Device, then you’d QueryInterface for a ID3D11Device2 which if it succeeds means you are using an OS that supports DirectX 11.2. See Anatomy of Direct3D 11 Create Device.

If this hypothetical Direct3D application supports Windows XP, you’d use a deployment bar of IsWindowsXPSP2OrGreater or IsWindowsXPSP3OrGreater, and then at run time use explicit linking to try to find the D3D11.DLL. If it wasn’t present, you’d fall back to using Direct3D 9—since we set the minimum bar, we know that DirectX 9.0c or later is always present.

They key point here is that in most cases, you should not use GetVersionEx.

Note that with Windows 10, VerifyVersionInfo and getting the file version stamp via GetFileVersionInfo for kernel32.lib are now subject to the same manifest based behavior as GetVersionEx (i.e. without the manifest GUID for Windows 10, it returns results as if the OS version were 6.2 rather than 10.0).

For universal Windows apps on Windows 10, you can a new WinRT API AnalyticsInfo to get a version stamp string for diagnostic logs and telemetry.

Senum

3 / 2 / 1

Регистрация: 02.05.2014

Сообщений: 92

1

10.04.2015, 01:24. Показов 15198. Ответов 4

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <locale>
using namespace std;
 
 
void VersionWindows1()
{
    OSVERSIONINFO osvi;
    ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    GetVersionEx((OSVERSIONINFO*)&osvi);
    cout << "индификатор Ос:" << osvi.dwMajorVersion << endl;
    cout << "Версия:" << osvi.dwMinorVersion << endl;
    cout << "Платформа:" << osvi.dwPlatformId << endl;
    if (osvi.dwMajorVersion == 6)
    {
 
        if (osvi.dwMinorVersion == 0)
        {
            if (osvi.dwPlatformId == 2)
                cout << "Windows Vista";
            else cout << "Windows server 2008";
        }
        if (osvi.dwMinorVersion == 1)
        {
            if (osvi.dwPlatformId == 2)
                cout << "Windows 7";
            else cout << "Windows server 2008 R2";
        }
    }
    if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
    {
        if (GetSystemMetrics(SM_SERVERR2))
            cout << "Windows server 2003 R2";
        else if (osvi.dwPlatformId == VER_SUITE_STORAGE_SERVER)
            cout << "Windows storage Server 2003";
        else if (osvi.dwPlatformId == VER_SUITE_WH_SERVER)
            cout << "Windows home server";
        else if (osvi.dwPlatformId == 2)
            cout << "Windows XP Professional x64 editon";
        else cout << "Windows server 2003";
    }
    if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
        cout << "Windows XP";
    if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
        cout << "Windows 2000";
    cout << endl;
    cout << "сборка:" << osvi.dwBuildNumber << endl;
    cout << "Доп.Инфо:" << osvi.szCSDVersion << endl;
}

ошибка
Ошибка 1 error C4996: ‘GetVersionExA’: объявлен deprecate

пытался использовать

C++
1
2
3
4
#ifdef _MSC_VER
#pragma warning( push )
#pragma warning( once: 4996 )
#endif

не помогло



0



rao

903 / 424 / 159

Регистрация: 02.04.2014

Сообщений: 1,206

10.04.2015, 19:17

2

Лучший ответ Сообщение было отмечено schdub как решение

Решение

Так это же не ошибка, а только предупреждение. В MSDN’е написано как отключить:

C++
1
#pragma warning(disable : 4996)



0



3 / 2 / 1

Регистрация: 02.05.2014

Сообщений: 92

10.04.2015, 21:02

 [ТС]

3

При добавлении этого кода возникают две другие ошибки

Ошибка 2 error LNK1120: неразрешенных внешних элементов: 1
Ошибка 1 error LNK2019: ссылка на неразрешенный внешний символ _main в функции ___tmainCRTStartup



0



903 / 424 / 159

Регистрация: 02.04.2014

Сообщений: 1,206

10.04.2015, 21:58

4



1



3 / 2 / 1

Регистрация: 02.05.2014

Сообщений: 92

10.04.2015, 22:26

 [ТС]

5

Спс,разобрался



0



Я работаю над VS 2013 в Win 8.1.
Как решить это предупреждение?

4b9b3361

Ответ 1

Основной вопрос: «Почему вы вызываете GetVersionExW в первую очередь?» Ответ на этот вопрос определяет, что вы должны делать вместо этого.

Предупреждение об устаревании должно дать разработчикам хедз-ап об изменении поведения appcompat, которое началось в Windows 8.1. См. Поваренная книга совместимости с Windows и Windows Server: Windows 8, Windows 8.1 и Windows Server 2012. Короче говоря, эта функция не возвращает то, что, по вашему мнению, возвращает по умолчанию.

Исторически, плохо написанные проверки версий ОС являются основным источником ошибок appcompat для обновлений ОС Windows. Было несколько различных подходов к устранению этой проблемы (версия AppVerifier лежит, API VerifyVersionInfo и т.д.), И это наиболее агрессивно на сегодняшний день.

VersionHelpers.h, упомянутый в комментариях, содержится в SDK Windows 8.1, который поставляется с Visual Studio 2013. Они не являются новым API; это всего лишь код утилиты, который использует API VerifyVersionInfo, введенный обратно в Windows 2000. Эти функции предназначены для того, чтобы выполнять проверки типа «Вы должны быть такими, чтобы ездить на этой поездке», которые являются классом проверки версий, которые чаще всего бывают плохо написано. Код довольно прост. Например, тест IsWindowsVistaSP2OrGreater:

VERSIONHELPERAPI
IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
{
    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;
}

VERSIONHELPERAPI
IsWindowsVistaSP2OrGreater()
{
    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 2);
}

Вам не нужно использовать VersionHelpers.h, поскольку вы могли бы просто сделать этот код самостоятельно, но они удобны, если вы уже используете компилятор VS 2013. Для игр у меня есть статья Что в номере версии?, который использует VerifyVersionInfo для выполнения разумных проверок, необходимых для развертывания игры.

Обратите внимание, что если вы используете VS 2013 с набором инструментов платформы v120_xp для целевой Windows XP, вы фактически будете использовать SDK Windows 7.1A, а #include <VersionHelpers.h> не будет работать. Конечно, вы можете напрямую использовать VerifyVersionInfo.

Другим основным использованием GetVersionExW являются диагностические журналы и телеметрия. В этом случае один из вариантов заключается в том, чтобы продолжать использовать этот API и убедиться, что у вас есть правильные записи манифеста в приложении, чтобы обеспечить достаточно точные результаты. Подробнее о том, что вы здесь делаете, см. Manifest Madness. Главное, чтобы вы имели в виду, что, если вы регулярно обновляете свой код, вы в конечном итоге перестанете получать точную информацию в будущей версии ОС.

Обратите внимание, что рекомендуется поместить раздел <compatibility> во встроенный манифест, независимо от того, насколько вы заботитесь о результатах GetVersionEx как общей лучшей практики. Это позволяет ОС автоматически применять будущие исправления appcompat, основываясь на знании того, как приложение было первоначально протестировано.

Для журналов диагностики другой подход, который может быть немного более надежным, — это захватить номер версии из системной DLL, например kernel32.dll, используя GetFileVersionInfoW. Этот подход имеет большой хаос: не пытайтесь разбираться, делать сравнения или делать допущения кода на основе версии файла, которую вы получаете таким образом; просто напишите где-нибудь. В противном случае вы рискуете воссоздать ту же самую проблему с проверкой версии ОС, которая лучше решается с помощью VerifyVersionInfo. Эта опция недоступна для приложений Windows Store, приложений для телефонов Windows и т.д., Но должна работать в настольных приложениях Win32.

#include <windows.h>
#include <stdint.h>
#include <memory>

#pragma comment(lib, "version.lib" )

bool GetOSVersionString( WCHAR* version, size_t maxlen )
{
    WCHAR path[ _MAX_PATH ];
    if ( !GetSystemDirectoryW( path, _MAX_PATH ) )
        return false;

    wcscat_s( path, L"\kernel32.dll" );

    //
    // Based on example code from this article
    // http://support.microsoft.com/kb/167597
    //

    DWORD handle;
#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
    DWORD len = GetFileVersionInfoSizeExW( FILE_VER_GET_NEUTRAL, path, &handle );
#else
    DWORD len = GetFileVersionInfoSizeW( path, &handle );
#endif
    if ( !len )
        return false;

    std::unique_ptr<uint8_t> buff( new (std::nothrow) uint8_t[ len ] );
    if ( !buff )
        return false;

#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
    if ( !GetFileVersionInfoExW( FILE_VER_GET_NEUTRAL, path, 0, len, buff.get() ) )
#else
    if ( !GetFileVersionInfoW( path, 0, len, buff.get() ) )
#endif
        return false;

    VS_FIXEDFILEINFO *vInfo = nullptr;
    UINT infoSize;

    if ( !VerQueryValueW( buff.get(), L"\", reinterpret_cast<LPVOID*>( &vInfo ), &infoSize ) )
        return false;

    if ( !infoSize )
        return false;

    swprintf_s( version, maxlen, L"%u.%u.%u.%u",
                HIWORD( vInfo->dwFileVersionMS ),
                LOWORD(vInfo->dwFileVersionMS),
                HIWORD(vInfo->dwFileVersionLS),
                LOWORD(vInfo->dwFileVersionLS) );

    return true;
}

Если есть еще одна причина, по которой вы вызываете GetVersionExW, вы, вероятно, не должны ее вызывать. Проверка компонента, который может отсутствовать, не должна быть привязана к проверке версии. Например, если вашему приложению требуется Media Foundation, вы должны установить для этого развертывания «Это должно быть высоко, чтобы выполнить эту проверку езды», например VersionHelpers.h IsWindowsVistaOrGreater, но во время выполнения вы должны использовать явное соединение через LoadLibrary или LoadLibaryEx сообщить об ошибке или использовать резервную копию, если MFPLAT.DLL не найден.

Явное связывание не является вариантом для приложений Windows Store. Windows 8.x решает эту проблему. особая проблема с помощью заглушки MFPLAT.DLL и MFStartUp вернет E_NOTIMPL. См. «Кто переместил мой [Windows Media] сыр» ?

Другой пример: если ваше приложение хочет использовать Direct3D 11.2, если оно доступно, и в противном случае использует DirectX 11.0, вы должны использовать минимальную панель IsWindowsVistaSP2OrGreater для развертывания, возможно, используя D3D11InstallHelper, Затем во время выполнения вы должны создать устройство DirectX 11.0, и если он сбой, вы сообщите об ошибке. Если вы получите ID3D11Device, вы бы QueryInterface для ID3D11Device2, который, если он преуспеет, означает, что вы используете ОС, поддерживающую DirectX 11.2. См. Анатомия Direct3D 11 Создать устройство.

Если это гипотетическое приложение Direct3D поддерживает Windows XP, вы должны использовать панель развертывания IsWindowsXPSP2OrGreater или IsWindowsXPSP3OrGreater, а затем во время выполнения используйте явное соединение, чтобы попытаться найти D3D11.DLL. Если его нет, вы вернетесь к использованию Direct3D 9 — поскольку мы устанавливаем минимальную полосу, мы знаем, что DirectX 9.0c или более поздняя версия присутствует всегда.

Ключевым моментом здесь является то, что в большинстве случаев вы не должны использовать GetVersionEx.

Обратите внимание, что при Windows 10, VerifyVersionInfo и получении штампа версии файла через GetFileVersionInfo для kernel32.lib теперь подчиняется такому же основанному на манифестам поведению, что и GetVersionEx (т.е. без манифест GUID для Windows 10, он возвращает результаты, как если бы версия ОС была 6.2, а не 10.0).

Для универсальных приложений Windows в Windows 10 вы можете использовать новый WinRT API AnalyticsInfo, чтобы получить строку штампа версии для диагностических журналов и телеметрии.

Ответ 2

вы можете отключить это предупреждение и использовать GetVersionEx в любом случае, добавив:

#pragma warning(disable : 4996)

Senum

3 / 2 / 1

Регистрация: 02.05.2014

Сообщений: 92

1

10.04.2015, 01:24. Показов 14209. Ответов 4

Метки нет (Все метки)


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <locale>
using namespace std;
 
 
void VersionWindows1()
{
    OSVERSIONINFO osvi;
    ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    GetVersionEx((OSVERSIONINFO*)&osvi);
    cout << "индификатор Ос:" << osvi.dwMajorVersion << endl;
    cout << "Версия:" << osvi.dwMinorVersion << endl;
    cout << "Платформа:" << osvi.dwPlatformId << endl;
    if (osvi.dwMajorVersion == 6)
    {
 
        if (osvi.dwMinorVersion == 0)
        {
            if (osvi.dwPlatformId == 2)
                cout << "Windows Vista";
            else cout << "Windows server 2008";
        }
        if (osvi.dwMinorVersion == 1)
        {
            if (osvi.dwPlatformId == 2)
                cout << "Windows 7";
            else cout << "Windows server 2008 R2";
        }
    }
    if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
    {
        if (GetSystemMetrics(SM_SERVERR2))
            cout << "Windows server 2003 R2";
        else if (osvi.dwPlatformId == VER_SUITE_STORAGE_SERVER)
            cout << "Windows storage Server 2003";
        else if (osvi.dwPlatformId == VER_SUITE_WH_SERVER)
            cout << "Windows home server";
        else if (osvi.dwPlatformId == 2)
            cout << "Windows XP Professional x64 editon";
        else cout << "Windows server 2003";
    }
    if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
        cout << "Windows XP";
    if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
        cout << "Windows 2000";
    cout << endl;
    cout << "сборка:" << osvi.dwBuildNumber << endl;
    cout << "Доп.Инфо:" << osvi.szCSDVersion << endl;
}

ошибка
Ошибка 1 error C4996: ‘GetVersionExA’: объявлен deprecate

пытался использовать

C++
1
2
3
4
#ifdef _MSC_VER
#pragma warning( push )
#pragma warning( once: 4996 )
#endif

не помогло

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь

0

rao

902 / 423 / 159

Регистрация: 02.04.2014

Сообщений: 1,206

10.04.2015, 19:17

2

Лучший ответ Сообщение было отмечено schdub как решение

Решение

Так это же не ошибка, а только предупреждение. В MSDN’е написано как отключить:

C++
1
#pragma warning(disable : 4996)

0

3 / 2 / 1

Регистрация: 02.05.2014

Сообщений: 92

10.04.2015, 21:02

 [ТС]

3

При добавлении этого кода возникают две другие ошибки

Ошибка 2 error LNK1120: неразрешенных внешних элементов: 1
Ошибка 1 error LNK2019: ссылка на неразрешенный внешний символ _main в функции ___tmainCRTStartup

0

902 / 423 / 159

Регистрация: 02.04.2014

Сообщений: 1,206

10.04.2015, 21:58

4

1

3 / 2 / 1

Регистрация: 02.05.2014

Сообщений: 92

10.04.2015, 22:26

 [ТС]

5

Спс,разобрался

0

The basic question is «why are you calling GetVersionExW in the first place?» The answer to that question determines what you should do instead.

The deprecation warning is there to give developers a heads-up about the appcompat behavior change that started in Windows 8.1. See Windows and Windows Server compatibility cookbook: Windows 8, Windows 8.1, and Windows Server 2012. In short, that function doesn’t return what you think it returns by default.

Historically, badly written OS version checks are the primary source of appcompat bugs for Windows OS upgrades. There’ve been a number of different approaches to trying to mitigate this problem (the AppVerifier version lie, the VerifyVersionInfo API, etc.), and this is the most aggressive to date.

The VersionHelpers.h mentioned in the comments are in the Windows 8.1 SDK that comes with Visual Studio 2013. They are not a new API; they are just utility code that makes use of the VerifyVersionInfo API introduced back in Windows 2000. These functions are for doing «You must be this high to ride this ride» style checks which are the class of version checks that are most often badly written. The code is pretty simple. For example, the IsWindowsVistaSP2OrGreater test is:

VERSIONHELPERAPI
IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
{
    OSVERSIONINFOEXW osvi = {};
    osvi.dwOSVersionInfoSize = sizeof(osvi);
    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;
}

VERSIONHELPERAPI
IsWindowsVistaSP2OrGreater()
{
    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 2);
}

You don’t need to use VersionHelpers.h as you could just do this kind of code yourself, but they are convenient if you are already using the VS 2013 compiler. For games, I have an article What’s in a version number? which uses VerifyVersionInfo to do the kind of reasonable checks one should for game deployment.

Note if you are using VS 2013 with the v120_xp platform toolset to target Windows XP, you’ll actually be using the Windows 7.1A SDK and #include <VersionHelpers.h> won’t work. You can of course use VerifyVersionInfo directly.

The other major use of GetVersionExW is diagnostic logs and telemetry. In this case, one option is to continue to use that API and make sure you have the right manifest entries in your application to ensure reasonably accurate results. See Manifest Madness for details on what you do here to achieve this. The main thing to keep in mind is that unless you routinely update your code, you will eventually stop getting fully accurate information in a future version of the OS.

Note that it is recommended you put the <compatibility> section in an embedded manifest whether or not you care about the results of GetVersionEx as general best practice. This allows the OS to automatically apply future appcompat fixes based on knowing how the app was originally tested.

For diagnostic logs, another approach that might be a bit more robust is to grab the version number out of a system DLL like kernel32.dll using GetFileVersionInfoW. This approach has a major caveat: Do not try parsing, doing comparisons, or making code assumptions based on the file version you obtain this way; just write it out somewhere. Otherwise you risk recreating the same bad OS version check problem that is better solved with VerifyVersionInfo. This option is not available to Windows Store apps, Windows phone apps, etc. but should work for Win32 desktop apps.

#include <Windows.h>
#include <cstdint>
#include <memory>

#pragma comment(lib, "version.lib" )

bool GetOSVersionString( WCHAR* version, size_t maxlen )
{
    WCHAR path[ _MAX_PATH ] = {};
    if ( !GetSystemDirectoryW( path, _MAX_PATH ) )
        return false;

    wcscat_s( path, L"kernel32.dll" );

    //
    // Based on example code from this article
    // http://support.microsoft.com/kb/167597
    //

    DWORD handle;
#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
    DWORD len = GetFileVersionInfoSizeExW( FILE_VER_GET_NEUTRAL, path, &handle );
#else
    DWORD len = GetFileVersionInfoSizeW( path, &handle );
#endif
    if ( !len )
        return false;

    std::unique_ptr<uint8_t> buff( new (std::nothrow) uint8_t[ len ] );
    if ( !buff )
        return false;

#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
    if ( !GetFileVersionInfoExW( FILE_VER_GET_NEUTRAL, path, 0, len, buff.get() ) )
#else
    if ( !GetFileVersionInfoW( path, 0, len, buff.get() ) )
#endif
        return false;

    VS_FIXEDFILEINFO *vInfo = nullptr;
    UINT infoSize;

    if ( !VerQueryValueW( buff.get(), L"", reinterpret_cast<LPVOID*>( &vInfo ), &infoSize ) )
        return false;

    if ( !infoSize )
        return false;

    swprintf_s( version, maxlen, L"%u.%u.%u.%u",
                HIWORD( vInfo->dwFileVersionMS ),
                LOWORD(vInfo->dwFileVersionMS),
                HIWORD(vInfo->dwFileVersionLS),
                LOWORD(vInfo->dwFileVersionLS) );
    
    return true;
}

If there is some other reason you are calling GetVersionExW, you probably shouldn’t be calling it. Checking for a component that might be missing shouldn’t be tied to a version check. For example, if your application requires Media Foundation, you should set a «You must be this high to ride this ride check» like the VersionHelpers.h IsWindowsVistaOrGreater for deployment, but at runtime you should use explicit linking via LoadLibrary or LoadLibaryEx to report an error or use a fallback if MFPLAT.DLL is not found.

Explicit linking is not an option for Windows Store apps. Windows 8.x solves this
particular problem by having a stub MFPLAT.DLL and MFStartUp will return E_NOTIMPL.
See «Who moved my [Windows Media] Cheese»?

Another example: if your application wants to use Direct3D 11.2 if it is available and otherwise uses DirectX 11.0, you’d use set a IsWindowsVistaSP2OrGreater minimum bar for deployment perhaps using the D3D11InstallHelper. Then at runtime, you’d create the DirectX 11.0 device and if it fails, you’d report an error. If you obtain a ID3D11Device, then you’d QueryInterface for a ID3D11Device2 which if it succeeds means you are using an OS that supports DirectX 11.2. See Anatomy of Direct3D 11 Create Device.

If this hypothetical Direct3D application supports Windows XP, you’d use a deployment bar of IsWindowsXPSP2OrGreater or IsWindowsXPSP3OrGreater, and then at run time use explicit linking to try to find the D3D11.DLL. If it wasn’t present, you’d fall back to using Direct3D 9—since we set the minimum bar, we know that DirectX 9.0c or later is always present.

They key point here is that in most cases, you should not use GetVersionEx.

Note that with Windows 10, VerifyVersionInfo and getting the file version stamp via GetFileVersionInfo for kernel32.lib are now subject to the same manifest based behavior as GetVersionEx (i.e. without the manifest GUID for Windows 10, it returns results as if the OS version were 6.2 rather than 10.0).

For universal Windows apps on Windows 10, you can a new WinRT API AnalyticsInfo to get a version stamp string for diagnostic logs and telemetry.

Better than disabling warnings, you can just disable the relevant code as it is intended to be disabled by adding to the file’s preprocessor defines.

Right-click on sqlite3.c, click Properties, Configuration Properties->C/C++->Preprocessor. Make sure you have «all configurations» selected for the configuration and platform dropdowns (unless you only have one platform, then just select the one that’s available) and edit the Preprocessor Definitions to be

SQLITE_WIN32_GETVERSIONEX=0;%(PreprocessorDefinitions)

This will skip the NTDDI_VERSION check since that symbol isn’t defined or is defined incorrectly when your compiler hits sqlite3.c.

There’s this comment in there, too, which may be interesting:

/*
** NOTE: All sub-platforms where the GetVersionEx[AW] functions are
**       deprecated are always assumed to be based on the NT kernel.
*/

The net effect of setting that #define is that your OS is always assumed to be based on Win NT, which it is since you’re Win 8.1 or Win 10 (or greater). ;)

So basically by disabling that warning you’re just making your code slower because it needs to do work to figure out if it’s on WinNT or not.

Better than disabling warnings, you can just disable the relevant code as it is intended to be disabled by adding to the file’s preprocessor defines.

Right-click on sqlite3.c, click Properties, Configuration Properties->C/C++->Preprocessor. Make sure you have «all configurations» selected for the configuration and platform dropdowns (unless you only have one platform, then just select the one that’s available) and edit the Preprocessor Definitions to be

SQLITE_WIN32_GETVERSIONEX=0;%(PreprocessorDefinitions)

This will skip the NTDDI_VERSION check since that symbol isn’t defined or is defined incorrectly when your compiler hits sqlite3.c.

There’s this comment in there, too, which may be interesting:

/*
** NOTE: All sub-platforms where the GetVersionEx[AW] functions are
**       deprecated are always assumed to be based on the NT kernel.
*/

The net effect of setting that #define is that your OS is always assumed to be based on Win NT, which it is since you’re Win 8.1 or Win 10 (or greater). ;)

So basically by disabling that warning you’re just making your code slower because it needs to do work to figure out if it’s on WinNT or not.

Introduction

Starting With Windows 8.1 you can no longer use a block of code that looks like this.

OSVERSIONINFOEX  versionInfo;
   versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
OSVERSIONINFO*  pVersionInfo = (POSVERSIONINFO)&versionInfo;   
if(::GetVersionEx(pVersionInfo))
{
  wcout<<_T("MajorVersion:")<<versionInfo.dwMajorVersion<<endl;
  wcout<<_T("MinorVersion:")<<versionInfo.dwMinorVersion<<endl;
}

Please Look Update Section for better ways to achieve this.

Background

I recently upgraded my development box to Windows8.1 from
Windows 8. I was trying to log the version of Windows to the product’s logfile
and suddenly I am faced with an issue where the Windows Version I retrieve from
GetVersionEx
API is actually associated with Windows 8. That is I expected Version 6.3 =
Windows8.1 but I was getting Version 6.2 = Windows8. It was impossible to
believe such an important API would be malfunctioning, so using Hyper-V I created
a Windows8.1 Image from scratch to make sure this was not an issue associated
with Windows Upgrade. But the issue persisted, so I upgraded to Visual Studio
2013, hoping that would solve the issue. The issue persisted and that’s
when I found the following Article
on msdn describing Microsoft’s deprecation of GetVersionEx API. Actually Visual 2013 Marks
GetVersionEx and GetVersion APIs as deprecated and throws an Error if you reference it. Moreover .Net
Framework’s API to retrieve OS version is also “deprecated” (returning inaccurate data). Let’s just say
this move is a big surprise by Microsoft. How is a Web Browser Supposed to Report
an accurate User Agent?
how is a product supposed to report accurate Telemetry Data without obtaining
Operating System version. In My particular case, how am I supposed to log the
version of OS in Diagnostic log files that customer would be shipping to me?
All these Questions led me to believe that Microsoft’s Version Helper API that
Ships with Windows
8.1 SDK are not sufficient. But they do provide a very good clue that VerifyVersionInfo
can indeed be used to fill the void.

I decided against doing dynamic LoadLibrary and GetProcAddress Technique to use
«undocumented» from Kernelbase.dll,Kernel32.dll, shell32.dll or shcore.dll and using internal APIs there. It also seemed
not the best idea to load the version of Windows from someplace in Registry. Another
approach would have been to load any key dll that resides in %systemroot% system32
folder and then use an API such as DllGetVersion
to retrieve Product Version from that DLL. but I did not like that idea either because a dll itself and can get hotfixed and potentially have different version (I have not seen this occur).

Using the code

Disclaimer: This is not Productionready code!

If you look close at VerifyVersionInfo and its sister API VerSetConditionMask
there is useful flag called VER_EQUAL.

We can verify the System is Running Windows 8.1 by using VER_EQUAL FLAG.

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 _tmain(int argc, _TCHAR* argv[])
{
    if (EqualsMajorVersion(6) && EqualsMinorVersion(3))
    {
        wcout << _T("System is Windows 8.1");
    }
    return 0;
}

That Works and in fact that’s very similar to the Mechanism used by VersionHelpers.h From Windows 8.1 SDK.

ERSIONHELPERAPI
IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
{
    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;
}

So You might have noticed Windows Versions have been historically predictable. By That I mean we had Windows 3.0, Windows 3.1, Windows NT, 95(4.0), Windows 2000 (5.0), Windows XP (5.1), …. Windows 7(6.1), ….. , Windows 8.1 (6.3). It’s not like previous Version was 100.0 and the next version is 213.0. so it fair to say with a small number of iterations and incrementing of a base known version we should able to get the version of windows that we are running on.

So Here are three More Helper Functions to Get ServicePack and ascertain whether this Windows is Workstation or Windows Server.

BOOL EqualsServicePack(WORD servicePackMajor)
{
    OSVERSIONINFOEX osVersionInfo;
    ::ZeroMemory(&osVersionInfo, sizeof(OSVERSIONINFOEX));
    osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
    osVersionInfo.wServicePackMajor = servicePackMajor;
    ULONGLONG maskCondition = ::VerSetConditionMask(0, VER_SERVICEPACKMAJOR, VER_EQUAL);
    return ::VerifyVersionInfo(&osVersionInfo, VER_SERVICEPACKMAJOR, maskCondition);
}

BOOL EqualsProductType(BYTE productType)
{
    OSVERSIONINFOEX osVersionInfo;
    ::ZeroMemory(&osVersionInfo, sizeof(OSVERSIONINFOEX));
    osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
    osVersionInfo.wProductType = productType;
    ULONGLONG maskCondition = ::VerSetConditionMask(0, VER_PRODUCT_TYPE, VER_EQUAL);
    return ::VerifyVersionInfo(&osVersionInfo, VER_PRODUCT_TYPE, maskCondition);
}

BYTE GetProductType()
{
    if (EqualsProductType(VER_NT_WORKSTATION))
    {
        return VER_NT_WORKSTATION;
    }
    else if (EqualsProductType(VER_NT_SERVER))
    {
        return VER_NT_SERVER;
    }
    else if (EqualsProductType(VER_NT_DOMAIN_CONTROLLER))
    {
        return VER_NT_DOMAIN_CONTROLLER;
    }
    return 0;}  

VerifyVersionInfo API was relased on Windows 2000 (Windows 5.0) so we can setup an array that contains known version of Windows back to Windows 200 and use this API to verify them.

struct WindowsNTOSInfo
{
    DWORD dwMajorVersion;
    DWORD dwMinorVersion;
    WORD wServicePackMajor;    
    };

struct WindowsNTOSInfoEx :WindowsNTOSInfo
{
    BYTE ProductType;
};

const WindowsNTOSInfo KnownVersionsOfWindows[] =
{
    { 6, 3, 0,   },    { 6, 2, 0,   },
    { 6, 1, 1,  },    { 6, 1, 0,  },
    { 5, 1, 3,  },    { 5, 1, 2,  },    { 5, 1, 1,  },    { 5, 1, 0,  },
    { 6, 0, 2,  },    { 6, 0, 1,  },    { 6, 0, 0,  },
    { 5, 2, 2,  },    { 5, 2, 1,  },    { 5, 2, 0,  },

    { 5, 1, 4,  },     { 5, 1, 3,  },     { 5, 1, 2,  },     { 5, 1, 2,  },     { 5, 1, 0,  }, };

const size_t n_KnownVersionofWindows = sizeof(KnownVersionsOfWindows) / sizeof(WindowsNTOSInfo);

So Here the Code that retrieves a known Version of Windows.

bool GetKnownWindowsVersion(WindowsNTOSInfoEx& osInfo)
{
    for (size_t i = 0; i < n_KnownVersionofWindows; i++)
    {
        if (EqualsMajorVersion(KnownVersionsOfWindows[i].dwMajorVersion))
        {
            if (EqualsMinorVersion(KnownVersionsOfWindows[i].dwMinorVersion))
            {
                if (EqualsServicePack(KnownVersionsOfWindows[i].wServicePackMajor))
                {
                    osInfo.dwMajorVersion = KnownVersionsOfWindows[i].dwMajorVersion;
                    osInfo.dwMinorVersion = KnownVersionsOfWindows[i].dwMinorVersion;
                    osInfo.wServicePackMajor = KnownVersionsOfWindows[i].wServicePackMajor;
                    osInfo.ProductType = GetProductType();
                    return true;
                }
            }
        }
    }
    return false;
}

But What about checking unkown version of Windows?

well for that we need to write a few loops and call our helper functions to Verify Major,Minor and Service Pack.

const DWORD MajorVersion_Start = 6;
const DWORD MinorVersion_Start = 3;
const WORD ServicePackVersion_Start = 1;

const DWORD MajorVersion_Max = 10;
const DWORD MinorVersion_Max = 5;
const WORD ServicePackVersion_Max = 4;

bool GetUnkownVersion(WindowsNTOSInfoEx& osInfo)
{
    DWORD minorVersionCounterSeed = MinorVersion_Start;
    DWORD servicePackCounterSeed = ServicePackVersion_Start;
        for (DWORD majorVersion = MajorVersion_Start; majorVersion <= MajorVersion_Max; majorVersion++)
    {
        if (EqualsMajorVersion(majorVersion))
        {
            for (DWORD minorVersion = minorVersionCounterSeed; 
                    minorVersion <= MinorVersion_Max; minorVersion++)
            {
                if (EqualsMinorVersion(minorVersion))
                {
                    osInfo.dwMajorVersion = majorVersion;
                    osInfo.dwMinorVersion = minorVersion;
                    osInfo.ProductType = GetProductType();
                    for (WORD servicePack = servicePackCounterSeed; 
                           servicePack <= ServicePackVersion_Max; servicePack++)
                    {
                        if (EqualsServicePack(servicePack))
                        {                            
                            osInfo.wServicePackMajor = servicePack;
                            break;
                        }
                    }
                    return true;
                }
                else
                {
                                                            servicePackCounterSeed = 0;
                }                
            }
        }
        else
        {
                        minorVersionCounterSeed = 0;
        }
    }
    return false;
}

So then let’s just call the before mentioned code with a function to glue them together.

bool GetWindowsVersion(WindowsNTOSInfoEx& osInfo)
{
    bool capturedWinVersion = GetKnownWindowsVersion(osInfo);
    if (!capturedWinVersion)
    {
        return GetUnkownVersion(osInfo);
    }
    return capturedWinVersion;
}



int _tmain(int argc, _TCHAR* argv[])
{
    WindowsNTOSInfoEx osInfo;
    ::ZeroMemory(&osInfo,sizeof(WindowsNTOSInfoEx));
    if (GetWindowsVersion(osInfo))
    {
        wcout << _T("MajorVersion:") << osInfo.dwMajorVersion << 
            _T(" VersionMinor:") << osInfo.dwMinorVersion << 
            _T(" ServicePackMajor:") << osInfo.wServicePackMajor << 
            _T(" ProductType:") << osInfo.ProductType << endl;
    }
    else
    {
        wcout << _T("Failed to Detect Windows Version") << endl;
    }
    return 0;
}

Note:I have only smoke tested this code on Windows 8.1 and Windows XP SP3.

Points of Interest

Performance: This code is actually quite slow!

It can take anywhere from 5-15 Milliseconds on a Physical System. It took upward of 30 Milliseconds on a Virtual Machine to Execute.
Since This API can be can called many times during an Application’s life cycle I have included a High Resolution Timer code to measure how lengthy of an operation this is. It appears Calling VerifyVersionInfo is much more expensive the first time. The cost of subsequent calls appear to be significantly less than the First Call.

BuildNumber: I have not seen people attach significant importance to the BuildNumber of Windows and with this approach retrieving BuildNumber can become really expensive. so I skipped over BuildNumber.

I will include another article to fetch Windows Version. But that approach uses COM and may not be desired by some.

 Update:

A User on this board has provided a better way to do this.

if you include an embeded manifest file as part of your .exe program.  GetVersionEx will return the right version on Windows8.1. Note that you can support other operating systems as well. but you must make sure Windows 8.1 is inclucded.

="1.0"="UTF-8"="yes"
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>
      
      <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
      
    </application>
  </compatibility>

  <assemblyIdentity type="win32"
                    name="SampleCode.GetWindowsVersionInfo"
                    version="1.0.0.0"
                    processorArchitecture="x86"
                    publicKeyToken="0000000000000000"
  />
</assembly>

The Great thing about this approach is that the performance  of GetVersionEx is fantastic. 

But the issue still remains that your binaries will always missbehave on Newer Version of Windows (since you don’t know newever Version of Windows Guid ahead of time).

Also One More issue is that you can not create an application that runs in Compatiblity Mode with previous Windows OS.

you will have to get rid of Visual Studio Deprecation Errors by disabling by doing something like this.

#pragma warning (disable : 4996)
versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
POSVERSIONINFO pVersionInfo = (POSVERSIONINFO)&versionInfo;
if (::GetVersionEx(pVersionInfo))
{
    if (6 == versionInfo.dwMajorVersion && 3 == versionInfo.dwMinorVersion)
    {
        wcout << _T("Windows 8.1 Detected") << endl;
    }
    else if (6 == versionInfo.dwMajorVersion && 2 == versionInfo.dwMinorVersion)
    {
        wcout << _T("Windows 8.0 Detected") << endl;
    }
}
#pragma warning (default : 4996)

I have also discovered another API that still returns Windows Version without any compatability Manifests required.  But it takes a 2-3 miliseconds to execute so it is significantly slower than GetVersionEx API.

bool GetWindowsVersion(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;
		::NetApiBufferFree(pinfoRawData);
		return true;
	}
	return false;
}
int _tmain(int argc, _TCHAR* argv[])
{	
	DWORD major = 0;
	DWORD minor = 0;
	if (GetWindowsVersion(major, minor))
	{
		wcout << _T("Major:") << major << _T("Minor:") << minor << endl;
	}	
	return 0;
}

I have been doing some sort of Software Development since 1998. I started with C Programming but quickly upgraded to C++. I am proficient in Windows UI, Windows Server/Service, COM, C# and WinForms, C# and Asp.net. I can also claim some know-how in VB.NET and java. Every once in a while I hone in my scripting skills by doing more JQuery and Powershell but I quickly forget it all. I also have a working knowledge of CSS and HTML as well.
check out my Blog

Лучше, чем отключать предупреждения, вы можете просто отключить соответствующий код, поскольку он предназначен для отключения путем добавления в файл препроцессора.

Щелкните правой кнопкой мыши по sqlite3.c, выберите Свойства, Свойства конфигурации → C/С++ → Препроцессор. Убедитесь, что вы выбрали «все конфигурации» для выпадающих списков конфигурации и платформы (если только у вас нет только одной платформы, а затем выберите только ту, которая доступна) и отредактируйте определения препроцессора как

SQLITE_WIN32_GETVERSIONEX=0;%(PreprocessorDefinitions)

Это пропустит проверку NTDDI_VERSION, так как этот символ не определен или определен неверно, когда ваш компилятор попадает на sqlite3.c.

Там тоже есть этот комментарий, который может быть интересным:

/*
** NOTE: All sub-platforms where the GetVersionEx[AW] functions are
**       deprecated are always assumed to be based on the NT kernel.
*/

Сетевой эффект установки #define заключается в том, что ваша ОС всегда считается основанной на Win NT, которая есть, так как вы — Win 8.1 или Win 10 (или больше).;)

Итак, в основном, отключив это предупреждение, вы просто делаете свой код медленнее, потому что ему нужно выполнить работу, чтобы выяснить, есть ли это в WinNT или нет.

The basic question is «why are you calling GetVersionExW in the first place?» The answer to that question determines what you should do instead.

The deprecation warning is there to give developers a heads-up about the appcompat behavior change that started in Windows 8.1. See Windows and Windows Server compatibility cookbook: Windows 8, Windows 8.1, and Windows Server 2012. In short, that function doesn’t return what you think it returns by default.

Historically, badly written OS version checks are the primary source of appcompat bugs for Windows OS upgrades. There’ve been a number of different approaches to trying to mitigate this problem (the AppVerifier version lie, the VerifyVersionInfo API, etc.), and this is the most aggressive to date.

The VersionHelpers.h mentioned in the comments are in the Windows 8.1 SDK that comes with Visual Studio 2013. They are not a new API; they are just utility code that makes use of the VerifyVersionInfo API introduced back in Windows 2000. These functions are for doing «You must be this high to ride this ride» style checks which are the class of version checks that are most often badly written. The code is pretty simple. For example, the IsWindowsVistaSP2OrGreater test is:

VERSIONHELPERAPI
IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
{
    OSVERSIONINFOEXW osvi = {};
    osvi.dwOSVersionInfoSize = sizeof(osvi);
    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;
}

VERSIONHELPERAPI
IsWindowsVistaSP2OrGreater()
{
    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 2);
}

You don’t need to use VersionHelpers.h as you could just do this kind of code yourself, but they are convenient if you are already using the VS 2013 compiler. For games, I have an article What’s in a version number? which uses VerifyVersionInfo to do the kind of reasonable checks one should for game deployment.

Note if you are using VS 2013 with the v120_xp platform toolset to target Windows XP, you’ll actually be using the Windows 7.1A SDK and #include <VersionHelpers.h> won’t work. You can of course use VerifyVersionInfo directly.

The other major use of GetVersionExW is diagnostic logs and telemetry. In this case, one option is to continue to use that API and make sure you have the right manifest entries in your application to ensure reasonably accurate results. See Manifest Madness for details on what you do here to achieve this. The main thing to keep in mind is that unless you routinely update your code, you will eventually stop getting fully accurate information in a future version of the OS.

Note that it is recommended you put the <compatibility> section in an embedded manifest whether or not you care about the results of GetVersionEx as general best practice. This allows the OS to automatically apply future appcompat fixes based on knowing how the app was originally tested.

For diagnostic logs, another approach that might be a bit more robust is to grab the version number out of a system DLL like kernel32.dll using GetFileVersionInfoW. This approach has a major caveat: Do not try parsing, doing comparisons, or making code assumptions based on the file version you obtain this way; just write it out somewhere. Otherwise you risk recreating the same bad OS version check problem that is better solved with VerifyVersionInfo. This option is not available to Windows Store apps, Windows phone apps, etc. but should work for Win32 desktop apps.

#include <Windows.h>
#include <cstdint>
#include <memory>

#pragma comment(lib, "version.lib" )

bool GetOSVersionString( WCHAR* version, size_t maxlen )
{
    WCHAR path[ _MAX_PATH ] = {};
    if ( !GetSystemDirectoryW( path, _MAX_PATH ) )
        return false;

    wcscat_s( path, L"kernel32.dll" );

    //
    // Based on example code from this article
    // http://support.microsoft.com/kb/167597
    //

    DWORD handle;
#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
    DWORD len = GetFileVersionInfoSizeExW( FILE_VER_GET_NEUTRAL, path, &handle );
#else
    DWORD len = GetFileVersionInfoSizeW( path, &handle );
#endif
    if ( !len )
        return false;

    std::unique_ptr<uint8_t> buff( new (std::nothrow) uint8_t[ len ] );
    if ( !buff )
        return false;

#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
    if ( !GetFileVersionInfoExW( FILE_VER_GET_NEUTRAL, path, 0, len, buff.get() ) )
#else
    if ( !GetFileVersionInfoW( path, 0, len, buff.get() ) )
#endif
        return false;

    VS_FIXEDFILEINFO *vInfo = nullptr;
    UINT infoSize;

    if ( !VerQueryValueW( buff.get(), L"", reinterpret_cast<LPVOID*>( &vInfo ), &infoSize ) )
        return false;

    if ( !infoSize )
        return false;

    swprintf_s( version, maxlen, L"%u.%u.%u.%u",
                HIWORD( vInfo->dwFileVersionMS ),
                LOWORD(vInfo->dwFileVersionMS),
                HIWORD(vInfo->dwFileVersionLS),
                LOWORD(vInfo->dwFileVersionLS) );
    
    return true;
}

If there is some other reason you are calling GetVersionExW, you probably shouldn’t be calling it. Checking for a component that might be missing shouldn’t be tied to a version check. For example, if your application requires Media Foundation, you should set a «You must be this high to ride this ride check» like the VersionHelpers.h IsWindowsVistaOrGreater for deployment, but at runtime you should use explicit linking via LoadLibrary or LoadLibaryEx to report an error or use a fallback if MFPLAT.DLL is not found.

Explicit linking is not an option for Windows Store apps. Windows 8.x solves this
particular problem by having a stub MFPLAT.DLL and MFStartUp will return E_NOTIMPL.
See «Who moved my [Windows Media] Cheese»?

Another example: if your application wants to use Direct3D 11.2 if it is available and otherwise uses DirectX 11.0, you’d use set a IsWindowsVistaSP2OrGreater minimum bar for deployment perhaps using the D3D11InstallHelper. Then at runtime, you’d create the DirectX 11.0 device and if it fails, you’d report an error. If you obtain a ID3D11Device, then you’d QueryInterface for a ID3D11Device2 which if it succeeds means you are using an OS that supports DirectX 11.2. See Anatomy of Direct3D 11 Create Device.

If this hypothetical Direct3D application supports Windows XP, you’d use a deployment bar of IsWindowsXPSP2OrGreater or IsWindowsXPSP3OrGreater, and then at run time use explicit linking to try to find the D3D11.DLL. If it wasn’t present, you’d fall back to using Direct3D 9—since we set the minimum bar, we know that DirectX 9.0c or later is always present.

They key point here is that in most cases, you should not use GetVersionEx.

Note that with Windows 10, VerifyVersionInfo and getting the file version stamp via GetFileVersionInfo for kernel32.lib are now subject to the same manifest based behavior as GetVersionEx (i.e. without the manifest GUID for Windows 10, it returns results as if the OS version were 6.2 rather than 10.0).

For universal Windows apps on Windows 10, you can a new WinRT API AnalyticsInfo to get a version stamp string for diagnostic logs and telemetry.

The basic question is «why are you calling GetVersionExW in the first place?» The answer to that question determines what you should do instead.

The deprecation warning is there to give developers a heads-up about the appcompat behavior change that started in Windows 8.1. See Windows and Windows Server compatibility cookbook: Windows 8, Windows 8.1, and Windows Server 2012. In short, that function doesn’t return what you think it returns by default.

Historically, badly written OS version checks are the primary source of appcompat bugs for Windows OS upgrades. There’ve been a number of different approaches to trying to mitigate this problem (the AppVerifier version lie, the VerifyVersionInfo API, etc.), and this is the most aggressive to date.

The VersionHelpers.h mentioned in the comments are in the Windows 8.1 SDK that comes with Visual Studio 2013. They are not a new API; they are just utility code that makes use of the VerifyVersionInfo API introduced back in Windows 2000. These functions are for doing «You must be this high to ride this ride» style checks which are the class of version checks that are most often badly written. The code is pretty simple. For example, the IsWindowsVistaSP2OrGreater test is:

VERSIONHELPERAPI
IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
{
    OSVERSIONINFOEXW osvi = {};
    osvi.dwOSVersionInfoSize = sizeof(osvi);
    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;
}

VERSIONHELPERAPI
IsWindowsVistaSP2OrGreater()
{
    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 2);
}

You don’t need to use VersionHelpers.h as you could just do this kind of code yourself, but they are convenient if you are already using the VS 2013 compiler. For games, I have an article What’s in a version number? which uses VerifyVersionInfo to do the kind of reasonable checks one should for game deployment.

Note if you are using VS 2013 with the v120_xp platform toolset to target Windows XP, you’ll actually be using the Windows 7.1A SDK and #include <VersionHelpers.h> won’t work. You can of course use VerifyVersionInfo directly.

The other major use of GetVersionExW is diagnostic logs and telemetry. In this case, one option is to continue to use that API and make sure you have the right manifest entries in your application to ensure reasonably accurate results. See Manifest Madness for details on what you do here to achieve this. The main thing to keep in mind is that unless you routinely update your code, you will eventually stop getting fully accurate information in a future version of the OS.

Note that it is recommended you put the <compatibility> section in an embedded manifest whether or not you care about the results of GetVersionEx as general best practice. This allows the OS to automatically apply future appcompat fixes based on knowing how the app was originally tested.

For diagnostic logs, another approach that might be a bit more robust is to grab the version number out of a system DLL like kernel32.dll using GetFileVersionInfoW. This approach has a major caveat: Do not try parsing, doing comparisons, or making code assumptions based on the file version you obtain this way; just write it out somewhere. Otherwise you risk recreating the same bad OS version check problem that is better solved with VerifyVersionInfo. This option is not available to Windows Store apps, Windows phone apps, etc. but should work for Win32 desktop apps.

#include <Windows.h>
#include <cstdint>
#include <memory>

#pragma comment(lib, "version.lib" )

bool GetOSVersionString( WCHAR* version, size_t maxlen )
{
    WCHAR path[ _MAX_PATH ] = {};
    if ( !GetSystemDirectoryW( path, _MAX_PATH ) )
        return false;

    wcscat_s( path, L"kernel32.dll" );

    //
    // Based on example code from this article
    // http://support.microsoft.com/kb/167597
    //

    DWORD handle;
#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
    DWORD len = GetFileVersionInfoSizeExW( FILE_VER_GET_NEUTRAL, path, &handle );
#else
    DWORD len = GetFileVersionInfoSizeW( path, &handle );
#endif
    if ( !len )
        return false;

    std::unique_ptr<uint8_t> buff( new (std::nothrow) uint8_t[ len ] );
    if ( !buff )
        return false;

#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
    if ( !GetFileVersionInfoExW( FILE_VER_GET_NEUTRAL, path, 0, len, buff.get() ) )
#else
    if ( !GetFileVersionInfoW( path, 0, len, buff.get() ) )
#endif
        return false;

    VS_FIXEDFILEINFO *vInfo = nullptr;
    UINT infoSize;

    if ( !VerQueryValueW( buff.get(), L"", reinterpret_cast<LPVOID*>( &vInfo ), &infoSize ) )
        return false;

    if ( !infoSize )
        return false;

    swprintf_s( version, maxlen, L"%u.%u.%u.%u",
                HIWORD( vInfo->dwFileVersionMS ),
                LOWORD(vInfo->dwFileVersionMS),
                HIWORD(vInfo->dwFileVersionLS),
                LOWORD(vInfo->dwFileVersionLS) );
    
    return true;
}

If there is some other reason you are calling GetVersionExW, you probably shouldn’t be calling it. Checking for a component that might be missing shouldn’t be tied to a version check. For example, if your application requires Media Foundation, you should set a «You must be this high to ride this ride check» like the VersionHelpers.h IsWindowsVistaOrGreater for deployment, but at runtime you should use explicit linking via LoadLibrary or LoadLibaryEx to report an error or use a fallback if MFPLAT.DLL is not found.

Explicit linking is not an option for Windows Store apps. Windows 8.x solves this
particular problem by having a stub MFPLAT.DLL and MFStartUp will return E_NOTIMPL.
See «Who moved my [Windows Media] Cheese»?

Another example: if your application wants to use Direct3D 11.2 if it is available and otherwise uses DirectX 11.0, you’d use set a IsWindowsVistaSP2OrGreater minimum bar for deployment perhaps using the D3D11InstallHelper. Then at runtime, you’d create the DirectX 11.0 device and if it fails, you’d report an error. If you obtain a ID3D11Device, then you’d QueryInterface for a ID3D11Device2 which if it succeeds means you are using an OS that supports DirectX 11.2. See Anatomy of Direct3D 11 Create Device.

If this hypothetical Direct3D application supports Windows XP, you’d use a deployment bar of IsWindowsXPSP2OrGreater or IsWindowsXPSP3OrGreater, and then at run time use explicit linking to try to find the D3D11.DLL. If it wasn’t present, you’d fall back to using Direct3D 9—since we set the minimum bar, we know that DirectX 9.0c or later is always present.

They key point here is that in most cases, you should not use GetVersionEx.

Note that with Windows 10, VerifyVersionInfo and getting the file version stamp via GetFileVersionInfo for kernel32.lib are now subject to the same manifest based behavior as GetVersionEx (i.e. without the manifest GUID for Windows 10, it returns results as if the OS version were 6.2 rather than 10.0).

For universal Windows apps on Windows 10, you can a new WinRT API AnalyticsInfo to get a version stamp string for diagnostic logs and telemetry.

  • Ошибка c4996 c getch
  • Ошибка c4716 должна возвращать значение
  • Ошибка c4703 используется потенциально неинициализированная локальная переменная указатель
  • Ошибка c4700 использована неинициализированная локальная переменная
  • Ошибка c4600 kyocera 6530