作者:朱金灿
来源:http://blog.csdn.net/clever101
个人不建议用 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; }
参考文献: