GetVersion GetVersionEx判斷系統代碼


Windows API 中有兩個函數可以得到系統版本信息:GetVersion和GetVersionEx。
      GetVersion這個函數曾經困擾了很多程序員,其本來設計的是在DWORD返回值中用低位的那個字表示MS-DOS的版本號,高位的那個字表示Windows版本號。對於每個字來說,高位字節代表主要版本號,低位字節代表次要版本號。可是因爲編寫此函數的程序員犯了一個錯誤,使得此函數返回的Windows版本號顛倒了(即把主要版本號放到了低位字節,而次要版本號放到了高位字節)。當發現此錯誤的時候已經有很多程序員在使用這個函數了,Microsoft只好將錯就錯,直接把原來的API文檔給改了過來。
      爲了解決GetVersion帶來的問題,Microsoft後來開發了一個新的函數GetVersionEx,用它能夠得到更詳細的Windows系統的版本信息,下面我就寫寫GetVersionEx的使用方法。
函數原型:
BOOL GetVersionEx(POSVERSIONINFO pVersionInformation);
我們先來看看OSVERSIONINFOEX這個結構:
typedef struct {
DWORD dwOSVersionInfoSize;       //在使用GetVersionEx之前要將此初始化爲結構的大小
DWORD dwMajorVersion;               //系統主版本號
DWORD dwMinorVersion;               //系統次版本號
DWORD dwBuildNumber;               //系統構建號
DWORD dwPlatformId;                  //系統支持的平臺(詳見附1)
TCHAR szCSDVersion[128];          //系統補丁包的名稱
WORD wServicePackMajor;            //系統補丁包的主版本
WORD wServicePackMinor;            //系統補丁包的次版本
WORD wSuiteMask;                      //標識系統上的程序組(詳見附2)
BYTE wProductType;                    //標識系統類型(詳見附3)
BYTE wReserved;                         //保留,未使用
} OSVERSIONINFOEX, *POSVERSIONINFOEX;
這個結構在Windows 2000後出現,老版本的OSVERSIONINFO結構沒有wServicePackMajor、wServicePackMinor、wSuiteMask、wProductType和wReserved這幾個成員。
接着在調用函數之前先初始化結構的大小:
OSVERSIONINFOEX os;
os.dwOSVersionInfoSize=sizeof(os);
函數返回值爲TRUE表示成功:
if(!GetVersionEx((OSVERSIONINFO *)&os))
{
      return FALSE;
}
函數調用成功以後就可以通過OSVERSIONINFOEX來查看系統的版本信息了。
下面是一個通過系統版本來判斷操作系統名稱的例子:
CString getSystemName()
{
    SYSTEM_INFO info;                                   //用SYSTEM_INFO結構判斷64位AMD處理器
    GetSystemInfo(&info);                               //調用GetSystemInfo函數填充結構
    OSVERSIONINFOEX os;
    os.dwOSVersionInfoSize=sizeof(OSVERSIONINFOEX);  /*在調用函數前必須用sizeof(OSVERSIONINFOEXA)填充dwOSVersionInfoSize結構成員*/
    if(GetVersionEx((OSVERSIONINFO *)&os))                  /*調用GetVersionEx函數OSVERSIONINFOEX結構必須將指針類型強制轉換*/
    {
        CString vname;
        //下面根據版本信息判斷操作系統名稱
        switch(os.dwMajorVersion){                        //判斷主版本號
            case 4:
                switch(os.dwMinorVersion){                //判斷次版本號
                    case 0:
                        if(os.dwPlatformId==VER_PLATFORM_WIN32_NT)
                            vname=_T("Microsoft Windows NT 4.0");                //1996年7月發佈
                        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月發佈
                        break;
                    case 1:
                        vname=_T("Microsoft Windows XP");                    //2001年8月發佈
                        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月發佈
                        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是桌面系統 */
                            vname=_T("Microsoft Windows Vista");
                        else
                            vname=_T("Microsoft Windows Server 2008");          //服務器版本
                        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("未知操作系統");
        }
        return vname;
    }
    else
        return _T("");
}
以上只能判斷操作系統的名稱,那如何判斷它是什麼版本的呢(如Home版或Professional版)。
下面這個函數就返回具體的版本名稱:
CString getVersionMark()
{
    OSVERSIONINFOEX os;
    os.dwOSVersionInfoSize=sizeof(OSVERSIONINFOEX);
    if(GetVersionEx((OSVERSIONINFO *)&os)){
        CString vmark;
        switch(os.dwMajorVersion){                //先判斷操作系統版本
            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("");
}
另外,操作系統的補丁包名稱也可以從szCSDVersion直接獲取。
程序編譯出來後大家可以用不同版本的兼容模式運行這個程序,來檢測結果是不是正確,兼容模式會欺騙GetVersionEx這些API函數,拿Windows 98 兼容模式來說,程序會以爲自己是在Windows 98 上運行。
有什麼問題請給我留言,如果在本頁面下發沒有看到有留言請刷新一下頁面。
附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.

 
 

Operating system Version number dwMajorVersion  dwMinorVersion Other
Windows 7 6.1 6 1 OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION
Windows Server 2008 R2 6.1 6 1 OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION
Windows Server 2008 6.0 6 0 OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION
Windows Vista 6.0 6 0 OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION
Windows Server 2003 R2 5.2 5 2 GetSystemMetrics(SM_SERVERR2) != 0
Windows Home Server 5.2 5 2 OSVERSIONINFOEX.wSuiteMask == VER_SUITE_WH_SERVER
Windows Server 2003 5.2 5 2 GetSystemMetrics(SM_SERVERR2) == 0
Windows XP Professional x64 Edition 5.2 5 2 (OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION) && (SYSTEM_INFO.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
Windows XP 5.1 5 1 Not applicable
Windows 2000 5.0 5 0 Not applicable
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章