问题
How can I accurately detect the current Windows operating system on a native (C/C++) project in Visual Studio 2012.3 for operating systems past Windows 8.1?
I've looked in to VersionHelperAPI under MS recommendation, but this solution only applies to VS2013.
Previously we used GetVersionEx(), but I'd like a solution that is more stable and future-proof in a way. It seems like MS is planning to deprecate this in the future.
回答1:
The important thing is to include compatibility flags in manifest file:
Targeting your application for Windows
Here are the relevant parts:
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!-- Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
</application>
</compatibility>
Without the above tags, when running on Windows 10, GetVersionEx and VerifyVersionInfoW will see Windows 8
Microsoft insists you should use VerifyVersionInfoW, not GetVersionEx
There are some helper functions which are not available in earlier VS version. But you may find them on your computer in this directory:
"C:\Program Files (x86)\Windows Kits\8.1\Include\um\VersionHelpers.h"
Here is what they are (I modified them slightly because they were too long, and tested it for Windows 10, you should double-check for older Windows versions)
#define _WIN32_WINNT_NT4 0x0400
#define _WIN32_WINNT_WIN2K 0x0500
#define _WIN32_WINNT_WINXP 0x0501
#define _WIN32_WINNT_WS03 0x0502
#define _WIN32_WINNT_WIN6 0x0600
#define _WIN32_WINNT_VISTA 0x0600
#define _WIN32_WINNT_WS08 0x0600
#define _WIN32_WINNT_LONGHORN 0x0600
#define _WIN32_WINNT_WIN7 0x0601
#define _WIN32_WINNT_WIN8 0x0602
#define _WIN32_WINNT_WINBLUE 0x0603
#define _WIN32_WINNT_WIN10 0x0A00
BOOL IsWinVersionOrGreater(DWORD id, WORD wServicePackMajor)
{
WORD wMajorVersion = HIBYTE(id);
WORD wMinorVersion = LOBYTE(id);
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;
}
BOOL IsWindowsXPOrGreater() { return IsWinVersionOrGreater(_WIN32_WINNT_WINXP, 0);}
BOOL IsWindowsXPSP1OrGreater() { return IsWinVersionOrGreater(_WIN32_WINNT_WINXP, 1);}
BOOL IsWindowsXPSP2OrGreater() { return IsWinVersionOrGreater(_WIN32_WINNT_WINXP, 2);}
BOOL IsWindowsXPSP3OrGreater() { return IsWinVersionOrGreater(_WIN32_WINNT_WINXP, 3);}
BOOL IsWindowsVistaOrGreater() { return IsWinVersionOrGreater(_WIN32_WINNT_VISTA, 0);}
BOOL IsWindowsVistaSP1OrGreater(){ return IsWinVersionOrGreater(_WIN32_WINNT_VISTA, 1);}
BOOL IsWindowsVistaSP2OrGreater(){ return IsWinVersionOrGreater(_WIN32_WINNT_VISTA, 2);}
BOOL IsWindows7OrGreater() { return IsWinVersionOrGreater(_WIN32_WINNT_WIN7, 0);}
BOOL IsWindows7SP1OrGreater() { return IsWinVersionOrGreater(_WIN32_WINNT_WIN7, 1);}
BOOL IsWindows8OrGreater() { return IsWinVersionOrGreater(_WIN32_WINNT_WIN8, 0);}
BOOL IsWindows8Point1OrGreater() { return IsWinVersionOrGreater(_WIN32_WINNT_WINBLUE, 0); }
BOOL IsWindows10OrGreater() { return IsWinVersionOrGreater(_WIN32_WINNT_WIN10, 0); }
BOOL IsWindowsServer()
{
OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0,{ 0 }, 0, 0, 0, VER_NT_WORKSTATION };
DWORDLONG const dwlConditionMask = VerSetConditionMask(0, VER_PRODUCT_TYPE, VER_EQUAL);
return !VerifyVersionInfoW(&osvi, VER_PRODUCT_TYPE, dwlConditionMask);
}
来源:https://stackoverflow.com/questions/34235151/get-windows-version