獲取windows版本資訊的做法
阿新 • • 發佈:2019-02-18
作者:朱金燦
個人不建議用 GetVersion 或GetVersionEx 之類的 API 來獲取系統版本號。注意微軟也說過,這個結果會受到相容模式的影響,即如果程式設定相容模式為 XP 那麼拿到的也可能是 5.1 的。所以要準確的獲取版本號,我建議直接獲取 kernel32.dll 的主版本號,這個是和系統的版本號是一樣的。
下面是我寫的一個獲取windows版本資訊的兩個函式,供大家參考:
// 具體版本資訊參考Operating System Version https://msdn.microsoft.com/en-us/library/ms724832.aspx enum enOsInfo { OS_UNKNOWN = 0, // 未知的作業系統 OS_WIN_NT_3_5, // win nt 4.0,1996年7月釋出 OS_WIN_95, // win 95 OS_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.2 OS_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; else os_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; } else os_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; else os_info = OS_WIN8; } else os_info = OS_WIN_SERVER2012; break; } case 3: { if(os.wProductType == VER_NT_WORKSTATION) { os_info = OS_WIN8_1; } else os_info = OS_WIN_SERVER2012_R2; break; } default: break; } break; } default: break; } } return os_info; }
參考文獻: