Visual Studio是否在Windows 7上将WINVER/\u WIN32\u WINNT设置为Windows 8?
我正在使用Visual Studio 2012在Windows 7 x64上执行一些测试。微软的工具链似乎正在将Visual Studio是否在Windows 7上将WINVER/\u WIN32\u WINNT设置为Windows 8?,windows,visual-studio,visual-studio-2012,windows-7,platform,Windows,Visual Studio,Visual Studio 2012,Windows 7,Platform,我正在使用Visual Studio 2012在Windows 7 x64上执行一些测试。微软的工具链似乎正在将\u WIN32\u WINNT设置为0x602(\u WIN32\u WINNT\u WIN8)。运行我们的测试程序会导致在动态链接库KERNEL32.dll中找不到过程入口点GetOverlappedResultEx: 我有两个问题。首先,出于病态的好奇,为什么Microsoft将\u WIN32\u WINNT设置为对执行环境无效的值?我能理解用户是否想这样做,但微软不能,因为
\u WIN32\u WINNT
设置为0x602
(\u WIN32\u WINNT\u WIN8
)。运行我们的测试程序会导致在动态链接库KERNEL32.dll中找不到过程入口点GetOverlappedResultEx:
我有两个问题。首先,出于病态的好奇,为什么Microsoft将\u WIN32\u WINNT
设置为对执行环境无效的值?我能理解用户是否想这样做,但微软不能,因为它会破坏东西(q.v.)
其次,我们如何将WINVER
或\u WIN32\u WINNT
设置为符号“This Platform”?在本例中,“此平台”是Windows 7。当我在WindowsVista上测试时,它将是一个不同的平台。当我在Windows8上测试时,它将是另一个平台。当我在ARM开发者提示下测试Windows Phone和Windows应用商店时,它将是另一个平台
这个问题很容易重复。以下是步骤。我想任何拥有良好测试环境的人都已经具备了前八个步骤
main
真的对这个问题至关重要吗?无论文件中有什么内容,都将设置错误的WINVER
和\u WIN32\u WINNT
我知道错误的根源。我们的代码最近进行了更改,以更好地支持。变化如下:
#if defined(CRYPTOPP_WIN32_AVAILABLE)
# if ((WINVER >= 0x0602 /*_WIN32_WINNT_WIN8*/) || (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/))
# include <synchapi.h>
# include <ioapiset.h>
# define USE_WINDOWS8_API
# endif
#endif
...
#if defined(USE_WINDOWS8_API)
BOOL result = GetOverlappedResultEx(GetHandle(), &m_overlapped, &m_lastResult, INFINITE, FALSE);
#else
BOOL result = GetOverlappedResult(GetHandle(), &m_overlapped, &m_lastResult, FALSE);
#endif
这里有一个相关的堆栈溢出问题:,但它没有讨论如何将其设置为“this platform” 以下是微软关于这个主题的文档:和。讽刺的是,他们并没有真正讨论Windows 10、Windows Phone 10、Windows Store 10或Windows Universal Platform的问题
另外,GCC有一个类似的
-march=native
,基本上提供“此平台”。如果您没有明确提供目标平台版本,Windows SDK将选择一个默认版本(有关详细信息,请参阅SDK的sdkddkver.h文件)
例如,Windows 8.0 SDK sdkdver.h文件包含以下代码段:
#if !defined(_WIN32_WINNT) && !defined(_CHICAGO_)
#define _WIN32_WINNT 0x0602
#endif
如果不希望使用默认选择,则需要通过适当定义\u WIN32\u WINNT
和/或相关宏来配置目标平台版本。您可以使用项目设置或makefile中的/D
编译器选项执行此操作,也可以在源文件或包含SDK头之前包含在所有内容中的公共头中定义它
类似于
/D\u WIN32\u WINNT=0x0601的内容可能适合您(0x0601对应于Win7)。如果您没有明确提供目标平台版本,则Windows SDK将选择默认版本(有关详细信息,请参阅SDK的sdkddkver.h文件)
例如,Windows 8.0 SDK sdkdver.h文件包含以下代码段:
#if !defined(_WIN32_WINNT) && !defined(_CHICAGO_)
#define _WIN32_WINNT 0x0602
#endif
如果不希望使用默认选择,则需要通过适当定义\u WIN32\u WINNT
和/或相关宏来配置目标平台版本。您可以使用项目设置或makefile中的/D
编译器选项执行此操作,也可以在源文件或包含SDK头之前包含在所有内容中的公共头中定义它
类似于/D\u WIN32\u WINNT=0x0601
的内容可能适合您(0x0601对应于Win7)。这里的根本问题是您使用\u WIN32\u WINNT
来确定要采用的代码路径,而不是实际设置它。这适用于Windows应用商店/Phone/UWP构建(如Chuck的回答中所述),但不适用于桌面构建
对于桌面构建,正确的解决方案是要么使用最低公分母,要么在运行时选择代码路径。否则,您需要为不同版本的Windows构建不同的桌面可执行文件
在这种特殊情况下,由于您没有使用由GetOverlappedResultEx
提供的附加功能,因此对于桌面构建,坚持使用GetOverlappedResult
可能更明智。您可以使用中列出的宏定义来确定是否为桌面生成
对于桌面应用程序,GetOverlappedResult
API似乎并不受欢迎,因此,如果您对UWP/Store/Phone构建使用GetOverlappedResultEx
,则不应得到脏的编译。(?)
据我所知,没有真正优雅的方法使生成输出依赖于运行生成工具的Windows版本-您会注意到,任何一个或的预定义宏都不允许您确定操作系统版本
但是,如果这确实是一种罕见的情况,那么您可以通过使用预构建事件或自定义构建步骤来运行一个程序,该程序检查操作系统版本并构建一个头文件,您的代码可以包含该头文件。如果其他Windows开发人员将构建您的库,我不建议这样做,因为他们不会期望这种行为
#include <WinSDKVer.h>
#define _WIN32_WINNT 0x0600 // Windows Vista SP2 or later
#include <SDKDDKVer.h>
#include <WinSDKVer.h>
#define _WIN32_WINNT 0x0601 // Windows 7 or later
#include <SDKDDKVer.h>
HANDLE hEvent = CreateEventEx( nullptr, nullptr,
CREATE_EVENT_MANUAL_RESET, EVENT_MODIFY_STATE | SYNCHRONIZE );
...
// Read and verify header
OVERLAPPED request = {};
request.hEvent = hEvent;
bool wait = false;
if( !ReadFile( hFile, ..., &request ) )
{
DWORD error = GetLastError();
if ( error != ERROR_IO_PENDING )
return HRESULT_FROM_WIN32( error );
wait = true;
}
DWORD bytes;
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
BOOL result = GetOverlappedResultEx( hFile, &request, &bytes, INFINITE, FALSE );
#else
if ( wait )
(void)WaitForSingleObject( hEvent, INFINITE );
BOOL result = GetOverlappedResult( hFile, &request, &bytes, FALSE );
#endif