1. 程式人生 > >獲取作業系統名稱和版本

獲取作業系統名稱和版本

以下內容為轉載,(最後內容為個人新增)

 原文作者:http://blog.sina.com.cn/s/blog_49764fbb0100r29v.html

先看這個:http://tieba.baidu.com/f?kz=859123733說的是什麼是SP1 sp2 sp3....
Windows XP Service Pack 的版本簡稱SP
通俗地說:微軟的漏洞補丁集合包補丁到一定數量 他們就會做補丁包
叫SP1 讓大家不用一個一個的去打了
再攢攢 就出SP2了


SP是Service Pack的縮寫,它是一個補丁包,裡面以前包括所有的安全補丁,還有一個系統方面的改善,微軟會定期釋出SP。 
windows XP 是微軟windows作業系統之一,由於XP使用一段時間後,發現有很多的漏洞和BUG,所以微軟為了防止系統受到攻擊和增加穩定性就打上了SP1補丁!後現又發現了windows XP sp1的重大漏洞(比如衝擊波/震盪波),所以微軟再進一步打上SP2補丁已增加系統的安全和穩定。
 
SP2將增設眾多功能來為使用者提供安全保障。首先,增設了Windows防火牆,來增強對PC的保護,抵禦病毒以及那些嘗試通過Internet訪問PC的入侵者。此外,未經使用者的同意,大多數由Web站點彈出的瀏覽器視窗將被關閉;Outlook Express支援新的附件管理器,它能夠在使用者開啟附件時對其進行隔離,從而避免接收到不請自來的電子郵件訊息。微軟(中國)有限公司副總經理孫建東表示:“SP2已經不再是簡單意義上的服務包,它融合了很先進的技術。”按照孫的介紹,SP2提供了增強無線支援特性,可以簡化無線網路的發現與連線方式。最後,SP2裡面包含了最新的DirectX9.0C。


為了支援更新的功能,SP2更加臃腫,更難侍侯了。一般電腦的256M記憶體,剛進系統就已經被剝削的七七八八,所剩無幾了。在不增加實體記憶體的情況下,我們建議大家加大虛擬記憶體,和儘可能的優化系統,關閉一些自己不需要的服務和程序


Windows XP Service Pack 3 (SP3) 包含以前釋出的所有 Windows XP 更新,包括安全更新和修補程式。其中還包括選擇帶外版本,以及少量新的增強功能,它們不會顯著更改客戶對作業系統的體驗。


基本上,部署 Windows XP SP3 與部署 Windows XP SP1 和 Windows XP SP2 相同: 
 • SP3 是累積的,因此使用者可以在 Windows XP SP1 或 SP2 的基礎上安裝 SP3。
 • Windows XP SP3 支援的語言與 Windows XP 的初始版本中的語言相同。 
• 可以在任何版本的 Windows XP SP1 或 SP2 上執行 SP3 更新程式包。例如,可以在執行帶有 SP1 的 Windows XP Media Center Edition 的計算機上執行 SP3 更新程式包。但 Embedded 版本的 XP 除外。
 • 系統管理員的工具和指南基本上與 Windows XP SP2 相同。有關綜合資訊,請訪問 Microsoft TechNet 上的 Deploy Windows XP Professional 和 Windows XP Service Pack 2 Deployment Information 站點。
 • 可以使用 Microsoft 系統管理伺服器 2003、Microsoft 系統中心配置管理器 2007 或第三方解決方案部署 SP3。這個過程基本上沒有改變。 Windows XP SP3 僅用於 x86 版本的 Windows XP。x64 版本的 Windows XP 由 Windows Server 2003 SP2 服務。有關其他資訊,請訪問 Windows Server 2003 Service Pack 2。


XP系統版本越新越高,檔案也就起越大,所以對電腦配置也越高。如果你是7年前買的電腦,而且沒有對它進行升級,最好安裝sp1, 增加記憶體後勉強可以安裝sp2


全新安裝完作業系統並安裝完驅動與軟體。重新啟動進入系統後,清除所有臨時檔案、Cookies,整理磁碟碎片。然後在進入系統選擇列表後,從選擇系統按回車的同時開始計時,到進入系統,所有要load的程序、服務、程式load完停止計時。 
測試的結果很明顯,雖然帶有一定的人為因素的影響,但是SP2與SP1接近10秒的差距已經超出了誤差的範圍。SP2由於需要載入防火牆、安全中心等等一系列程式,使得開機速度慢了不少。 
記憶體佔用對比:對於只有256M記憶體的使用者來說,系統本身佔用的記憶體空間也是一個比較敏感的因素,所以我們把SP1與SP2進入系統之後的記憶體佔有情況作出以下列表: 
SP1 進系統後可用的實體記憶體數為115464K;使用了138M的虛擬記憶體;有25個程序在執行 進系統後可用的實體記憶體數為94628K;使用了159M的虛擬記憶體;有28個程序在執行 
SP2 進系統後我們發現可用的實體記憶體數SP2比SP1少了20836K,近20M的記憶體;SP2使用了159M的虛擬記憶體,比SP1多使用了了21M;SP2有28個程序在執行比SP1多了3個,也可以從一個角度反應了為什麼SP2進系統比SP1慢了差不多10秒 


全新安裝完作業系統並安裝完驅動與軟體。重新啟動進入系統後,清除所有臨時檔案、C 
記憶體佔用對比:對於只有256M記憶體的使用者來說,系統本身佔用的記憶體空間也是一個比較敏感的因素,所以我們把SP1與SP2進入系統之後的記憶體佔有情況作出以下列表: 
SP1 進系統後可用的實體記憶體數為115464K;使用了138M的虛擬記憶體;有25個程序在執行 進系統後可用的實體記憶體數為94628K;使用了159M的虛擬記憶體;有28個程序在執行 
SP2 進系統後我們發現可用的實體記憶體數SP2比SP1少了20836K,近20M的記憶體;SP2使用了159M的虛擬記憶體,比SP1多使用了了21M;SP2有28個程序在執行比SP1多了3個,也可以從一個角度反應了為什麼SP2進系統比SP1慢了差不多10秒 


對於只有256M記憶體的使用者來說,系統本身佔用的記憶體空間也是一個比較敏感的因素,所以我們把SP1與SP2進入系統之後的記憶體佔有情況作出以下列表: 
SP1 進系統後可用的實體記憶體數為115464K;使用了138M的虛擬記憶體;有25個程序在執行 進系統後可用的實體記憶體數為94628K;使用了159M的虛擬記憶體;有28個程序在執行 
SP2 進系統後我們發現可用的實體記憶體數SP2比SP1少了20836K,近20M的記憶體;SP2使用了159M的虛擬記憶體,比SP1多使用了了21M;SP2有28個程序在執行比SP1多了3個,也可以從一個角度反應了為什麼SP2進系統比SP1慢了差不多10秒 




WindowsAPI使用詳解——GetVersion|GetVersionEx 獲取作業系統版本和名稱
轉載自:http://bbs.7boo.com.cn/thread-8093-1-1.html


AF注:
TCHAR cstCSDVersion[128];
sprintf(cstCSDVersion,"%s",os.szCSDVersion);//spk
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);   
    if(GetVersionEx((OSVERSIONINFO *)&os))                  
    { 
        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)
                            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)  
                            vmark=_T("Storage Server"); 
                        break; 
                } 
                break; 
            case 6: 
                switch(os.dwMinorVersion){ 
                    case 0: 
                        if(os.wProductType!=VER_NT_WORKSTATION && /
                        os.wSuiteMask==VER_SUITE_DATACENTER)   
                            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.

................................................................................................................................................

以下內容原創

以上版本判斷不包含win8及以後

版本6.2:

首先讀取登錄檔的系統名稱(後面說),如果沒有讀取到:

os.wProductType == VER_NT_WORKSTATIOn ->Windows 8

否則 windows server 2012

版本6.3同上,對應版本windows 8.1 windows server 2012 R2

        win10的判斷及將釋出的2016暫時未研究出結果

        以下是讀取登錄檔系統名稱的問題

  

bool GetWin8dot1Name(std::string& strName)
{
bool bRet = true;
do 
{
#ifdef WIN32
HKEY hKey = NULL;
LONG lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, 
REG_K,
0, KEY_ALL_ACCESS, &hKey);
if (ERROR_SUCCESS != lResult)
{
if (NULL != hKey)
{
lResult = RegCloseKey(hKey);
hKey = NULL;
}
bRet = false;
break;
}


DWORD dwType = 0;
char szSystemName[MAX_PATH] = {0};
DWORD dwSize = sizeof(szSystemName) / sizeof(szSystemName[0]);
lResult = RegQueryInfoKeyA(hKey, "ProductName", NULL, &dwType, (LPBYTE)szSystemName, (DWORD*)&dwSize);
if (ERROR_SUCCESS != hKey)
{
//同上;
}
strName = szSystemName;
RegCloseKey(hKey);


#endif
} while (0);


return bRet;
}