作者:朱金灿
来源:
个人不建议用 GetVersion 或GetVersionEx 之类的 API 来获取系统版本号。注意微软也说过,这个结果会受到兼容模式的影响,即如果程序设置兼容模式为 XP 那么拿到的也可能是 5.1 的。所以要准确的获取版本号,我建议直接获取 kernel32.dll 的主版本号,这个是和系统的版本号是一样的。
下面是我写的一个获取windows版本信息的两个函数,供大家参考:
// 具体版本信息参考Operating System Version https://msdn.microsoft.com/en-us/library/ms724832.aspxenum enOsInfo{ OS_UNKNOWN = 0, // 未知的操作系统OS_WIN_NT_3_5, // win nt 4.0,1996年7月发布 OS_WIN_95, // win 95OS_WIN_98,OS_WIN_ME, // windows me OS_WIN_2000,OS_WIN_XP,OS_WIN_XP_64, // win xp 64位OS_WIN_SERVER2003, OS_WIN_SERVER2003_R2,OS_WIN_VISTA,OS_WIN_SERVER2008,OS_WIN_SERVER2008_R2,OS_WIN7,OS_WIN7_64,OS_WIN_SERVER2012, OS_WIN8, //6.2OS_WIN8_64,OS_WIN_SERVER2012_R2,OS_WIN8_1 // 6.3};bool GetWindowsVersion(int& nMajorVersion,int& nMinorVersion,int& nBuildVersion,int& nReviVersion){TCHAR szDLLName[MAX_PATH] = { 0 };HRESULT hr = SHGetFolderPath(NULL, CSIDL_SYSTEM, NULL, SHGFP_TYPE_CURRENT, szDLLName);if (SUCCEEDED(hr) && PathAppend(szDLLName, _T("kernel32.dll"))) {DWORD dwVerInfoSize = GetFileVersionInfoSize(szDLLName, NULL);if (dwVerInfoSize > 0) {LPVOID pvVerInfoData = (LPVOID)new BYTE[dwVerInfoSize];if (GetFileVersionInfo(szDLLName, 0, dwVerInfoSize, pvVerInfoData)) {UINT ulLength = 0;VS_FIXEDFILEINFO* pVsInfo = NULL;if (VerQueryValue(pvVerInfoData, _T("\\"), (LPVOID *)&pVsInfo, &ulLength)) {nMajorVersion = HIWORD(pVsInfo->dwFileVersionMS);nMinorVersion = LOWORD(pVsInfo->dwFileVersionMS);nBuildVersion = HIWORD(pVsInfo->dwFileVersionLS);nReviVersion = LOWORD(pVsInfo->dwFileVersionLS);delete[] pvVerInfoData;return true;}}delete[] pvVerInfoData;}}return false;}enOsInfo GetOsInfo(){ enOsInfo os_info = OS_UNKNOWN;int nMajorVersion,nMinorVersion,nBuildVersion,nReviVersion;if(GetWindowsVersion( nMajorVersion,nMinorVersion,nBuildVersion,nReviVersion)){ switch(nMajorVersion){case 3:{ os_info = OS_WIN_NT_3_5; break;}case 4:{switch(nMinorVersion){case 0:os_info = OS_WIN_95;break;case 1:os_info = OS_WIN_98;break;case 9:os_info = OS_WIN_ME;break;default: break;} break;}case 5:{switch(nMinorVersion){case 0:os_info = OS_WIN_2000;break;case 1:os_info = OS_WIN_XP;break;case 2:{SYSTEM_INFO info; //用SYSTEM_INFO结构判断64位AMD处理器 GetNativeSystemInfo(&info); //调用GetSystemInfo函数填充结构 OSVERSIONINFOEX os; os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); if(GetVersionEx((OSVERSIONINFO *)&os)) {if(os.wProductType==VER_NT_WORKSTATION &&(info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64||info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64)) { os_info = OS_WIN_XP_64; } else if(GetSystemMetrics(SM_SERVERR2)==0) os_info = OS_WIN_SERVER2003; //2003年3月发布else if(GetSystemMetrics(SM_SERVERR2)!=0) os_info = OS_WIN_SERVER2003_R2; }break;}default:break;}break;} case 6:{SYSTEM_INFO info; //用SYSTEM_INFO结构判断64位AMD处理器 GetNativeSystemInfo(&info); //调用GetSystemInfo函数填充结构 OSVERSIONINFOEX os; os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); if(!GetVersionEx((OSVERSIONINFO *)&os)) break;switch(nMinorVersion){case 0:{if(os.wProductType == VER_NT_WORKSTATION) os_info = OS_WIN_VISTA; elseos_info = OS_WIN_SERVER2008;break;}case 1:if(os.wProductType == VER_NT_WORKSTATION) {if(info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64||info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64)os_info = OS_WIN7_64;else os_info = OS_WIN7;}elseos_info = OS_WIN_SERVER2008_R2;break;case 2:{if(os.wProductType == VER_NT_WORKSTATION) {if(info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 ||info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64)os_info = OS_WIN8_64;elseos_info = OS_WIN8;}elseos_info = OS_WIN_SERVER2012; break;}case 3:{if(os.wProductType == VER_NT_WORKSTATION) {os_info = OS_WIN8_1;}elseos_info = OS_WIN_SERVER2012_R2;break;}default:break;}break;}default:break;}}return os_info;}
参考文献:
1.
2.