Lesson 3 イベントとアクション

3. 本に書かれていないこと

Windows Installer が解決方法を提供してくれない非常に特殊なアクション (例えば、ユーザーが入力した登録キーの妥当性と整合性をチェックすること) に対しては、もう一つ別のタイプのカスタム・アクションを使うことが出来ます。 すなわち、私たちが書く DLL です。 ここでは、例として、ユーザー・キーの最初の数字が ‘1’ であれば承認する、という極めて安直な手法を使います。

以下のソースは Visual C++ ではそのままコンパイル出来ます。 別のコンパイラでコンパイルする場合でも、必要な修正は、(有るとしても)ほんの少しでしょう。 ヘッダ・ファイル、msi.hmsiquery.h は、MSI SDK から取得できます。更に msi.lib もリンクする必要があります。

#include <windows.h>
#include <msi.h>
#include <msiquery.h>

#pragma comment(linker, "/EXPORT:CheckPID=_CheckPID@4")

extern "C" UINT __stdcall CheckPID (MSIHANDLE hInstall) {
  char Pid[MAX_PATH];
  DWORD PidLen = MAX_PATH;

  MsiGetProperty(hInstall, "PIDKEY", Pid, &PidLen);
  MsiSetProperty(hInstall, "PIDACCEPTED", Pid[0] == '1' ? "1" : "0");
  return ERROR_SUCCESS;
}

この DLL を使うために、下記の数行を適切な場所に追加します (今や、三回目のレッスンの終り近くですから、これぐらいは自分で出来るでしょうが、 ずるをしたい場合は、SampleCA をダウンロードして下さい)。

訳註:SampleCA の日本語版は Sample-3-3-CA.zip です。

<Condition Message='このインストーラは完全 UI モードでのみ実行出来ます。'>
  <![CDATA[UILevel = 5]]>
</Condition>

<CustomAction Id='CheckingPID' BinaryKey='CheckPID'
    DllEntry='CheckPID' />
<CustomAction Id='RefusePID'
    Error='無効なキーです。インストールを中止します。' />

<InstallExecuteSequence>
  <Custom Action='CheckingPID' After='CostFinalize' />
  <Custom Action='RefusePID' After='CheckingPID'>
    PIDACCEPTED = "0" AND NOT Installed
  </Custom>
</InstallExecuteSequence>

<Binary Id='CheckPID' SourceFile='CheckPID.dll' />

簡単に説明します。最初に、私たちはこのインストーラが簡易 UI モードや UI 無しのモードで走ることを許可しません。 なぜなら、それらのモードでは、ユーザーが登録キーを入力することが出来ないからです。 醜い CDATA ラッパーを使っている理由は、XML がいくつかの文字、とりわけ ”<””>” に特別な意味を与えているからです。 これらの文字が、より小さいより大きい を意味する別の文脈で出現する場合には、 常に、式全体を CDATA に入れてエスケープしなければなりません。 この実例の場合は、等価であることをチェックしているだけなので、エスケープしなくても済みます。 しかし、このような条件式をすべて CDATA で包むようにするのは、良い習慣です。 そうしておけば、万一、後で条件を修正する必要があっても、そういう XML の衝突を招かずに済みます。

次に、CheckingPID という名前のカスタム・アクションを CostFinalize の後に走らせます。 すなわち、どの機能が必要で、どこにインストールしたいかを決定した後、インストーラに実際のインストールを開始するように指示する時です。 このカスタム・アクションは、インストーラに同梱されている CheckPID.dllCheckPID という関数を呼び出します。 DLL は、関連するコントロールによって入力されて PIDKEY プロパティに保存されているユーザー・キーの正当性を判断して、 PIDACCEPTED プロパティを 1 または 0 に設定します。 カスタム・アクションとの間で引数を渡したり戻り値を受け取ったりするためには、 プロパティを使うしか方法がないということを覚えておいて下さい。 また、そのプロパティの名前はすべて大文字でなければなりません。 そうでないと、Windows Installer はそのプロパティを public なものとは見なしません。

そして、RefusePID という名前の第二のカスタム・アクションを第一のアクションの後に走らせるように予定します。 これは条件付きのカスタム・アクションで、戻り値の PIDACCEPTED プロパティがゼロであった場合にだけ走らせます。 その場合、このカスタム・アクションはエラー・メッセージを表示して、インストールを中止します。 ただし、私たちが PIDACCEPTED の値に関心を持つのは、インストールの時だけです。 製品をアンインストールする場合には、PIDACCEPTED の値を問題にしません。

これらのアクションがどのように呼び出され、お互いにどのように関係しているのかを理解するためには、 詳細ロギングを有効にしてインストーラを走らせてみるのが良いでしょう。 ログは本当に詳細なものになりますから、実際に起っている事を記録している箇所を探すためには、 テキスト・エディタを使って、プロパティやカスタム・アクションの名前(“PID”でも大丈夫です)を検索するのが良いでしょう。

msiexec /i SampleCA.msi /l*v SampleCA.log

呼び出す必要がある DLL が単にパッケージに含まれているのではなくて、インストールされている場合は、次のように記述することが出来ます。

<CustomAction Id='CheckingPID' FileKey='HelperDLL'
    DllEntry='CheckPID' />

↑ 先頭  |  • 目次  |  « 前へ  |  次へ »  |  ∗ 原文

Table of Contents

1 始めよう

  1. ソフトウェア・パッケージ
  2. 中に入るファイル
  3. 使用に供する
  4. 便利な追加機能
  5. どこにインストールするか
  6. 条件付きインストール
  7. ファイルだけでなく
  8. 削除時の孤児化

2 ユーザー・インタフェイス

  1. 最初のステップ
  2. カスタムの設定
  3. UI の魔法
  4. 英語はわかりますか
  5. チェーンの新しい環
  6. 地域化を考える

3 イベントとアクション

  1. 列に並んで
  2. 追加のアクション
  3. 本に書かれていないこと
  4. コントロールをコントロールせよ
  5. マネージする方法
  6. 後の段階で

4 アップグレードとモジュラー化

  1. 古いのを探す
  2. 自分自身を置き換える
  3. パッチワーク
  4. 断片
  5. 融合するもの

5 Net と .NET

  1. .NET の枠組み
  2. ブートストラップ
  3. インターネットを起動する
  4. ウェブ・ディレクトリ
  5. サービスの提供

6 COM、式の構文、その他

  1. 違う色のコンポーネント
  2. 式の構文
  3. 書式指定文字列
  4. DDE 接続
  5. ディレクトリの作成
  6. 複数メディアのインストーラ
  7. プログラムの追加と削除の項目
  8. 新顔のユーザー
  9. 環境に優しく
  10. XML
  11. COM+ アプリケーション
  12. バージョンごとに

7 SQL

  1. データベースを作成する

8 ユーザー・インタフェイス再び

  1. 一つだけのダイアログ
  2. チューニング・アップ
  3. 相互作用
  4. カスタマイズがいっぱい
  5. これが進捗ですか
  6. よく出来ました
  7. 法律用語
  8. 順番外
  9. 英語はわかりませんか

9 トランスフォーム

  1. インストーラを変形する

10 標準ライブラリ

  1. カスタム・アクションとユーザー・インタフェイス
  2. お静かに願います