Windows API GetVersionEx()判断系统版本详解
生活随笔
收集整理的這篇文章主要介紹了
Windows API GetVersionEx()判断系统版本详解
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
轉(zhuǎn)載自:http://bbs.7boo.com.cn/thread-8093-1-1.html AF注: TCHAR cstCSDVersion[128]; sprintf(cstCSDVersion,"%s",os.szCSDVersion);//spk Windows API?中有兩個函數(shù)可以得到系統(tǒng)版本信息:GetVersion和GetVersionEx。
? ?? ?GetVersion這個函數(shù)曾經(jīng)困擾了很多程序員,其本來設(shè)計的是在DWORD返回值中用低位的那個字表示MS-DOS的版本號,高位的那個字表示Windows版本號。對于每個字來說,高位字節(jié)代表主要版本號,低位字節(jié)代表次要版本號??墒且驗榫帉懘撕瘮?shù)的程序員犯了一個錯誤,使得此函數(shù)返回的Windows版本號顛倒了(即把主要版本號放到了低位字節(jié),而次要版本號放到了高位字節(jié))。當發(fā)現(xiàn)此錯誤的時候已經(jīng)有很多程序員在使用這個函數(shù)了,Microsoft只好將錯就錯,直接把原來的API文檔給改了過來。
? ?? ?為了解決GetVersion帶來的問題,Microsoft后來開發(fā)了一個新的函數(shù)GetVersionEx,用它能夠得到更詳細的Windows系統(tǒng)的版本信息,下面我就寫寫GetVersionEx的使用方法。
函數(shù)原型:
BOOL?GetVersionEx(POSVERSIONINFO pVersionInformation);
我們先來看看OSVERSIONINFOEX這個結(jié)構(gòu):
typedef struct {
DWORD dwOSVersionInfoSize;? ?? ? //在使用GetVersionEx之前要將此初始化為結(jié)構(gòu)的大小
DWORD dwMajorVersion;? ?? ?? ?? ?? ?//系統(tǒng)主版本號
DWORD dwMinorVersion;? ?? ?? ?? ?? ?//系統(tǒng)次版本號
DWORD dwBuildNumber;? ?? ?? ?? ?? ?//系統(tǒng)構(gòu)建號
DWORD dwPlatformId;? ?? ?? ?? ?? ?? ?//系統(tǒng)支持的平臺(詳見附1)
TCHAR szCSDVersion[128];? ?? ?? ? //系統(tǒng)補丁包的名稱
WORD wServicePackMajor;? ?? ?? ?? ?//系統(tǒng)補丁包的主版本
WORD wServicePackMinor;? ?? ?? ?? ?//系統(tǒng)補丁包的次版本
WORD wSuiteMask;? ?? ?? ?? ?? ?? ?? ? //標識系統(tǒng)上的程序組(詳見附2)
BYTE wProductType;? ?? ?? ?? ?? ?? ???//標識系統(tǒng)類型(詳見附3)
BYTE wReserved;? ?? ?? ?? ?? ?? ?? ?? ? //保留,未使用
} OSVERSIONINFOEX, *POSVERSIONINFOEX;
這個結(jié)構(gòu)在Windows 2000后出現(xiàn),老版本的OSVERSIONINFO結(jié)構(gòu)沒有wServicePackMajor、wServicePackMinor、wSuiteMask、wProductType和wReserved這幾個成員。
接著在調(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)的版本信息了。
下面是一個通過系統(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);???
? ? if(GetVersionEx((OSVERSIONINFO *)&os))? ?? ?? ?? ?? ?? ? ? ? {? ? ?? ???CString vname;? ? ?? ???//下面根據(jù)版本信息判斷操作系統(tǒng)名稱?
? ?? ???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月發(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) ? ?? ?? ?? ?? ?? ?? ?? ?? ? 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版)。
下面這個函數(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)??
? ?? ?? ?? ?? ?? ?? ?? ?? ? 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(""); } 復制代碼 另外,操作系統(tǒng)的補丁包名稱也可以從szCSDVersion直接獲取。
程序編譯出來后大家可以用不同版本的兼容模式運行這個程序,來檢測結(jié)果是不是正確,兼容模式會欺騙GetVersionEx這些API函數(shù),拿Windows 98 兼容模式來說,程序會以為自己是在Windows 98 上運行。
有什么問題請給我留言,如果在本頁面下發(fā)沒有看到有留言請刷新一下頁面。
附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.
? ?? ?GetVersion這個函數(shù)曾經(jīng)困擾了很多程序員,其本來設(shè)計的是在DWORD返回值中用低位的那個字表示MS-DOS的版本號,高位的那個字表示Windows版本號。對于每個字來說,高位字節(jié)代表主要版本號,低位字節(jié)代表次要版本號??墒且驗榫帉懘撕瘮?shù)的程序員犯了一個錯誤,使得此函數(shù)返回的Windows版本號顛倒了(即把主要版本號放到了低位字節(jié),而次要版本號放到了高位字節(jié))。當發(fā)現(xiàn)此錯誤的時候已經(jīng)有很多程序員在使用這個函數(shù)了,Microsoft只好將錯就錯,直接把原來的API文檔給改了過來。
? ?? ?為了解決GetVersion帶來的問題,Microsoft后來開發(fā)了一個新的函數(shù)GetVersionEx,用它能夠得到更詳細的Windows系統(tǒng)的版本信息,下面我就寫寫GetVersionEx的使用方法。
函數(shù)原型:
BOOL?GetVersionEx(POSVERSIONINFO pVersionInformation);
我們先來看看OSVERSIONINFOEX這個結(jié)構(gòu):
typedef struct {
DWORD dwOSVersionInfoSize;? ?? ? //在使用GetVersionEx之前要將此初始化為結(jié)構(gòu)的大小
DWORD dwMajorVersion;? ?? ?? ?? ?? ?//系統(tǒng)主版本號
DWORD dwMinorVersion;? ?? ?? ?? ?? ?//系統(tǒng)次版本號
DWORD dwBuildNumber;? ?? ?? ?? ?? ?//系統(tǒng)構(gòu)建號
DWORD dwPlatformId;? ?? ?? ?? ?? ?? ?//系統(tǒng)支持的平臺(詳見附1)
TCHAR szCSDVersion[128];? ?? ?? ? //系統(tǒng)補丁包的名稱
WORD wServicePackMajor;? ?? ?? ?? ?//系統(tǒng)補丁包的主版本
WORD wServicePackMinor;? ?? ?? ?? ?//系統(tǒng)補丁包的次版本
WORD wSuiteMask;? ?? ?? ?? ?? ?? ?? ? //標識系統(tǒng)上的程序組(詳見附2)
BYTE wProductType;? ?? ?? ?? ?? ?? ???//標識系統(tǒng)類型(詳見附3)
BYTE wReserved;? ?? ?? ?? ?? ?? ?? ?? ? //保留,未使用
} OSVERSIONINFOEX, *POSVERSIONINFOEX;
這個結(jié)構(gòu)在Windows 2000后出現(xiàn),老版本的OSVERSIONINFO結(jié)構(gòu)沒有wServicePackMajor、wServicePackMinor、wSuiteMask、wProductType和wReserved這幾個成員。
接著在調(diào)用函數(shù)之前先初始化結(jié)構(gòu)的大小:
OSVERSIONINFOEX os;
os.dwOSVersionInfoSize=sizeof(os);
函數(shù)返回值為TRUE表示成功:
下面是一個通過系統(tǒng)版本來判斷操作系統(tǒng)名稱的例子:
下面這個函數(shù)就返回具體的版本名稱:
程序編譯出來后大家可以用不同版本的兼容模式運行這個程序,來檢測結(jié)果是不是正確,兼容模式會欺騙GetVersionEx這些API函數(shù),拿Windows 98 兼容模式來說,程序會以為自己是在Windows 98 上運行。
有什么問題請給我留言,如果在本頁面下發(fā)沒有看到有留言請刷新一下頁面。
附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.
轉(zhuǎn)載于:https://www.cnblogs.com/mystruc/archive/2013/02/24/2924066.html
總結(jié)
以上是生活随笔為你收集整理的Windows API GetVersionEx()判断系统版本详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Console-算法-递归算法示例
- 下一篇: iOS6.0以上版本,关于NSDateF