8月になりました。毎日、暑いですね~。この暑さでジョギングもすっかり、ご無沙汰です。
先日、散歩していたところ、あることに気が付きました。ガソリン高騰の影響だと思うのですが、道を走っている車が
気のせいか少なくなったように思います。ガソリン高騰、一体、どうなるんでしょう。
さて、話題を変えて、今回は Windows Installer に関係するネタです。
少し前に Windows Installer 4.5 がリリースされましたが、
Windows Vista / 2008 では、Windows Installer 4.0 が標準バンドルされており、
MSI のスキーマは 400 にすることが推奨されています。(最低でも、301)インストーラーはユーザーに対して一番最初に見せるプログラムであり、失敗することは許されません。
インストーラーでエラーになったら、それだけで使うのが嫌になってしまいますよね。
できれば、これくらいで抑えておきたいものです。
MSI 作成に限らず、インスールパッケージを作成する際、インストールパッケージ自体にあまり多くの機能を
入れ込まず、可能な限り、外出しのプログラム(セットアップやライブラリ化)にしておくのがよい実装です。
ただ、どうしても、MSI パッケージ内に独自の処理を入れなければならない場合もあります。
この場合は、カスタムアクション を用意することになります。
カスタムアクションとは、ユーザー定義のインストール動作です。
これは、標準動作では足りない部分を補うことができるように用意されているものです。
例えば、外部の EXE や DLL を実行したり、VBScript、JScript などのスクリプトを実行することもできます。
では、Windows Vista / 2008 で管理者権限のカスタムアクションを実装する際のポイントを解説します。
まず、カスタムアクションを使うために必ず知っておかなければならないことがあります。
- カスタムアクションの種類
- カスタムアクションがどのようなアーキテクチャで動作しているのか
- カスタムアクションの実装方法
では、まずは (1) から解説します。Windows Installer で用意されているカスタムアクションは、以下のものがあります。
この一覧は非常に重要なもので、カスタムアクションを実装する際には必ず参照すると思います。
この Custom Action Types 一覧では、どのような Custom Action Type があるのかをじっくりと読んでおいてください。
例えば、Custom Action Type 1 はバイナリテーブルに格納した DLL をカスタムアクションで
使用することです。同様に Custom Action Type 2 は、DLL ではなく EXE を使用することです。
余談ですが、最新の Windows Installer 4.5 ではカスタムアクションに .NET で作成したマネージコードの
DLL や EXE を実行することもできます。
では、カスタムアクションはどのようなアーキテクチャで動作しているのでしょう。
(2) を解説していきます。
Windows Installer は、クライアント/サーバー型のサービスプログラムであると、以前 (Windows Installer その1) に
記載しました。 Windows Installer がカスタムアクションを実行する際、カスタムアクション用にクライアントプロセスの
msiexec.exe をもう一つ起動します。
つまり、
————————————————————————–
msiexec.exe (サーバープロセス:Local System)
↓ プロセス起動
msiexec.exe (クライアントプロセス:管理者権限 or 各ユーザー権限)
→ カスタムアクション用の msiexec.exe (クライアントプロセス:各ユーザー権限)
————————————————————————–
という構造をとります。
例えば、カスタムアクションには DLL を実行する機能があります。その DLL をホストする EXE が必要になりますよね。
そこで、クライアントプロセス用の msiexec.exe を使ってもいいのですが、それでは、クライアントプロセス用の
msiexec.exe が止まってしまいます(メッセージループが止まる)。スレッドにしてもいいのですが、それでは複雑になり
エラー要因が増えてしまいます。何よりも DLL に問題が起った際には、クライアントプロセス用の msiexec.exe 自体が
落ちてしまいます。これでは信頼性を保つことはできません。
カスタムアクション用の msiexec.exe が動作しているかどうかは、タスクマネージャーでも確認できます。
ただ、msiexec.exe が複数起動しているので、識別するのは困難ですけど。
カスタムアクションの種類とアーキテクチャを理解したら、いよいよ (3) の実装です。
これを説明するために、以下をサンプルシナリオにします。ただし、簡単に説明するためにエラー時のロールバックは無視します。
(シナリオ)
- Windows Vista 用の MSI パッケージを作成する。Vista 専用であるため、スキーマは 400 を指定する。
- 標準アクションで不足する部分をカスタムアクションにて実装する。カスタムアクションは
DLL(MyExpt.dll) を呼び出すことで動作させる。使用する DLL の関数名は MyDataApi() とする。
なお、MyDataApi() の実行は管理者権限でなければならない。
- スクリプト内実行は、即時実行とする。
- 実行スケジュールは、1 プロセスにつき、1 回実行とする。
- 戻り値の処理は、終了コードを確認して同期処理を行う。
- カスタムアクションのシーケンス名は MYDATA と定義する。
このシナリオでは、カスタムアクションを DLL で実装するとありますので
Custom Action Types 一覧から、Custom Action Type 1 になることがわかります。
そして、Type が 1 であることを覚えておいてください。
つぎに、Custom Action Reference から Custom Action In-Script Execution Options を参照します。
スクリプト内実行は、即時実行とするので、表から、0 であることがわかります。
そして、DLL を管理者権限で実行する必要があるので、msidbCustomActionTypeNoImpersonate も指定することになります。
先ほど、アーキテクチャを説明しましたが、Windows Vista では以下のようになります。(Windows Server 2008 も同じ)
————————————————————————–
msiexec.exe (サーバープロセス:Trusted Installer)
↓ プロセス起動
msiexec.exe (クライアントプロセス:管理者権限(PA) or 各ユーザー権限(LUA))
→ カスタムアクション用の msiexec.exe (クライアントプロセス:各ユーザー権限(LUA))
PA:Privileged Administrator
LUA:Least-privilege User Access
————————————————————————–
上記を見ると、カスタムアクション用の msiexec.exe が LUA で動作することがわかります。
つまり、MSI に管理者権限が必要だという設定を行い、msiexec.exe の起動時に UAC により管理者権限に
昇格しても、カスタムアクション用の msiexec.exe は LUA(中 IL)で動作してしまうのです。
そのため、PA にならず、クライアントプロセス用の msiexec.exe と同じ権限で動作するように
msidbCustomActionTypeNoImpersonate を指定するわけです。
続いて、実行スケジュールですが、1 プロセスにつき、1 回実行としたので、
msidbCustomActionTypeOncePerProcess を指定します。最後に、戻り値の処理は、終了コードを確認して同期処理を行うとしたので、0 を指定します。以上より、今回のシナリオでは、Custom Action In-Script Execution Options
: 即時実行(0)
: msidbCustomActionTypeNoImpersonate(0x00000800)Custom Action Execution Scheduling Options
: msidbCustomActionTypeOncePerProcess(0x00000200)Custom Action Return Processing Options
: 同期実行(0)が必要なオプションになります。これらの数値を加えて、0 + 0x00000800 + 0x00000200 + 0 = A00
10進数に変換すると、2560 になります。最後に、Custom Action Type 1 の Type は 「1」 であるため、2560 に 1 を加えて 2561 になります。
あとは、この 2561 を CustomAction Table で該当する カスタムアクション の Type に指定すれば完了です。
つまり、CustomAction Table には
Action |
MYDATA |
Type |
2561 |
Source |
MyExpt.dll |
Target |
MyDataApi |
という定義を行うことで、実装完了です。
今回の例を応用して、管理者権限が必要なカスタムアクションを実装してください。ただ、初めにもお話しましたが、可能な限りカスタムアクションは使わない方がいいものです。
複雑なものを作りこめば、その分、エラーは発生しやすくなります。
プログラムは、 Simple is best !! です。それでは、今回はこの辺で。