注意:セットアッププロジェクトはVisual Studio 2012からサポートされなくなりました。
VSのセットアッププロジェクト(デプロイメントプロジェクト)では、「ユーザーインターフェイスエディタ」を使用することにより、インストール時に表示されるウィザードダイアログのページを追加、削除、変更することができます。
ユーザーインターフェイスエディタを表示するには、ソリューションエクスプローラでセットアッププロジェクトを右クリックし、メニューの「表示」-「ユーザーインターフェイス」を選択してください。
ダイアログを追加するには、ダイアログを追加するセクションを右クリックし、メニューの「ダイアログの追加」を選択してください。セクションは「インストール」と「管理者インストール」の両方につき「開始」「進行状況」「終了」の3つに分かれていますが、それぞれに追加できるダイアログの種類は異なります。
ダイアログを追加した後は、ダイアログを適当な位置に移動します。ドラッグ&ドロップにより、ダイアログの位置を変更することができます。
追加できるダイアログの種類などについては、ヘルプの「インストール用ユーザー インターフェイス ダイアログ ボックス」や「配置のダイアログ ボックス」で詳しく説明されています。
この内幾つかを簡単に説明します。
ユーザーインターフェイスエディタの基本的な使い方はヘルプに任せるとして、以下にちょっとしたTipと具体例を紹介します。
BannerBitmapプロパティはダイアログの上部に表示する画像を指定するもので、ほとんどのダイアログに存在するプロパティです。BannerBitmapプロパティに指定する画像の大きさは、横500ピクセル、縦70ピクセルとすべきで、これ以外の大きさでは伸縮されて表示されます。また画像の左側420ピクセルはテキストによって隠れる可能性があります。
また、BannerBitmapプロパティで使用する画像はセットアッププロジェクトに追加されている必要がありますが、画像ファイルのExcludeプロパティをTrueにすることにより、画像ファイルを配置しないようにできます。
ダイアログの見た目がどのようになっているか、MSIファイルを実行することなく、Orcaの「Dialog Preview」を使って確認することができます。Orcaのメニュー「Tool」にある「Dialog Preview」を選択すれば、「Dialog Preview」ダイアログが表示され、ここで選択したダイアログを「Preview」ボタンをクリックして確認することができます。
「ユーザー情報」ダイアログを使うことにより、シリアル番号の入力をユーザーに要求し、入力されたシリアル番号が正しいかごく簡単な検証を行うことができます。
まず「ユーザー情報」ダイアログをユーザーインターフェイスエディタで「開始」セクションに追加します。
次に「ユーザー情報」ダイアログのプロパティを変更します。ここで変更するプロパティは、ShowSerialNumberとSerialNumberTemplateです。ShowSerialNumberをTrueとすることにより、シリアル番号の入力欄がダイアログに表示されるようになります。
どのようなシリアル番号が入力されれば正しいと判断するかを指定するのが、SerialNumberTemplateプロパティです。SerialNumberTemplateプロパティにはテンプレートを指定し、ここで使用できる文字とその意味については、次に示すヘルプのページが参考になります。
しかし私が実際に確かめたところでは、これらのMSDNに書かれていることと実際の動作には一部違いがありました。私が確認したSerialNumberTemplateプロパティで使用できる文字の意味を以下に示します。これらはあくまで私が確かめた結果ですので、絶対に正しいという保障はできません。なお「検査アルゴリズムに含まれる」というのは、シリアル番号が正しいか検証する判断材料として使用され、正しくなければインストールできない(次に進めない)という意味です。
文字 | 説明 |
---|---|
# | 検査アルゴリズムに含まれない数字の入力を必要とします。(数字以外は入力できなくなります。) |
% | 検査アルゴリズムに含まれる数字の入力を必要とします。すべての数字を足した数が7で割り切れれば正しいとされます。(数字以外は入力できなくなります。) |
? | 検査アルゴリズムに含まれない英数字の入力を必要とします。 |
^ | 検査アルゴリズムに含まれる英大文字の入力を必要とします。すべての文字が英大文字ならば正しいとされます。 |
& | 検査アルゴリズムに含まれる英字の入力を必要とします。すべての文字が英字ならば正しいとされます。 |
` | 検査アルゴリズムに含まれない英数字の入力を必要とします。 |
SerialNumberTemplateプロパティはデフォルトで「<###-%%%%%%%>」となっていますが、このときは、2つのテキストボックスと、その間に「-」が表示されます。はじめのテキストボックスには、3桁の数字が入力されてさえいれば正しいと判断されます(ただし数字しか入力できません)。2番目のテキストボックスには7桁の数字と、すべての数の合計が7で割り切れることが条件となります(例えば、「7777777」や「1111111」など)。
#や%を使ったときはユーザーが数字しか入力できなくなりますし、テキストボックスには指定された文字数以上の文字が入力できなくなります。よってユーザーが正しいシリアル番号を予想するのはごく簡単です。しかもこのテンプレートはMSIファイルのPropertyテーブル内のPIDTemplateにそのまま書き込まれますので、これを見ればどのようなシリアル番号を入力すればよいか分かってしまいます。
このようないい加減な方法でなく、しっかりした検証を行いたいのであれば、カスタムアクションを使うしかないでしょう。その一例が、マイクロソフトのサポート技術情報の「How To Validate a Serial Number During an Installation Created with VSI」にありますので、参考にしてください。
しかしインストーラだけでシリアル番号を確認するよりも、アプリケーション自身が確認するようにした方がよいのではないでしょうか。
「ユーザーの登録」ダイアログを使ってユーザー登録できるようにする簡単な例を紹介します。
まずはユーザー登録をするためのアプリケーションを作成します。このアプリケーションにより、起動時のコマンドライン引数により与えられたユーザー情報を登録します。
ここではHTTPのPOSTにより指定されたURL(ここでは「http://localhost/reg.cgi」)にユーザー情報を送信する次のようなアプリケーションを作成します。もちろん「http://localhost/reg.cgi」にPOSTされた情報を登録するためのCGIが用意されていることが前提です。かなりいい加減に作っていますので、参考程度にしてください。
[VB.NET] VB.NETのコードは現在準備中です。 Convert C# to VB.NET により、 下記のC#のコードをVB.NETに変換したものを参考にしてください。
using System; using System.Windows.Forms; namespace RegisterUser { public class RegisterUser { static void Main(string[] args) { System.Text.Encoding enc = System.Text.Encoding.GetEncoding("shift_jis"); string postData = ""; for (int i = 0; i < args.Length; i = i + 2) { postData += args[i] + "=" + System.Web.HttpUtility.UrlEncode(args[i + 1], enc) + "&"; } byte[] postDataBytes = System.Text.Encoding.ASCII.GetBytes(postData); System.Net.HttpWebRequest req = (System.Net.HttpWebRequest) System.Net.WebRequest.Create("http://localhost/reg.cgi"); req.Method = "POST"; req.ContentType = "application/x-www-form-urlencoded"; req.ContentLength = postDataBytes.Length; System.IO.Stream reqStream = req.GetRequestStream(); reqStream.Write(postDataBytes, 0, postDataBytes.Length); reqStream.Close(); System.Net.HttpWebResponse res = (System.Net.HttpWebResponse) req.GetResponse(); if (res.StatusCode == System.Net.HttpStatusCode.OK) { MessageBox.Show("登録しました。"); } else { MessageBox.Show("登録に失敗しました。"); } res.Close(); } } }
次にユーザーインターフェイスエディタで「開始」セクションに「ユーザー情報」ダイアログを、「終了」セクションの「完了」ダイアログの前に「ユーザー登録」ダイアログを追加します。
「ユーザー情報」ダイアログのプロパティは、適当で結構です。また「ユーザー登録」ダイアログのArgumentsプロパティを「USERNAME "[USERNAME]" COMPANYNAME "[COMPANYNAME]" PIDKEY "[PIDKEY]"」、Excutableプロパティを先ほど作成したアプリケーションとします。Argumentsプロパティで指定された[USERNAME]、[COMPANYNAME]、[PIDKEY]は「ユーザー情報」ダイアログで入力された名前、所属、シリアル番号に置き換わります。
これで「ユーザー登録」ダイアログの「今すぐ登録」ボタンがクリックされたときにアプリケーションが起動し、ユーザー登録が行われるようになります。
ここでは、「オプションボタン」ダイアログを使った簡単な例を示します。
アプリケーションをインストールする際、ユーザーが完全インストールか最小インストールかを選択できるインストーラをよく見ますが、このようなインストーラを作成する方法を紹介します。(「カスタムインストール」は残念ながらVSだけでは無理といってよいでしょう。)
まずユーザーインターフェイスエディタで「開始」セクションに「オプションボタン(2ボタン)」ダイアログを追加します。
次にダイアログのプロパティを設定します。ここでは次のようにプロパティを設定します。
プロパティ | 値 |
---|---|
BannerText | インストールの種類 |
BodyText | インストールの種類を選択してください。 |
Button1Label | 完全インストール(すべてのファイルをインストールします。) |
Button1Value | 1 |
Button2Label | 最小インストール(最低限のファイルのみをインストールします。) |
Button2Value | 2 |
ButtonProperty | BUTTON2 |
DefaultValue | 1 |
次に最小インストールではインストールされず、完全インストールでのみインストールするファイルのConditionプロパティを「BUTTON2=1」に設定します。「BUTTON2」はButtonPropertyプロパティを、「1」は1番目のオプションボタンが選択されたことを示します。これで、1番目のオプションボタンが選択されたときにのみこれらのファイルが配置されるようになります。
補足:Windows Installerでは通常上記のような目的のためにはFeatureテーブルを使用しますが、残念ながらVSではFeatureテーブルを扱う方法が用意されていません。
次に「チェックボックス」ダイアログを使った例を紹介します。ここでは、デスクトップにショートカットを作成するかユーザーが選べるようにする方法を紹介します。
まずユーザーインターフェイスエディタで「開始」セクションに「チェックボックス」ダイアログを追加します。(A)(B)(C)はすべて同じですので、どれを追加してもかまいません。
次に「チェックボックス」ダイアログのプロパティを設定します。ここでは次の箇所をデフォルトから変更しました。
プロパティ | 値 |
---|---|
BannerText | オプション |
BodyText | オプションを選択してください。 |
Checkbox1Label | デスクトップにショートカットを作成する |
Checkbox1Property | CHECKBOXA1 |
Checkbox1Value | Checked |
Checkbox1Visible | True |
Checkbox2Visible Checkbox3Visible Checkbox4Visible | False |
これでユーザーが「デスクトップにショートカットを作成する」を選択したときにCHECKBOXA1プロパティが1となります。
後はCHECKBOXA1プロパティが1の時にデスクトップにショートカットを作成するだけですが、これが意外と難しいです。セットアッププロジェクトの「ファイルシステムエディタ」で「ユーザーのデスクトップ」にアプリケーションのショートカットを作成するように設定したとしても、ショートカットのプロパティにはConditionプロパティがありませんし、「ユーザーのデスクトップ」のConditionプロパティに「CHECKBOXA1=1」と記述しても常にショートカットが作成されてしまいます。
これを解決する方法として、2つ紹介します。
まず、セットアッププロジェクトにファイルを2つ追加する方法です。例えば「app.exe」へのショートカットをデスクトップに作成するかユーザーに選択させる場合は、セットアッププロジェクトに「app.exe」を2つ追加します。そして片方のConditionプロパティを「CHECKBOXA1=1」とし、こちらのファイルへのショートカットを「ファイルシステムエディタ」でデスクトップに作成するようにします。ただしこの方法は同じファイルを2回追加するため、MSIファイルのサイズがそれだけ無駄に大きくなります。
もう一つの方法は、カスタムアクションでショートカットを作成する方法です。この方法も簡単に紹介しておきましょう。
まずカスタムアクションとして実行する次のようなVBScriptを用意します。
dim arg, args, desktop, WshShell, WshShortcut 'CustomActionDataを分解 arg = Session.Property("CustomActionData") args = Split(arg, ":::") if args(2)="1" then set WshShell = CreateObject("WScript.Shell") 'デスクトップのパスを取得 if args(3)="1" then desktop = WshShell.SpecialFolders("AllUsersDesktop") else desktop = WshShell.SpecialFolders("Desktop") end if 'ショートカットを作成 On Error Resume Next set WshShortcut = _ WshShell.CreateShortcut(desktop & "\" & args(1) & ".lnk") WshShortcut.TargetPath = args(0) WshShortcut.Save end if
これを「カスタム動作」の「インストール」に追加し、CustomActionDataプロパティを
[TARGETDIR]app.exe:::アプリケーション:::[CHECKBOXA1]:::[ALLUSERS]
とします。ここで「app.exe」はショートカットのリンク先のファイル名、「アプリケーション」はショートカットの名前とします。
次にショートカットを削除するためのカスタムアクションを作成します。
dim arg, args, desktop, path, WshShell, fso 'CustomActionDataを分解 arg = Session.Property("CustomActionData") args = Split(arg, ":::") 'デスクトップのパスを取得 set WshShell = CreateObject("WScript.Shell") if args(1)="1" then desktop = WshShell.SpecialFolders("AllUsersDesktop") else desktop = WshShell.SpecialFolders("Desktop") end if '削除するファイルのパス path = desktop & "\" & args(0) & ".lnk" 'ショートカットを削除 set fso = CreateObject("Scripting.FileSystemObject") if (fso.FileExists(path)) then On Error Resume Next fso.DeleteFile(path) end if
これを「カスタム動作」の「アンインストール」と「ロールバック」に追加し、それぞれのCustomActionDataプロパティを
アプリケーション:::[ALLUSERS]
のようにします。「アプリケーション」は「インストール」で指定したショートカットの名前と同じにしてください。
以上で終了です。
「チェックボックス」ダイアログを使った例をもう一つ紹介します。インストール終了後にインストールしたアプリケーションを起動するかユーザーが選択できるようにします。同様の方法でインストール終了後にREADMEを表示させることも可能です。
まずはVSのみを使って作成してみますが、はじめに言ってしまうと、かなり妥協の産物となってしまいます。
まずはユーザーが選択できるように、ユーザーインターフェイスエディタで「チェックボックス」ダイアログを「開始」セクションに作成します。本来ならこのダイアログは最後に表示したいので「終了」セクションに置きたいところですが、それではカスタムアクションの実行後にダイアログが表示されることになるため、仕方がありません。
「チェックボックス」ダイアログのプロパティは次のようにします。
プロパティ | 値 |
---|---|
BannerText | アプリケーションの起動 |
BodyText | インストールしたアプリケーションを起動するか選択してください。 |
Checkbox1Label | インストールしたアプリケーションをインストール終了後に起動する |
Checkbox1Property | CHECKBOXA1 |
Checkbox1Value | Checked |
Checkbox1Visible | True |
Checkbox2Visible Checkbox3Visible Checkbox4Visible | False |
次にカスタムアクションを作成します。ここでは次のようなVBScriptを作成し、ファイルに保存します。
dim arg, args, WshShell arg = Session.Property("CustomActionData") args = Split(arg, ":::") if args(1)="1" then set WshShell = CreateObject("WScript.Shell") WshShell.Run """" & args(0) & """" end if
このカスタムアクションを「カスタム動作」の「インストール」に追加し、CustomActionDataプロパティを「[TARGETDIR]app.exe:::[CHECKBOXA1]」とします。
これでビルドすれば、終了です。ただし、カスタムアクションが実行されるタイミングが「完了」ダイアログが表示される前になりますので、アプリケーションが起動してもインストーラのダイアログは残ってしまうという問題があります。
次に、改良した方法を紹介します。アプリケーションの起動を問うダイアログを「終了」セクションに持ってきて、「完了」ダイアログの「閉じる」ボタンがクリックされた時にアプリケーションが起動するようにします。これには、ある程度のWindows Installerの知識が必要ですので、分かる方のみ参考にしてください。
まずユーザーインターフェイスエディタで「チェックボックス」ダイアログを「完了」セクションに作成します。プロパティは先ほどと同じとします。
次にアプリケーションを起動するためのカスタムアクションを作成します。ここでは次のようなVBScriptを作成し、「LauncherApp.vbs」として保存します。
dim WshShell if Session.Property("CHECKBOXA1") then set WshShell = CreateObject("WScript.Shell") WshShell.Run """" & Session.Property("TARGETDIR") & "app.exe""" end if
この「LauncherApp.vbs」をセットアッププロジェクトに追加し、アプリケーションフォルダに配置されるようにします。
さてここでプロジェクトをビルドし、作成されたMSIファイルをOrcaで開きます。
まずはCustomActionテーブルにカスタムアクションを追加します。そのためにFileテーブルを開いて「LauncherApp.vbs」(FileName列)のID(File列)を探します。ここでは「_1CD4536303AE460B8EA1AAEEC78DE0F3」であったとします。
次にCustomActionテーブルを表示し、次のような新しい列を追加します。
なおインストールされたVBScript以外のカスタムアクションを使う場合に指定するTypeについては、「Summary List of All Custom Action Types」をご覧ください。
最後に「完了」ダイアログの「閉じる」ボタンのイベントを設定します。ControlEventテーブルを開き、次のような新しい列を追加します。ここでFinishedFormは「完了」ダイアログを、CloseButtonは「閉じる」ボタンを意味していますので、これらが違う場合は適当に変更してください。
ただし、Dialog_が「FinishedForm」、Control_が「CloseButton」、Eventが「EndDialog」の列がすでに登録されており、Orderingが「0」になっていると思いますので、このOrderingを「1」に変更しておいてください。
これで保存すれば完了です。
補足:Conditionを「CHECKBOXA1=1」とし、カスタムアクションではアプリケーションを起動するだけとすることもできます。
補足:ここではカスタムアクションとしてアプリケーションを起動するスクリプトを使用しましたが、カスタムアクションにアプリケーションの実行ファイルを指定して起動することもできます。ただしこの時はmsidbCustomActionTypeAsync + msidbCustomActionTypeContinueオプションをつけて非同期で呼び出す必要があります。
「テキストボックス」ダイアログを使ってユーザーにパスワードを入力してもらうときなど、テキストボックスに入力された文字がそのまま表示されては困るというケースもあるでしょう。このような場合、テキストボックスに入力された文字を*で隠すように設定することができますが、これはVSだけでは無理で、Orcaを使わなければなりません。
ここでは、ユーザーインターフェイスエディタで追加された「テキストボックス」ダイアログの一番目のテキストボックスをパスワード入力用とし、入力された文字が表示されないようにします。
まずはOrcaでMSIファイルを開き、Controlテーブルを表示し、この中から対象となるテキストボックスを探します。ここでは、Dialog_列が「CustomTextA」で「Control」列が「Edit1」の行がそれです。
次にこのコントロールのAttributesにmsidbControlAttributesPasswordInputを追加します。具体的には、Attributes列にある数字に2097152を足した数を新しい値とします。通常は、2097159となるでしょう。
これで保存すれば終了です。
(この記事は、「.NETプログラミング研究」の第58号で紹介したものを基にしています。)