とっちゃん's Blog

WindowsInstaller に WiX はいかがですか~

目次

Blog 利用状況

ニュース

とっちゃんって?

コミュニティ

@ITの記事

CodeZineの記事

WiX チュートリアル

Windows ユーザー エクスペリエンス ガイドライン

唯一の日本語書籍

記事カテゴリ

書庫

日記カテゴリ

インストーラ関連

旧館

[Win32] 便利なAPI Part.2

ネタ元:初っ端から 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 とかは別途チェックが必要ですけど、いまさら判定の必要がなんてほとんどないでしょうから、割愛します。

投稿日時 : 2008年3月24日 16:00

コメントを追加

# re: [Win32] 便利なAPI Part.2 2008/03/24 16:10 シャノン

ご存知でしょうが、「特定のバージョン以降であるか?」というような判定を目的とする場合、VerifyVersion 関数が推奨されます。
これは Win2k 以降の関数なので、9x かどうかの判定には使えないわけですが、そろそろ 9x なんて捨てていいじゃん?

# re: [Win32] 便利なAPI Part.2 2008/03/24 16:10 シャノン

マチガエタ。VerifyVersionInfo です。

# re: [Win32] 便利なAPI Part.2 2008/03/24 16:39 とっちゃん

もちろん知ってますよw
このエントリーは、あくまでも現在のOSがなにか?の判断のためのものです。

ま、VerifyVersionInfo はあんまり使えるAPIともいい難いところがあるので...w
#特定バージョン以降で使えるAPIなら、GetProcAddressの成否で判定すればいいだけだしw

まぁ、一部のAPIでは、特定バージョン以降で追加のパラメータが使えるとかはありますけど...
その手の奴ってのは下位互換を維持しなきゃいけないことが多いのでそもそも呼び出し自体やらないことが大半だしwww

# re: [Win32] 便利なAPI Part.2 2008/04/11 11:46 くにゃくにゃ堂

GetVersionExでサーチしてたらたどり着きました^^;

と、いうのも・・・当方の環境では、Vista上でGetVersionExを使うと6.0が帰ってくる、とおもいきや5.1だったりするんですよね。
VistaをVMで動かしてる(ホストはXp)せいかもしれませんが
。ところがVerifyVersionInfoに6.0指定して呼ぶとちゃんとTRUEになるのです^^;

またVC.NETのデバッグ環境でデバッグ実行時にGetVersionExよぶと6.0がかえってきます。

VerifyVersionInfoって使い方がきれいじゃないので使いたくなかったのですが仕方なく・・・

# re: [Win32] 便利なAPI Part.2 2008/04/11 12:56 とっちゃん

>くにゃくにゃ堂さん

記事でも書いていますが、ACT(Microsoft Application Compatibility Toolkit)か、互換性タブで、OSをXP(=5.1)としているのが原因だと思います。

うちのソフト(市販製品)も、Vista出荷前のバージョンはこの設定がされていて、Vista特有の不具合を回避するために別のバージョンチェック方法をとっていたりしますしw

ちょっと古いですが、

http://www.microsoft.com/japan/msdn/windowsvista/compatibility/default.aspx

で互換性のことが書かれているので、参考にしてみてはいかがでしょうか。

# re: [Win32] 便利なAPI Part.2 2008/04/16 14:12 くにゃくにゃ堂

ずばり互換タブでした^^;
ありがとうございます。助かりました

タイトル
名前
URL
コメント