Ошибка c4996 getversionexa объявлен 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.

Senum

3 / 2 / 1

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

Сообщений: 92

1

10.04.2015, 01:24. Показов 15475. Ответов 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



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.

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Pick a username
Email Address
Password

By clicking “Sign up for GitHub”, you agree to our terms of service and
privacy statement. We’ll occasionally send you account related emails.

Already on GitHub?
Sign in
to your account

I need to build a Visual Studio 2012 project unchanged using Visual Studio 2015 and am finding that Visual Studio 2015 seems to have changed rules and now a Windows API function is deemed deprecated. I have found I can change compile options via the command line using SET CL but this command line options is being overridden.

I need to find a way to force the command line option to be used.

Here is the source code:

/*
1>e:\code\compile_cmd_line\main.cpp(15): warning C4996: 'GetVersionExA': was declared deprecated
1>  c:\program files (x86)\windows kits\8.1\include\um\sysinfoapi.h(433): note: see declaration of 'GetVersionExA'
*/

// with below line uncommented, builds in Visual Studio 2015 IDE ok
// #pragma warning(disable: 4996)  // error C4996: 'GetVersionExA': was declared deprecated

#include <windows.h>

int main() {
    OSVERSIONINFOA vi = { };
    BOOL ret = GetVersionExA(&vi);
}

The compiler options in the project file are:

/GS /GL /analyze- /W3 /Gy /Zc:wchar_t /Zi /Gm- /O2 /sdl /Fd"Release\vc140.pdb" /Zc:inline /fp:precise /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /Gd /Oy- /Oi /MD /Fa"Release\" /EHsc /nologo /Fo"Release\" /Fp"Release\compile_cmd_line.pch"

The problem settings are SDL checks /sdl and Security check /GS

Here is how I try to compile using VS2015:

E:\code\compile_cmd_line>set CL=/sdl- /GS-

E:\code\compile_cmd_line>devenv /useenv /build "Release|x86" compile_cmd_line.sln

Microsoft Visual Studio 2015 Version 14.0.25420.1.
Copyright (C) Microsoft Corp. All rights reserved.

The license for Visual Studio expires in 20 days.
1>------ Build started: Project: compile_cmd_line, Configuration: Release Win32
------
1>cl : Command line warning D9025: overriding '/sdl-' with '/GS-'
1>cl : Command line warning D9025: overriding '/GS-' with '/sdl'
1>  main.cpp
1>main.cpp(20): error C4996: 'GetVersionExA': was declared deprecated
1>  C:\Program Files (x86)\Windows Kits\8.1\include\um\sysinfoapi.h(433): note:
see declaration of 'GetVersionExA'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

E:\code\compile_cmd_line>

The problem lines:

1>cl : Command line warning D9025: overriding '/sdl-' with '/GS-'
1>cl : Command line warning D9025: overriding '/GS-' with '/sdl'

For completeness, I have a setup script to setup the env vars for the MS build tools:

call "%VS140COMNTOOLS%vsvars32.bat"

set INCLUDE=C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt;%INCLUDE%
set LIB=C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x86;%LIB%

Is there a better way to do this?

Can I force the override using SET CL?

Понравилась статья? Поделить с друзьями:
  • Ошибка c46 suzuki gsx r 750
  • Ошибка c46 gsxr 600
  • Ошибка c4201 kyocera 2540
  • Ошибка c41568 форд мондео
  • Ошибка c40168 ford