我的目标是在我的代码中检测Windows 10,它必须跨平台工作,并且跨不同版本的Windows (至少7& up)。Windows提供了IsWindows10OrGreater()
来解决这个问题,但是它还有另一个问题,这个函数在以前的windows版本中不存在。
您会发现无数的博客和问题,以及明显的疯狂,像这样的函数,getversion和其他函数返回一些不同的版本,而不是正确的版本。
例如,在我的机器上-- IsWindows10OrGreater()
不编译(我需要安装Win10 SDK)的方法,IsWindowsVersionOrGreater()
将6
报告为主要版本。
那么,有一个理智的多版本的方法,我可以解决这个问题?
发布于 2016-04-11 09:46:21
检索真正OS版本最直接的方法是调用RtlGetVersion。这是GetVersionEx
和VerifyVersionInfo
所称的,但没有使用兼容性shims。
您可以使用DDK (通过#包括和从内核模式针对NtosKrnl.lib进行链接,或者从用户模式使用ntdll.lib ),或者使用运行时动态链接,如下所示:
typedef LONG NTSTATUS, *PNTSTATUS;
#define STATUS_SUCCESS (0x00000000)
typedef NTSTATUS (WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
RTL_OSVERSIONINFOW GetRealOSVersion() {
HMODULE hMod = ::GetModuleHandleW(L"ntdll.dll");
if (hMod) {
RtlGetVersionPtr fxPtr = (RtlGetVersionPtr)::GetProcAddress(hMod, "RtlGetVersion");
if (fxPtr != nullptr) {
RTL_OSVERSIONINFOW rovi = { 0 };
rovi.dwOSVersionInfoSize = sizeof(rovi);
if ( STATUS_SUCCESS == fxPtr(&rovi) ) {
return rovi;
}
}
}
RTL_OSVERSIONINFOW rovi = { 0 };
return rovi;
}
如果您需要更多信息,您可以传递一个OSVERSIONINFOEXW结构来代替OSVERSIONINFOW结构(正确地分配dwOSVersionInfoSize成员)。
这将返回Windows 10上的预期结果,即使没有附加清单。
顺便说一句,人们普遍认为,根据可用的特性而不是OS版本提供不同的实现是一种更好的解决方案。
发布于 2016-04-11 08:27:16
IsWindows10OrGreater()
来自VersionHelpers.h
查看MSDN上的版本帮助函数的笔记
文件VersionHelpers.h
随Windows10SDK一起提供,但它在以前的版本中也能工作。只需将其复制到您的开发环境即可。
它只是一个只定义了头的小库,它使用VerSetConditionMask
和VerifyVersionInfoW
函数,这两个函数都可以在WinAPI中从Windows2000中获得。
Upd如果不能在源代码中包含清单文件,可以使用简单的hack:只需获得任何系统dll的版本,例如,使用GetFileVersionInfo
函数的kernel32.dll
。
发布于 2016-04-11 19:17:10
您可以从注册表读取真实的版本号,然后从注册表中推断Windows版本。您的应用程序不需要有此工作的清单:在我的计算机上,它正确地检测到操作系统的版本号为10586。例如:
#include <Windows.h>
#include <sstream>
struct HKeyHolder
{
private:
HKEY m_Key;
public:
HKeyHolder() :
m_Key(nullptr)
{
}
HKeyHolder(const HKeyHolder&) = delete;
HKeyHolder& operator=(const HKeyHolder&) = delete;
~HKeyHolder()
{
if (m_Key != nullptr)
RegCloseKey(m_Key);
}
operator HKEY() const
{
return m_Key;
}
HKEY* operator&()
{
return &m_Key;
}
};
bool IsRunningOnWindows10()
{
HKeyHolder currentVersion;
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, LR"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)", 0, KEY_QUERY_VALUE, ¤tVersion) != ERROR_SUCCESS)
return false;
DWORD valueType;
BYTE buffer[256];
DWORD bufferSize = 256;
if (RegQueryValueExW(currentVersion, L"CurrentBuild", nullptr, &valueType, buffer, &bufferSize) != ERROR_SUCCESS)
return false;
if (valueType != REG_SZ)
return false;
int version;
std::wistringstream versionStream(reinterpret_cast<wchar_t*>(buffer));
versionStream >> version;
return version > 9800;
}
https://stackoverflow.com/questions/36543301
复制相似问题