问题一:Windows SDK 8.1版本中的VersionHelper.h文件当中没有IsWindows10ORGreater,所以当你用IsWindows8Point1ORGreater判断出版本信息是Windows8.1以上的版本后,你就无法区分它到底是Win8.1还是Win10.
问题二:使用GetVersionEx这个API配合结构体OSVERSIONINFOEX这个方法获取版本信息,那么Win8以上的系统不论是Win8.1还是Win10都会被判定为主版本号为6,次版本号为2(即Win8的版本号)。
那么如何区分Win8.1和Win10?
使用如下未文档化API:
RtlGetNtVersionNumbers。
1 string GetNtVersionNumbers() 2 { 3 HMODULE hModNtdll = NULL; 4 DWORD dwMajorVer, dwMinorVer, dwBuildNumber; 5 OSVERSIONINFOEX lpVersionInformation; 6 7 BOOL set = GetVersionExW((OSVERSIONINFO *)&lpVersionInformation); 8 9 if ((lpVersionInformation.dwMajorVersion >= 6) && (lpVersionInformation.dwMinorVersion >= 2)) 10 { 11 if (hModNtdll = ::LoadLibraryW(L"ntdll.dll")) 12 { 13 typedef void (WINAPI *pfRTLGETNTVERSIONNUMBERS)(DWORD*, DWORD*, DWORD*); 14 pfRTLGETNTVERSIONNUMBERS pfRtlGetNtVersionNumbers; 15 pfRtlGetNtVersionNumbers = (pfRTLGETNTVERSIONNUMBERS)::GetProcAddress(hModNtdll, "RtlGetNtVersionNumbers"); 16 if (pfRtlGetNtVersionNumbers) 17 { 18 pfRtlGetNtVersionNumbers(&dwMajorVer, &dwMinorVer, &dwBuildNumber); 19 dwBuildNumber &= 0x0ffff; 20 } 21 ::FreeLibrary(hModNtdll); 22 hModNtdll = NULL; 23 } 24 } 25 string version = to_string(dwMajorVer) + "." + to_string(dwMinorVer) + "." + to_string(dwBuildNumber); 26 return version; 27 }
获取计算机操作系统信息基本可以依靠一下几个函数来完成
CString strOperatingSystem(OSVERSIONINFOEX str,BOOL tes) { // 系统信息 CString pszOS,gszOS; if(tes) pszOS = _T("Windows"); else pszOS = _T("Win"); switch (str.dwPlatformId) { case VER_PLATFORM_WIN32_NT: if ( str.dwMajorVersion <= 4 ) pszOS += _T("NT"); else if ( str.dwMajorVersion == 5 ) { if( str.dwMinorVersion == 0 ) pszOS += _T("2000"); else if( str.dwMinorVersion == 1 ) pszOS += _T("XP"); else if( str.dwMinorVersion == 2 ) { if(str.wProductType==VER_NT_WORKSTATION ) pszOS += _T("XP_x64"); else pszOS += _T("2003"); } } else if ( str.dwMajorVersion == 6 ) { if( str.dwMinorVersion == 0 ) { if(str.wProductType == VER_NT_WORKSTATION) pszOS += _T("Vista"); else pszOS += _T("2008"); } else if( str.dwMinorVersion == 1 ) { if(str.wProductType == VER_NT_WORKSTATION) pszOS += _T("7"); else pszOS += _T("2008R2"); } else if( str.dwMinorVersion == 2 ) { if(str.wProductType == VER_NT_WORKSTATION) pszOS += _T("8"); else pszOS += _T("2012"); } else if( str.dwMinorVersion == 3 ) { if(str.wProductType == VER_NT_WORKSTATION) pszOS += _T("8.1"); else pszOS += _T("2012R2"); } else pszOS += _T("Null"); } else if ( str.dwMajorVersion == 10 ) { if( str.dwMinorVersion == 0 ) { if(str.wProductType == VER_NT_WORKSTATION) pszOS += _T("10"); else pszOS += _T("2016"); } } } if(lstrlen(pszOS)) gszOS.Format("%s SP%d",pszOS,str.wServicePackMajor); else gszOS = _T("未知操作系统"); return gszOS; } // 读取系统位数 DWORD IsWow64() { DWORD bIsWow = 32; BOOL bIsWow64 = FALSE; FARPROC fnIsWow64Process = GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "IsWow64Process"); if(fnIsWow64Process) ((BOOL (WINAPI *)(HANDLE, PBOOL))fnIsWow64Process)(GetCurrentProcess(), &bIsWow64); if(bIsWow64) bIsWow = 64; else bIsWow = 32; return bIsWow; } BOOL GetNtVersionNumbers(DWORD&dwMajorVer, DWORD& dwMinorVer,DWORD& dwBuildNumber) { BOOL bRet= FALSE; HMODULE hModNtdll= NULL; if (hModNtdll= ::LoadLibraryW(L"ntdll.dll")) { typedef void (WINAPI *pfRTLGETNTVERSIONNUMBERS)(DWORD*,DWORD*, DWORD*); pfRTLGETNTVERSIONNUMBERS pfRtlGetNtVersionNumbers; pfRtlGetNtVersionNumbers = (pfRTLGETNTVERSIONNUMBERS)::GetProcAddress(hModNtdll, "RtlGetNtVersionNumbers"); if (pfRtlGetNtVersionNumbers) { pfRtlGetNtVersionNumbers(&dwMajorVer, &dwMinorVer,&dwBuildNumber); dwBuildNumber&= 0x0ffff; bRet = TRUE; } ::FreeLibrary(hModNtdll); hModNtdll = NULL; } return bRet; } // 获取系统版本号 BOOL g_GetVersionEx(OSVERSIONINFOEX &lpVersionInformation) { ZeroMemory(&lpVersionInformation, sizeof(OSVERSIONINFOEX)); lpVersionInformation.dwOSVersionInfoSize=sizeof(OSVERSIONINFOEX); BOOL set = GetVersionExA((OSVERSIONINFO *)&lpVersionInformation); if((lpVersionInformation.dwMajorVersion >= 6)&&(lpVersionInformation.dwMinorVersion >= 2)) { DWORD dwMajorVer,dwMinorVer,dwBuildNumber; GetNtVersionNumbers(dwMajorVer,dwMinorVer,dwBuildNumber); lpVersionInformation.dwMajorVersion = dwMajorVer; lpVersionInformation.dwMinorVersion = dwMinorVer; } return set; }
void main()
{
// TODO: Add your control notification handler code here
OSVERSIONINFOEX Log_OsVerInfoEx; // 系统版本信息
g_GetVersionEx(Log_OsVerInfoEx);
CString VerInfo;
VerInfo.Format("%d.%d %s[%d位]",Log_OsVerInfoEx.dwMajorVersion,Log_OsVerInfoEx.dwMinorVersion,strOperatingSystem(Log_OsVerInfoEx,TRUE),IsWow64());
SetDlgItemText(IDC_VERLNFOEX,VerInfo);
}