ネタ元:初っ端から Service Pack 1 適用済みの Windows Server 2008
古い系のネタでヒットしたものをピックアップするこのコーナー。第二回の栄えある?APIは GetVersionEx です。
稼働中のOSのバージョン判定に使うAPIです。注意点としては、NT 系OSでは、完璧にだまされることがある(ACTでだませますw)という点ですかね。
9x系でも、ある程度だませますが、こちらは回避コードが公開されていたので、setup.exe を自作していた人ならたぶんみんな知ってると思いますw
ということで、9x系回避コード付きの、バージョン取得。
1: bool MyGetVersion( OSVERSIONINFOEX& verInfo )
2: {
3: verInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
4: if( !::GetVersionEx( reinterpret_cast<OSVERSIONINFO*>( &verInfo ) ) ){
5: verInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
6: if( !::GetVersionEx( reinterpret_cast<OSVERSIONINFO*>( &verInfo ) ) ){
7: return false;
8: }
9: }
10: // 9x 系の場合のリカバリ
11: if( verInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ){
12: WORD wOsVer = HIWORD( verInfo.dwBuildNumber );
13: verInfo.dwBuildNumber = LOWORD( m_verInfo.dwBuildNumber );
14: verInfo.dwMajorVersion = HIBYTE( wOsVer );
15: verInfo.dwMinorVersion = LOBYTE( wOsVer );
16: }
17: return true;
18: }
API自身は、NT 3.5 から搭載みたいです。さすがにそんなに古い資料を引き出してくるのは面倒なので、当時のリファレンスは見てませんがw
ちなみに、EX 構造体版の呼び出しは、NT4 SP6 以降からとなります。9x系はもちろんそれ以前のNT4(3.5xを含む)はエラーを返します。
稼働中のOS判定は、まず最初に、dwPlatformId で識別します。ここである程度ふるいにかけた後、実際に対応するOSかどうか?の判定となります。
この値は、
VER_PLATFORM_WIN32s |
0 |
Win32s 環境 |
VER_PLATFORM_WINDOWS |
1 |
Win9x 環境 |
VER_PLATFORM_WIN32_NT |
2 |
WinNT 環境 |
となっています(CE は、3らしいのですが、WindowsSDKのヘッダーに乗っていないので割愛)。
それでは、本題のOS判定。まずはサクッと9x系。といっても、いまさらなので、まぁこんな感じ...というところですかね。
一応、98SE だけは乗せてありますが、これ以外の判定方法として、szCSDVersion を使ったやり方もあるということだけ記載しておきます。
#こちらはぶれがあるので、お勧めできない方法ですけどねw
1: if( verInfo.dwMinorVersion < 10 ){
2: cout << "Windows 95";
3: cout << endl;
4: }
5: else if( verInfo.dwMinorVersion < 90 ){
6: cout << "Windows 98";
7: if( verInfo.dwMinorVersion > 10 || verInfo.dwBuildNumber > 1998 ){
8: cout << " SE";
9: }
10: cout << endl;
11: }
12: else{
13: cout << "Windows Me" << endl;
14: }
ActiveDesktop(岡山の勉強会で名前が出てましたね。さすが大野さんって感じでしたw)の判定とかはまた別の方法が必要ですので、ご注意をw
続いて、NT系。全部載せると膨大なので、2000 以降については、最新の MSDN ライブラリにゆだねることにします。Getting the System Version にサンプルコードがあるので参考にしてください。
ということで、最近のOSで一番段取りが面倒な、XP-x64 の判定コードだけ抜粋(ただし手抜き版)。
1: if( verInfo.dwMajorVersion == 5 && verInfo.dwMinorVersion == 2 && verInfo.wProductType == VER_NT_WORKSTATION ){
2: cout << "Windows XP x64 Edition";
3: }
本当は、上記判定の後、GetNativeSystemInfo でCPUアーキテクチャが、x64 かどうかを判定する必要があるんですが、5.2 なバージョンのワークステーションOSは、XP-x64 しか存在しないので、問題はないでしょうw
なお、NT4 は、dwMajorVersion == 4 の判定だけで判断がつきます。Server とかは別途チェックが必要ですけど、いまさら判定の必要がなんてほとんどないでしょうから、割愛します。