獲取Windows系統版本號
阿新 • • 發佈:2019-01-08
前言
由於前段時間比較忙,一直沒有來跟大家分享交流技術,實在是抱歉,往後我會不定時跟大家分享一些C++技術。
廢話
有些東西看似簡單,但坑多著呢,所以大家還是要多親自嘗試,不要眼高手低。
核心程式碼
注意事項//讀取作業系統的名稱 string GetSystemName() { SYSTEM_INFO info; //用SYSTEM_INFO結構判斷64位AMD處理器 GetSystemInfo(&info); //呼叫GetSystemInfo函式填充結構 OSVERSIONINFOEX os; os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); string osname = "unknown OperatingSystem."; if(GetVersionEx((OSVERSIONINFO *)&os)) { //下面根據版本資訊判斷作業系統名稱 switch(os.dwMajorVersion)//判斷主版本號 { case 4: switch(os.dwMinorVersion)//判斷次版本號 { case 0: if(os.dwPlatformId==VER_PLATFORM_WIN32_NT) osname = "Microsoft Windows NT 4.0"; //1996年7月釋出 else if(os.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS) osname = "Microsoft Windows 95"; break; case 10: osname = "Microsoft Windows 98"; break; case 90: osname = "Microsoft Windows Me"; break; } break; case 5: switch(os.dwMinorVersion) //再比較dwMinorVersion的值 { case 0: osname = "Microsoft Windows 2000";//1999年12月釋出 break; case 1: osname = "Microsoft Windows XP";//2001年8月釋出 break; case 2: if(os.wProductType==VER_NT_WORKSTATION && info.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64) { osname = "Microsoft Windows XP Professional x64 Edition"; } else if(GetSystemMetrics(SM_SERVERR2)==0) osname = "Microsoft Windows Server 2003";//2003年3月釋出 else if(GetSystemMetrics(SM_SERVERR2)!=0) osname = "Microsoft Windows Server 2003 R2"; break; } break; case 6: switch(os.dwMinorVersion) { case 0: if(os.wProductType == VER_NT_WORKSTATION) osname = "Microsoft Windows Vista"; else osname = "Microsoft Windows Server 2008";//伺服器版本 break; case 1: if(os.wProductType == VER_NT_WORKSTATION) osname = "Microsoft Windows 7"; else osname = "Microsoft Windows Server 2008 R2"; break; case 2: if(os.wProductType == VER_NT_WORKSTATION) osname = "Microsoft Windows 8"; else osname = "Microsoft Windows Server 2012"; break; case 3: if(os.wProductType == VER_NT_WORKSTATION) osname = "Microsoft Windows 8.1"; else osname = "Microsoft Windows Server 2012 R2"; break; } break; case 10: switch(os.dwMinorVersion) { case 0: if(os.wProductType == VER_NT_WORKSTATION) osname = "Microsoft Windows 10"; else osname = "Microsoft Windows Server 2016 Technical Preview";//伺服器版本 break; } break; } }//if(GetVersionEx((OSVERSIONINFO *)&os)) //https://msdn.microsoft.com/en-us/library/ms724832.aspx return osname; }
現在系統升級很快,這對軟體開發人員來說是個打擊,測試起來太麻煩,要考慮的相容性問題也越來越多,坑也越來越多。。。
雖然核心程式碼就一個函式:GetVersionEx,但是Win8.1和Win10獲取到的版本缺一直是6.2(Win8)
仔細閱讀微軟說明:https://msdn.microsoft.com/en-us/library/ms724832.aspx 細心的朋友可以從中找到答案
我用國語講一下出現這個問題的原因:簡單講就是相容問題。可以通過修改manifest檔案解決,也可以採用新的API來獲取版本號。
由於新的API在低版本作業系統沒有,還要特別處理,我們乾脆使用修改manifest檔案的方法,提高程式自身的相容性,從而得到正確的系統版本資訊。
將以上內容儲存為compatibility.xml,留著備用。<?xml version="1.0" encoding="UTF-8"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> <application> <!-- Windows 10 --> <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> <!-- Windows 8.1 --> <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> <!-- Windows Vista --> <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> <!-- Windows 7 --> <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> <!-- Windows 8 --> <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> </application> </compatibility> </assembly>
實戰
問題和解決方法也介紹差不多了,下面演示一下如何正確使用。
新建一個基於對話方塊的MFC專案,然後新增如下圖所示程式碼,執行結果如下
很明顯。是有問題的,本來win8.1系統,它說是win8的,下面說一下解決辦法。
程式碼不變,只需要把專案屬性設定一下就好了
配置目標那裡選則所有配置,配置屬性->清單工具->輸入和輸出-附加清單檔案 填寫compatibility.xml,並把這個檔案拷貝到專案原始碼目錄。
具體設定如下圖所示:
設定儲存後,重新生成一下,然後執行,結果如下:
很明顯,已經是win8.1了,將程式拷貝到Win10機器上,獲取到的也正確。
可以獲取作業系統版本,MAC地址,本地IP地址,以及判定是否為網咖。核心我已經封裝成類了。