DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

ユーザーインターフェイスエディタの使い方

注意:セットアッププロジェクトはVisual Studio 2012からサポートされなくなりました。

VSのセットアッププロジェクト(デプロイメントプロジェクト)では、「ユーザーインターフェイスエディタ」を使用することにより、インストール時に表示されるウィザードダイアログのページを追加、削除、変更することができます。

ユーザーインターフェイスエディタを表示するには、ソリューションエクスプローラでセットアッププロジェクトを右クリックし、メニューの「表示」-「ユーザーインターフェイス」を選択してください。

ダイアログを追加するには、ダイアログを追加するセクションを右クリックし、メニューの「ダイアログの追加」を選択してください。セクションは「インストール」と「管理者インストール」の両方につき「開始」「進行状況」「終了」の3つに分かれていますが、それぞれに追加できるダイアログの種類は異なります。

ダイアログを追加した後は、ダイアログを適当な位置に移動します。ドラッグ&ドロップにより、ダイアログの位置を変更することができます。

追加できるダイアログの種類などについては、ヘルプの「インストール用ユーザー インターフェイス ダイアログ ボックス」や「配置のダイアログ ボックス」で詳しく説明されています。

この内幾つかを簡単に説明します。

インストールフォルダ
インストール先のフォルダをユーザーが選択できるようにします。選択されたフォルダは、Windows InstallerのTARGETDIRプロパティに格納されます。通常このダイアログは「開始」セクションの最後か、「インストールの確認」ダイアログの前に置かれます。Web Setupプロジェクト以外で使用できます。
インストールアドレス
インストールするWebの場所(仮想ディレクトリとポート)をユーザーが選択できるようにします。選択された仮想ディレクトリとポートは、それぞれWindows InstallerのTARGETVDIRとPORTプロパティに格納されます。通常このダイアログは「開始」セクションの最後か、「インストールの確認」ダイアログの前に置かれます。Web Setupプロジェクトでのみ使用できます。
スプラッシュ
画像を表示します。画像の大きさは横480ピクセル、縦320ピクセルで、これ以外の大きさでは伸縮して表示されます。
注意事項
ユーザーに注意事項を提示します。表示するメッセージにリッチテキストを使用します。
使用許諾契約書
ユーザーに使用許諾契約書を提示し、許可を求めます。ユーザーは「同意する」にチェックを入れなければ、次に進めなくなります。使用許諾契約書にはリッチテキストを使用します。
ユーザー情報
名前、所属、シリアル番号の情報の入力をユーザーに求めます。入力された名前、所属、シリアル番号はそれぞれWindows InstallerのUSERNAME、COMPANYNAME、PIDKEYプロパティに格納されます。さらに入力された情報はレジストリのInstallPropertiesキーに書き込まれます(とヘルプにはありますが、実際に確認すると書き込まれていないようでした)。具体的な使い方は、下記の「シリアル番号の入力を促し、それが正しいか検証する」で紹介します。
ユーザーの登録
ユーザーが登録情報を送信できるようにするために使用します。「今すぐ登録」ボタンをクリックすることにより、指定された実行ファイルが起動します。このとき、コマンドライン引数を指定することができ、これにはWindows Installerプロパティも使用できます。具体的な使い方は、下記の「ユーザーの登録を行う」で紹介します。
オプションボタン
ユーザーに排他的な選択を要求するオプションボタンを表示します。(2ボタン)、(3ボタン)、(4ボタン)の3種類あり、それぞれオプションボタンの数が違います。具体的な使い方は、下記の「「完全インストール」か「最小インストール」を選択できるようにする」で紹介します。
チェックボックス
ユーザーに選択を要求するチェックボックスを最大4つ表示します。(A)(B)(C)の3種類ありますが、すべて同じです。具体的な使い方は、下記の「デスクトップにショートカットを作成するかユーザーが選択できるようにする」で紹介します。
テキストボックス
ユーザーにテキスト入力を要求するテキストボックスを最大4つ表示します。(A)(B)(C)の3種類ありますが、すべて同じです。

ユーザーインターフェイスエディタの基本的な使い方はヘルプに任せるとして、以下にちょっとしたTipと具体例を紹介します。

BannerBitmapプロパティ

BannerBitmapプロパティはダイアログの上部に表示する画像を指定するもので、ほとんどのダイアログに存在するプロパティです。BannerBitmapプロパティに指定する画像の大きさは、横500ピクセル、縦70ピクセルとすべきで、これ以外の大きさでは伸縮されて表示されます。また画像の左側420ピクセルはテキストによって隠れる可能性があります。

また、BannerBitmapプロパティで使用する画像はセットアッププロジェクトに追加されている必要がありますが、画像ファイルのExcludeプロパティをTrueにすることにより、画像ファイルを配置しないようにできます。

ダイアログの見た目をMSIファイルを実行することなく確かめる

ダイアログの見た目がどのようになっているか、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]
VB.NETのコードは現在準備中です。
Convert C# to VB.NET により、
下記のC#のコードをVB.NETに変換したものを参考にしてください。
C#
コードを隠すコードを選択
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を用意します。

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」はショートカットのリンク先のファイル名、「アプリケーション」はショートカットの名前とします。

次にショートカットを削除するためのカスタムアクションを作成します。

VBScript
コードを隠すコードを選択
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を作成し、ファイルに保存します。

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」として保存します。

VBScript
コードを隠すコードを選択
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テーブルを表示し、次のような新しい列を追加します。

Action
LauncherApp
Type
22
Source
_1CD4536303AE460B8EA1AAEEC78DE0F3
Target

なおインストールされたVBScript以外のカスタムアクションを使う場合に指定するTypeについては、「Summary List of All Custom Action Types」をご覧ください。

最後に「完了」ダイアログの「閉じる」ボタンのイベントを設定します。ControlEventテーブルを開き、次のような新しい列を追加します。ここでFinishedFormは「完了」ダイアログを、CloseButtonは「閉じる」ボタンを意味していますので、これらが違う場合は適当に変更してください。

Dialog_
FinishedForm
Control_
CloseButton
Evant
DoAction
Argument
LauncherApp
Condition
1
Ordering
0

ただし、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 Tipsをご利用いただく際は、注意事項をお守りください。