Windows SDK練習曲--檢驗Windows版本資訊
Windows版本資訊除了能「取得」之後自行檢查,也能直接將相關資訊送交特定API來檢驗;例如若想知道是不是Windows 7,就送驗主序號6和次序號1。
負責檢驗版本資訊的API是VerifyVersionInfo,但在呼叫之前,必須先以OSVERSIONINFOEX結構和VER_SET_CONDITION巨集來處理欲檢驗的相關資訊。以下以檢驗Windows 7為例說明(Windows 7的版本序號是6.1)。
設定OSVERSIONINFOEX結構
之前的例子就曾用過OSVERSIONINFOEX,這個結構可儲存好幾種Windows版本相關資訊,本例欲檢驗Windows 7,因此其中與本例相關的是:
- dwMajorVersion:主序號,設為6。
- dwMinorVersion:次序號,設為1。
- wServicePackMajor:Service Pack主序號,設為0。
- wServicePackMinor:Service Pack次序號,設為0。
- wProductType:產品類型,設為VER_NT_WORKSTATION。
雖然目前Windows 7並無Service Pack,也就是並無檢驗Service Pack序號的必要,但仍建議加入,並設為0。整個初始OSVERSIONINFOEX的程式碼如下:
OSVERSIONINFOEX osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); osvi.dwMajorVersion = 6;
osvi.dwMinorVersion = 1;
osvi.wServicePackMajor = 0;
osvi.wServicePackMinor = 0;
osvi.wProductType = VER_NT_WORKSTATION;
呼叫VER_SET_CONDITION巨集
VER_SET_CONDITION巨集的目的是設定比較的條件遮罩,以設定Windows 7的主序號為例:
VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
- dwlConditionMask:儲存比較資訊(初始值需為0),後續會是呼叫VerifyVersionInfo的第3個參數。
- VER_MAJORVERSION:設定比較的類型,VER_MAJORVERSION即為版本主序號。所有類型的常數包括:
- VER_BUILDNUMBER(dwBuildNumber)
- VER_MAJORVERSION(dwMajorVersion)
- VER_MINORVERSION(dwMinorVersion)
- VER_PLATFORMID(dwPlatformId)
- VER_PRODUCT_TYPE(wProductType)
- VER_SERVICEPACKMAJOR(wServicePackMajor)
- VER_SERVICEPACKMINOR(wServicePackMinor)
- VER_SUITENAME(wSuiteMask)
- VER_GREATER_EQUAL:比較運算子,VER_GREATER_EQUAL表示必須大於或等於,也就是本例必須大於或等於6才會得到True值。其他的運算子常數包括:
- VER_EQUAL:等於
- VER_GREATER:大於
- VER_GREATER_EQUAL:大於或等於
- VER_LESS:小於
- VER_LESS_EQUAL:小於或等於
本例需比較5項資訊,程式碼如下:
VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
VER_SET_CONDITION(dwlConditionMask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
VER_SET_CONDITION(dwlConditionMask, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL);
VER_SET_CONDITION(dwlConditionMask, VER_NT_WORKSTATION, VER_EQUAL );
呼叫VerifyVersionInfo函式
VerifyVersionInfo(
&osvi,
VER_MAJORVERSION | VER_MINORVERSION |
VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR |
VER_NT_WORKSTATION,
dwlConditionMask);
VerifyVersionInfo函式有3個參數:
- 指向OSVERSIONINFOEX的指標。
- 檢驗的類型,同VER_SET_CONDITION的第2個參數,能以OR位元運算子(|)合併所有欲檢驗的類型常數。
- 比較資訊,就是VER_SET_CONDITION巨集的第1個參數。
VerifyVersionInfo函式的傳回值有3種情況:
- 目前作業系統符合檢驗資訊,傳回非零值(也就是True)。
- 目前作業系統「不」符合檢驗資訊,或,傳回零(也就是Flase),且GetLastError函式會傳回ERROR_OLD_WIN_VERSION。
- VerifyVersionInfo函式呼叫失敗,傳回零(也就是Flase),且GetLastError函式會傳回不同於ERROR_OLD_WIN_VERSION的錯誤碼(端視錯誤原因而定)。
檢驗Windows版本資訊
我們可以將檢驗Windows 7的程式碼包裝成函式(例如Is_Win7_or_Later),再根據傳回值來判斷目前的作業系統版本是不是Windows 7:
if(Is_Win7_or_Later()) printf("這是 Windows 7 或其後續版本\n"); else printf("這不是 Windows 7 或其後續版本\n");
完整的程式碼請下載verifyWinVer.zip(1 KB),其中還另外包含了Windows Server 2008 SP2及網域控制器的檢驗。


4 意見:
嗚~我程式知識不深都看不懂
> <
影子您好:
如果您想看懂的話,可以花點時間加強 C 語言、Windows SDK 開發的能力。
賴大哥您好,小弟想請問一下,如何判斷作業系統WIN-PE與非WIN-PE?因為使用您的方式擷取出來的資訊並不能判斷出是否為PE版本,系統提供的API得到的版本數在WIN-PE與非WIN-PE下得到的版本數皆相同,小弟也曾參考MSND範例http://msdn.microsoft.com/en-us/library/ms724429(v=VS.85).aspx,但還是得不到答案,所以想請教賴大哥有什麼方式可以判斷目前作業系統版本是否為WIN-PE,謝謝。
NONO你好:
目前並沒有直接得知Windows PE版本資訊的Windows API,只能旁敲側擊。
網路上有一篇討論(http://groups.google.com/group/microsoft.public.win32.programmer.kernel/browse_thread/thread/8da9b4e7a911b410?pli=1),其中Jeffrey Tan提供的方式值得一試,供你參考。
張貼意見