· http://flyxxtt.blogbus.com/logs/42705986.html
Windows API 中有兩個(gè)函數(shù)可以得到系統(tǒng)版本信息:GetVersion和GetVersionEx。
GetVersion這個(gè)函數(shù)曾經(jīng)困擾了很多程序員,其本來設(shè)計(jì)的是在DWORD返回值中用低位的那個(gè)字表示MS-DOS的版本號(hào),高位的那個(gè)字表示Windows版本號(hào)。對(duì)于每個(gè)字來說,高位字節(jié)代表主要版本號(hào),低位字節(jié)代表次要版本號(hào)。可是因?yàn)榫帉懘撕瘮?shù)的程序員犯了一個(gè)錯(cuò)誤,使得此函數(shù)返回的Windows版本號(hào)顛倒了(即把主要版本號(hào)放到了低位字節(jié),而次要版本號(hào)放到了高位字節(jié))。當(dāng)發(fā)現(xiàn)此錯(cuò)誤的時(shí)候已經(jīng)有很多程序員在使用這個(gè)函數(shù)了,Microsoft只好將錯(cuò)就錯(cuò),直接把原來的API文檔給改了過來。
為了解決GetVersion帶來的問題,Microsoft后來開發(fā)了一個(gè)新的函數(shù)GetVersionEx,用它能夠得到更詳細(xì)的Windows系統(tǒng)的版本信息,下面我就寫寫GetVersionEx的使用方法。
函數(shù)原型:
BOOL GetVersionEx(POSVERSIONINFO pVersionInformation);
我們先來看看OSVERSIONINFOEX這個(gè)結(jié)構(gòu):
typedef struct {
DWORD dwOSVersionInfoSize; //在使用GetVersionEx之前要將此初始化為結(jié)構(gòu)的大小
DWORD dwMajorVersion; //系統(tǒng)主版本號(hào)
DWORD dwMinorVersion; //系統(tǒng)次版本號(hào)
DWORD dwBuildNumber; //系統(tǒng)構(gòu)建號(hào)
DWORD dwPlatformId; //系統(tǒng)支持的平臺(tái)(詳見附1)
TCHAR szCSDVersion[128]; //系統(tǒng)補(bǔ)丁包的名稱
WORD wServicePackMajor; //系統(tǒng)補(bǔ)丁包的主版本
WORD wServicePackMinor; //系統(tǒng)補(bǔ)丁包的次版本
WORD wSuiteMask; //標(biāo)識(shí)系統(tǒng)上的程序組(詳見附2)
BYTE wProductType; //標(biāo)識(shí)系統(tǒng)類型(詳見附3)
BYTE wReserved; //保留,未使用
} OSVERSIONINFOEX, *POSVERSIONINFOEX;
這個(gè)結(jié)構(gòu)在Windows 2000后出現(xiàn),老版本的OSVERSIONINFO結(jié)構(gòu)沒有wServicePackMajor、wServicePackMinor、wSuiteMask、wProductType和wReserved這幾個(gè)成員。
接著在調(diào)用函數(shù)之前先初始化結(jié)構(gòu)的大小:
OSVERSIONINFOEX os;
os.dwOSVersionInfoSize=sizeof(os);
函數(shù)返回值為TRUE表示成功:
if(!GetVersionEx((OSVERSIONINFO *)&os))
{
return FALSE;
}
函數(shù)調(diào)用成功以后就可以通過OSVERSIONINFOEX來查看系統(tǒng)的版本信息了。
下面是一個(gè)通過系統(tǒng)版本來判斷操作系統(tǒng)名稱的例子:
CString getSystemName()
{
SYSTEM_INFO info; //用SYSTEM_INFO結(jié)構(gòu)判斷64位AMD處理器
GetSystemInfo(&info); //調(diào)用GetSystemInfo函數(shù)填充結(jié)構(gòu)
OSVERSIONINFOEX os;
os.dwOSVersionInfoSize=sizeof(OSVERSIONINFOEX); /*在調(diào)用函數(shù)前必須用sizeof(OSVERSIONINFOEXA)填充dwOSVersionInfoSize結(jié)構(gòu)成員*/
if(GetVersionEx((OSVERSIONINFO *)&os)) /*調(diào)用GetVersionEx函數(shù)OSVERSIONINFOEX結(jié)構(gòu)必須將指針類型強(qiáng)制轉(zhuǎn)換*/
{
CString vname;
//下面根據(jù)版本信息判斷操作系統(tǒng)名稱
switch(os.dwMajorVersion){ //判斷主版本號(hào)
case 4:
switch(os.dwMinorVersion){ //判斷次版本號(hào)
case 0:
if(os.dwPlatformId==VER_PLATFORM_WIN32_NT)
vname=_T("Microsoft Windows NT 4.0"); //1996年7月發(fā)布
else if(os.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)
vname=_T("Microsoft Windows 95");
break;
case 10:
vname=_T("Microsoft Windows 98");
break;
case 90:
vname=_T("Microsoft Windows Me");
break;
}
break;
case 5:
switch(os.dwMinorVersion){ //再比較dwMinorVersion的值
case 0:
vname=_T("Microsoft Windows 2000"); //1999年12月發(fā)布
break;
case 1:
vname=_T("Microsoft Windows XP"); //2001年8月發(fā)布
break;
case 2:
if(os.wProductType==VER_NT_WORKSTATION && /
info.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
vname=_T("Microsoft Windows XP Professional x64 Edition");
else if(GetSystemMetrics(SM_SERVERR2)==0)
vname=_T("Microsoft Windows Server 2003"); //2003年3月發(fā)布
else if(GetSystemMetrics(SM_SERVERR2)!=0)
vname=_T("Microsoft Windows Server 2003 R2");
break;
}
break;
case 6:
switch(os.dwMinorVersion){
case 0:
if(os.wProductType==VER_NT_WORKSTATION)/*
VER_NT_WORKSTATION是桌面系統(tǒng) */
vname=_T("Microsoft Windows Vista");
else
vname=_T("Microsoft Windows Server 2008"); //服務(wù)器版本
break;
case 1:
if(os.wProductType==VER_NT_WORKSTATION)
vname=_T("Microsoft Windows 7");
else
vname=_T("Microsoft Windows Server 2008 R2");
break;
}
break;
default:
vname=_T("未知操作系統(tǒng)");
}
return vname;
}
else
return _T("");
}
以上只能判斷操作系統(tǒng)的名稱,那如何判斷它是什么版本的呢(如Home版或Professional版)。
下面這個(gè)函數(shù)就返回具體的版本名稱:
CString getVersionMark()
{
OSVERSIONINFOEX os;
os.dwOSVersionInfoSize=sizeof(OSVERSIONINFOEX);
if(GetVersionEx((OSVERSIONINFO *)&os)){
CString vmark;
switch(os.dwMajorVersion){ //先判斷操作系統(tǒng)版本
case 5:
switch(os.dwMinorVersion){
case 0: //Windows 2000
if(os.wSuiteMask==VER_SUITE_ENTERPRISE)
vmark=_T("Advanced Server");
break;
case 1: //Windows XP
if(os.wSuiteMask==VER_SUITE_EMBEDDEDNT)
vmark=_T("Embedded");
else if(os.wSuiteMask==VER_SUITE_PERSONAL)
vmark=_T("Home Edition");
else
vmark=_T("Professional");
break;
case 2:
if(GetSystemMetrics(SM_SERVERR2)==0 && /
os.wSuiteMask==VER_SUITE_BLADE) //Windows Server 2003
vmark=_T("Web Edition");
else if(GetSystemMetrics(SM_SERVERR2)==0 && /
os.wSuiteMask==VER_SUITE_COMPUTE_SERVER)
vmark=_T("Compute Cluster Edition");
else if(GetSystemMetrics(SM_SERVERR2)==0 && /
os.wSuiteMask==VER_SUITE_STORAGE_SERVER)
vmark=_T("Storage Server");
else if(GetSystemMetrics(SM_SERVERR2)==0 && /
os.wSuiteMask==VER_SUITE_DATACENTER)
vmark=_T("Datacenter Edition");
else if(GetSystemMetrics(SM_SERVERR2)==0 && /
os.wSuiteMask==VER_SUITE_ENTERPRISE)
vmark=_T("Enterprise Edition");
else if(GetSystemMetrics(SM_SERVERR2)!=0 && /
os.wSuiteMask==VER_SUITE_STORAGE_SERVER) /*
Windows Server 2003 R2*/
vmark=_T("Storage Server");
break;
}
break;
case 6:
switch(os.dwMinorVersion){
case 0:
if(os.wProductType!=VER_NT_WORKSTATION && /
os.wSuiteMask==VER_SUITE_DATACENTER) /*
Windows Server 2008*/
vmark=_T("Datacenter Server");
else if(os.wProductType!=VER_NT_WORKSTATION && /
os.wSuiteMask==VER_SUITE_ENTERPRISE)
vmark=_T("Enterprise");
else if(os.wProductType==VER_NT_WORKSTATION && /
os.wSuiteMask==VER_SUITE_PERSONAL) //Windows Vista
vmark=_T("Home");
break;
}
break;
default:
vmark=_T("");
}
return vmark;
}
else
return _T("");
}
另外,操作系統(tǒng)的補(bǔ)丁包名稱也可以從szCSDVersion直接獲取。
程序編譯出來后大家可以用不同版本的兼容模式運(yùn)行這個(gè)程序,來檢測(cè)結(jié)果是不是正確,兼容模式會(huì)欺騙GetVersionEx這些API函數(shù),拿Windows 98 兼容模式來說,程序會(huì)以為自己是在Windows 98 上運(yùn)行。
有什么問題請(qǐng)給我留言,如果在本頁面下發(fā)沒有看到有留言請(qǐng)刷新一下頁面。
附1:dwPlatformId的值:
VER_PLATFORM_WIN32s (Win32s),
VER_PLATFORM_WIN32_WINDOWS (Windows 95/Windows 98),
VER_PLATFORM_WIN32_NT (Windows NT/Windows 2000),
VER_PLATFORM_WIN32_CEHH (Windows CE).
附2:wSuiteMask的值:
VER_SUITE_SMALLBUSINESS,
VER_SUITE_ENTERPRISE,
VER_SUITE_BACKOFFICE,
VER_SUITE_COMMUNICATIONS,
VER_SUITE_TERMINAL,
VER_SUITE_SMALLBUSINESS_RESTRICTED,
VER_SUITE_EMBEDDEDNT,
VER_SUITE_DATACENTER.
附3:wProductType的值:
VER_NT_WORKSTATION,
VER_NT_SERVER,
VER_NT_DOMAIN_CONTROLLER.