ダイアログを用意する
それでは本題です。インストーラの画面遷移にユーザー情報を入力する画面を追加してみましょう。
まず、Mondoにユーザー情報入力画面を用意します。Officeなどにもあるように、ユーザー名、会社名、シリアル番号を入れるダイアログです。画面構成はフルスクラッチで作成してもよいのですが、どこにでもあるダイアログをイチから作り直すというのもなんとなく釈然としません。ここでは、ベースとして既にあるものを活用させてもらうことにしましょう。都合のよいことに、Platform SDKのサンプルにユーザー情報入力画面が用意されています。今回はこれを使います。
WiX用のソースを用意する
Platform SDKのサンプルは、msiファイルになっているので、そのままではWiXで利用することができません。msiのテーブルを見て、ちまちまとダイアログを起こすという手法もないわけではありませんが、あまりにも効率が悪すぎます。WiXには、msiをデコンパイルしてwxsファイルを生成する「dark」というツールが用意されています。それを使って一気に変換してしまいましょう。
また、darkにはちょっとした癖があります。どうやらフォルダ名に空白文字がある場合もNGになるようです。これは、きちんと調査できていないのですが、サンプルのフォルダにあるものをそのまま使おうとしたら、エラーになってしまったので、おそらくパラメータ解析のどこかに不都合があると思われます。
とはいえ、これらの問題は運用で回避できる程度のものなので、臨機応変に対応していきましょう。
msiファイルをwxsファイルに変換する
では、さっそく作業に入ります。変換作業は以下の手順に従って実行してください。Platform SDKのインストーラはマイクロソフトのWebページからダウンロードできます。なお下記の手順では、インストール先はデフォルトの「C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2」、バージョンは「March 2006」を前提としています。また、作業用フォルダとして「C:\Work」を使います(作業用フォルダは、空白文字を含まないフォルダならどこでも可)。
- エクスプローラなどで、「C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Samples\SysMgmt\Msi\database」に移動。
- 「UISample.msi」を「C:\Work」にコピー。
- コマンドプロンプトを開き、「C:\Work」に移動
- コマンドプロンプトで「dark /ui UISample.msi UISample.wxs」を実行。
以上です。これで「C:\Work」に、「UISample.wxs」というファイルができます(デコンパイルしたファイルは、サンプルに同梱しています)。
変換したソースをSTEditのインストーラへ組み込む
次に、変換したソースから必要な部分だけを取り出してきて、STEditのインストーラへ組み込みます。UISample
にあるユーザー情報入力画面は、UserRegistrationDlg
というダイアログです。せっかくなので、実際の画面イメージ(ORCAでプレビューしたもの)とダイアログのソース(抜粋)を載せておきます。
![UserRegistrationDlgの画面イメージ UserRegistrationDlgの画面イメージ](http://cz-cdn.shoeisha.jp/static/images/article/632/UserRegistrationDlg.gif)
<Dialog Id="UserRegistrationDlg" Width="370" Height="270" Title="[ProductName] [Setup]" NoMinimize="yes"> <Control Id="NameLabel" Type="Text" X="45" Y="73" Width="100" Height="15" TabSkip="no" Text="&User Name:" /> <Control Id="NameEdit" Type="Edit" X="45" Y="85" Width="220" Height="18" Property="USERNAME" Text="{80}" /> <Control Id="OrganizationLabel" Type="Text" X="45" Y="110" Width="100" Height="15" TabSkip="no" Text="&Organization:" /> <Control Id="OrganizationEdit" Type="Edit" X="45" Y="122" Width="220" Height="18" Property="COMPANYNAME" Text="{80}" /> <Control Id="CDKeyLabel" Type="Text" X="45" Y="147" Width="50" Height="10" TabSkip="no"> <Text><![CDATA[CD &Key:]]></Text> </Control> <Control Id="CDKeyEdit" Type="MaskedEdit" X="45" Y="159" Width="250" Height="16" Property="PIDKEY" Text="[PIDTemplate]" /> <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="[ButtonText_Back]"> <Publish Event="NewDialog" Value="LicenseAgreementDlg"> <![CDATA[1]]></Publish> </Control> <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="[ButtonText_Next]"> <Publish Event="ValidateProductID" Value="0"><![CDATA[0]]></Publish> <Publish Event="SpawnWaitDialog" Value="WaitForCostingDlg"> <![CDATA[CostingComplete = 1]]></Publish> <Publish Event="NewDialog" Value="SetupTypeDlg"> <![CDATA[ProductID]]></Publish> </Control> <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="[ButtonText_Cancel]"> <Publish Event="SpawnDialog" Value="CancelDlg"> <![CDATA[1]]></Publish> </Control> <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="374" Height="44" TabSkip="no" Text="[BannerBitmap]" /> <Control Id="BannerLine" Type="Line" X="0" Y="44" Width="374" Height="0" /> <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="374" Height="0" /> <Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes"> <Text><![CDATA[Please enter your customer information]]></Text> </Control> <Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes"> <Text><![CDATA[[DlgTitleFont]Customer Information]]></Text> </Control> </Dialog>
ダイアログボックスはこのように、ダイアログタグの中に各コントロールとその実行コードに当たるデータが含まれています(このダイアログでは、Back
/Next
/Cancel
に、実行コードに当たるPublish
があります)。巷で話題のXAMLと同じようにXMLで構成されていますが、XAMLとは文法その他すべて異なりますので混同しないようにしてください。
残念ながらこのソースは、WiXのUIとは異なる構成になっているため、そのままでは利用することができません。若干(といっても、本当にごく一部)の修正を施す必要があります。具体的には、表示に関する部分と、遷移イベントの設定方法です。表示に関しては、外部リソースに切り出すのが望ましいのですが、いささか面倒なので今回は埋め込み文字列とします。
シリアル番号の検証機能を組み込む
ユーザー情報入力画面を組み込んで、体裁を整えたものが「STEdit8.wxs」です。こちらはダイアログの組み込みだけではなく、シリアル番号検証機能の組み込みも追加しています。Windows Installerでは、実装仕様のひとつとして、画面を表示しないサイレントインストールへの対応が必須となっています。そのため、シリアル検証はUI上だけではなく、実行時にも行う必要があります。こちらはわずか3行なので、ソースを紹介しておきましょう。
<InstallExecuteSequence> <ValidateProductID> </InstallExecuteSequence>
これで、自動的に規定の位置に検証ルーチンが組み込まれました。
シリアル番号の構成を決定する
動作ロジックの組み込みができたので、次は対象となるシリアル番号の構成を決定します。この部分は製品依存部分であり、製品ごとにいろいろな設定方法が設けられています。Microsoft製品の古いものでは、シリアル番号は3桁+7桁の数字の組み合わせでしたが、最近は5x5の25桁の英数字の組み合わせになっているなど、ひとつのメーカーでもさまざまな構成が用意されています。
とはいえWindows Installerが標準で用意している検証ルーチンは非常に限られた組み合わせでしかないため、メーカー独自のシリアル番号の規則に従うことはできません。といって最初から独自の処理を組み入れるのも大変なので、まずは標準の仕組みを明らかにしておきたいと思います。
Windows Installerの標準の仕様
先ほどのダイアログでも利用していますが、多くのアプリケーションがシリアル番号の入力にMaskedEdit
というコントロールを利用しています。このコントロールは与えられたテンプレートテキストをもとに、入力エディットを動的に組み上げるという構造になっています。そのため、独自検証を行うのか、標準検証を行うのかに関係なく入力の際に使われます。MSDNライブラリに、この書式が抜粋表記されていたので、その表を引用しておきます。
文字 | 説明 |
# | 検証アルゴリズムに含まれない数字の入力。 |
% | 検証アルゴリズムに含まれる数字の入力。 |
? | 検証アルゴリズムに含まれない英数字の入力。 |
^ | 英大文字または小文字の入力。 |
< | 入力対象フォーマットの開始文字。 |
> | 入力対象フォーマットの終了文字。 |
このほかに、セパレータキャラクタとして「=」や「-」などがありますが、実際のところ、標準ルーチンで検査対象とする部分は上記の「%」の箇所だけになります。これらについてはMSDNライブラリに、この表を含めて検証手段を解説している箇所があるのでそちらを参照してください。
- MSDNライブラリ 『SerialNumberTemplateプロパティ』
なお、今回は「UISample.msi」で最初から定義されていた、「12345<###-%%%%%%%>@@@@@」をマスク文字列としています。
PIDTemplate
、ユーザーが入力するデータがPIDKEY
、検証結果の出力先がProductID
と、決まったプロパティを利用しています。インストーラでは、入力させたい形式をPIDTemplate
に入れておき、MaskedEdit
コントロールのテキストに[PIDTemplate]
を指定することで、マスク入力を実現しています(パスワードマスクではないため、入力形式が制限されるだけという点に注意してください)。また、入力結果を受け取るプロパティの指定を
PIDKEY
としない限り、検証ルーチンが有効に働かない点も注意が必要です。多くの独自形式の検証ルーチンでも上記のプロパティをそのまま流用しているものが多数ありますので、独自ルーチンを構築する際の参考にできると思います。動作確認
以上で、画面遷移の変更作業は終了です。確認のため実際に動かしてみましょう。シリアル番号は「123-1234567」となっています。インストールで先に進めるでしょうか? 違う値を入れた場合の動作についても確認してみてください。
また、今回はプログラム側も修正を行い、アプリケーションの情報を表示するアバウトダイアログで、シリアル番号を表示できるようにしています。このようにインストーラの機能とアプリケーション側の機能をうまく融合することで、独自にデータ保持を行うことなく、情報を吸い上げることができるのも、Windows Installerの利点のひとつと言えます。