*.NETプログラミング研究 第58号 [#h67b13a6] **.NET Tips [#g7cc3001] ***ユーザーインターフェイスエディタの使い方 [#k1af3900] VS.NETのデプロイメントプロジェクトでは、「ユーザーインターフェイスエディタ」を使用することにより、インストール時に表示されるウィザードダイアログのページを追加、削除、変更することができます。 -[[配置でのユーザー インターフェイスの管理>http://www.microsoft.com/japan/msdn/library/ja/vsintro7/html/vbcontheuserinterfaceeditor.asp]] ユーザーインターフェイスエディタを表示するには、ソリューションエクスプローラでデプロイメントプロジェクトを右クリックし、メニューの「表示」-「ユーザーインターフェイス」を選択してください。 ダイアログを追加するには、ダイアログを追加するセクションを右クリックし、メニューの「ダイアログの追加」を選択してください。セクションは「インストール」と「管理者インストール」の両方につき「開始」「進行状況」「終了」の3つに分かれていますが、それぞれに追加できるダイアログの種類は異なります。 ダイアログを追加した後は、ダイアログを適当な位置に移動します。ドラッグ&ドロップにより、ダイアログの位置を変更することができます。 追加できるダイアログの種類などについては、ヘルプの「インストール用ユーザー インターフェイス ダイアログ ボックス」や「配置のダイアログ ボックス」で詳しく説明されています。 -[[インストール用ユーザー インターフェイス ダイアログ ボックス>http://www.microsoft.com/japan/msdn/library/ja/vsintro7/html/vbconinstallationuserinterfacedialogs.asp]] -[[配置のダイアログ ボックス>http://www.microsoft.com/japan/msdn/library/ja/vsintro7/html/vbcondeploymentdialogs.asp]] この内幾つかを簡単に説明します。 #prescroll(wrap=true){{ ・インストールフォルダ インストール先のフォルダをユーザーが選択できるようにします。選択されたフォルダは、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プロパティ [#k6af352e] BannerBitmapプロパティはダイアログの上部に表示する画像を指定するもので、ほとんどのダイアログに存在するプロパティです。BannerBitmapプロパティに指定する画像の大きさは、横500ピクセル、縦70ピクセルとすべきで、これ以外の大きさでは伸縮されて表示されます。また画像の左側420ピクセルはテキストによって隠れる可能性があります。 また、BannerBitmapプロパティで使用する画像はデプロイメントプロジェクトに追加されている必要がありますが、画像ファイルのExcludeプロパティをTrueにすることにより、画像ファイルを配置しないようにできます。 -[[BannerBitmap プロパティ>http://www.microsoft.com/japan/msdn/library/ja/vsintro7/html/vxgrfbannerbitmapproperty.asp]] ***ダイアログの見た目をMSIファイルを実行することなく確かめる [#g355ab58] ダイアログの見た目がどのようになっているか、MSIファイルを実行することなく、Orcaの「Dialog Preview」を使って確認することができます。Orcaのメニュー「Tool」にある「Dialog Preview」を選択すれば、「Dialog Preview」ダイアログが表示され、ここで選択したダイアログを「Preview」ボタンをクリックして確認することができます。 ***ユーザーにシリアル番号の入力を促し、それが正しいか検証する [#xd90d3da] 「ユーザー情報」ダイアログを使うことにより、シリアル番号の入力をユーザーに要求し、入力されたシリアル番号が正しいかごく簡単な検証を行うことができます。 まず「ユーザー情報」ダイアログをユーザーインターフェイスエディタで「開始」セクションに追加します。 次に「ユーザー情報」ダイアログのプロパティを変更します。ここで変更するプロパティは、ShowSerialNumberとSerialNumberTemplateです。ShowSerialNumberをTrueとすることにより、シリアル番号の入力欄がダイアログに表示されるようになります。 どのようなシリアル番号が入力されれば正しいと判断するかを指定するのが、SerialNumberTemplateプロパティです。SerialNumberTemplateプロパティにはテンプレートを指定し、ここで使用できる文字とその意味については、次に示すヘルプのページが参考になります。 -[[SerialNumberTemplate プロパティ>http://www.microsoft.com/japan/msdn/library/ja/vsintro7/html/vxgrfserialnumbertemplateproperty.asp]] -[[MaskedEdit Control>http://msdn.microsoft.com/library/en-us/msi/setup/maskededit_control.asp]] しかし私が実際に確かめたところでは、これらのドキュメントに書かれていることと実際の動作には一部違いがありました。私が確認したSerialNumberTemplateプロパティで使用できる文字の意味を以下に示します。これらはあくまで私が確かめた結果ですので、絶対に正しいという保障はできません。なお「検査アルゴリズムに含まれる」というのは、シリアル番号が正しいか検証する判断材料として使用され、正しくなければインストールできない(次に進めない)という意味です。 #prescroll(wrap=true){{ # 検査アルゴリズムに含まれない数字の入力を必要とします。(数字以外は入力できなくなります。) % 検査アルゴリズムに含まれる数字の入力を必要とします。すべての数字を足した数が7で割り切れれば正しいとされます。(数字以外は入力できなくなります。) ? 検査アルゴリズムに含まれない英数字の入力を必要とします。 ^ 検査アルゴリズムに含まれる英大文字の入力を必要とします。すべての文字が英大文字ならば正しいとされます。 & 検査アルゴリズムに含まれる英字の入力を必要とします。すべての文字が英字ならば正しいとされます。 ` 検査アルゴリズムに含まれない英数字の入力を必要とします。 }} SerialNumberTemplateプロパティはデフォルトで「<###-%%%%%%%>」となっていますが、このときは、2つのテキストボックスと、その間に「-」が表示されます。はじめのテキストボックスには、3桁の数字が入力されてさえいれば正しいと判断されます(ただし数字しか入力できません)。2番目のテキストボックスには7桁の数字と、すべての数の合計が7で割り切れることが条件となります(例えば、「7777777」や「1111111」など)。 #や%を使ったときはユーザーが数字しか入力できなくなりますし、テキストボックスには指定された文字数以上の文字が入力できなくなります。よってユーザーが正しいシリアル番号を予想するのはごく簡単です。しかもこのテンプレートはMSIファイルのPropertyテーブル内のPIDTemplateにそのまま書き込まれますので、これを見ればどのようなシリアル番号を入力すればよいか分かってしまいます。 -[[PIDKEY Property>http://msdn.microsoft.com/library/en-us/msi/setup/pidkey.asp]] -[[PIDTemplate Property>http://msdn.microsoft.com/library/en-us/msi/setup/pidtemplate.asp]] -[[ValidateProductID Action>http://msdn.microsoft.com/library/en-us/msi/setup/validateproductid_action.asp]] このようないい加減な方法でなく、しっかりした検証を行いたいのであれば、カスタムアクションを使うしかないでしょう。その一例が、マイクロソフトのサポート技術情報にありますので、参考にしてください。 -[[How To Validate a Serial Number During an Installation Created with VSI>http://www.support.microsoft.com/kb/253683/]] しかしインストーラだけでシリアル番号を確認するよりも、アプリケーション自身が確認するようにした方がよいのではないでしょうか。 ***ユーザーの登録を行う [#z4bb54c0] 「ユーザーの登録」ダイアログを使ってユーザー登録できるようにする簡単な例を紹介します。 まずはユーザー登録をするためのアプリケーションを作成します。このアプリケーションにより、起動時のコマンドライン引数により与えられたユーザー情報を登録します。 ここではHTTPのPOSTにより指定されたURL(ここでは「http://localhost/reg.cgi」)にユーザー情報を送信する次のようなアプリケーションを作成します。もちろん「http://localhost/reg.cgi」にPOSTされた情報を登録するためのCGIが用意されていることが前提です。かなりいい加減に作っていますので、参考程度にしてください。 #code(csharp){{ 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(); } } } }} 参考. -[[DOBON.NET .NET Tips - POSTによりファイルをダウンロードし表示する>http://dobon.net/vb/dotnet/internet/webrequestpost.html]] 次にユーザーインターフェイスエディタで「開始」セクションに「ユーザー情報」ダイアログを、「終了」セクションの「完了」ダイアログの前に「ユーザー登録」ダイアログを追加します。 「ユーザー情報」ダイアログのプロパティは、適当で結構です。また「ユーザー登録」ダイアログのArgumentsプロパティを「USERNAME "[USERNAME]" COMPANYNAME "[COMPANYNAME]" PIDKEY "[PIDKEY]"」、Excutableプロパティを先ほど作成したアプリケーションとします。Argumentsプロパティで指定された[USERNAME]、[COMPANYNAME]、[PIDKEY]は「ユーザー情報」ダイアログで入力された名前、所属、シリアル番号に置き換わります。 これで「ユーザー登録」ダイアログの「今すぐ登録」ボタンがクリックされたときにアプリケーションが起動し、ユーザー登録が行われるようになります。 ***「完全インストール」か「最小インストール」を選択できるようにする [#f1a979a6] ここでは、「オプションボタン」ダイアログを使った簡単な例を示します。 アプリケーションをインストールする際、ユーザーが完全インストールか最小インストールかを選択できるインストーラをよく見ますが、このようなインストーラを作成する方法を紹介します。(「カスタムインストール」は残念ながらVS.NETだけでは無理といってよいでしょう。) まずユーザーインターフェイスエディタで「開始」セクションに「オプションボタン(2ボタン)」ダイアログを追加します。 次にダイアログのプロパティを設定します。ここでは次のようにプロパティを設定します。 #prescroll(wrap=true){{ BannerText インストールの種類 BodyText インストールの種類を選択してください。 Button1Label 完全インストール(すべてのファイルをインストールします。) Button1Value 1 Button2Label 最小インストール(最低限のファイルのみをインストールします。) Button2Value 2 ButtonProperty BUTTON2 DefaultValue 1 }} 次に最小インストールではインストールされず、完全インストールでのみインストールするファイルのConditionプロパティを「BUTTON2=1」に設定します。「BUTTON2」はButtonPropertyプロパティを、「1」は1番目のオプションボタンが選択されたことを示します。これで、1番目のオプションボタンが選択されたときにのみこれらのファイルが配置されるようになります。 補足.Windows Installerでは通常上記のような目的のためにはFeatureテーブルを使用しますが、残念ながらVS.NETではFeatureテーブルを扱う方法が用意されていません。 ***デスクトップにショートカットを作成するかユーザーが選択できるようにする [#w6cfa649] 次に「チェックボックス」ダイアログを使った例を紹介します。ここでは、デスクトップにシュートカットを作成するかユーザーが選べるようにする方法を紹介します。 まずユーザーインターフェイスエディタで「開始」セクションに「チェックボックス」ダイアログを追加します。(A)(B)(C)はすべて同じですので、どれを追加してもかまいません。 次に「チェックボックス」ダイアログのプロパティを設定します。ここでは次の箇所をデフォルトから変更しました。 #prescroll(wrap=true){{ 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を用意します。 #code(vbscript){{ dim arg, args, desktop, WshShell, WshShortcut arg = Session.Property("CustomActionData") args = Split(arg, ":::") if args(1)="1" then set WshShell = CreateObject("WScript.Shell") desktop = WshShell.SpecialFolders("Desktop") set WshShortcut = WshShell.CreateShortcut(desktop & "\アプリケーション.lnk") WshShortcut.TargetPath = args(0) WshShortcut.Save end if }} これを「カスタム動作」の「インストール」に追加し、CustomActionDataプロパティを「[TARGETDIR]app.exe:::[CHECKBOXA1]」とします(ここでは「app.exe」へのシュートカットを「アプリケーション」という名前で作成しています)。(「カスタム動作」について詳しくは、前号をご覧ください。) この方法ではカスタムアクションでショートカットを作成しているため、アンインストールにも(必要があればロールバックにも)カスタムアクションを追加して、作成したシュートカットを削除する必要があります。 ***インストール終了後にアプリケーションを起動するか選択できるようにする [#xd29e1b2] 「チェックボックス」ダイアログを使った例をもう一つ紹介します。インストール終了後にインストールしたアプリケーションを起動するかユーザーが選択できるようにします。同様の方法でインストール終了後にREADMEを表示させることも可能です。 まずはVS.NETのみを使って作成してみますが、はじめに言ってしまうと、かなり妥協の産物となってしまいます。 まずはユーザーが選択できるように、ユーザーインターフェイスエディタで「チェックボックス」ダイアログを「開始」セクションに作成します。本来ならこのダイアログは最後に表示したいので「終了」セクションに置きたいところですが、それではカスタムアクションの実行後にダイアログが表示されることになるため、仕方がありません。 「チェックボックス」ダイアログのプロパティは次のようにします。 #prescroll(wrap=true){{ BannerText アプリケーションの起動 BodyText インストールしたアプリケーションを起動するか選択してください。 Checkbox1Label インストールしたアプリケーションをインストール終了後に起動する Checkbox1Property CHECKBOXA1 Checkbox1Value Checked Checkbox1Visible True Checkbox2Visible,Checkbox3Visible,Checkbox4Visible False }} 次にカスタムアクションを作成します。ここでは次のようなVBScriptを作成し、ファイルに保存します。 #code(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」として保存します。 #code(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テーブルを表示し、次のような新しい列を追加します。 #prescroll(wrap=true){{ Action LauncherApp Type 22 Source _1CD4536303AE460B8EA1AAEEC78DE0F3 Target }} なおインストールされたVBScript以外のカスタムアクションを使う場合に指定するTypeについては、「Summary List of All Custom Action Types」をご覧ください。 -[[Summary List of All Custom Action Types>http://msdn.microsoft.com/library/en-us/msi/setup/summary_list_of_all_custom_action_types.asp]] 最後に「完了」ダイアログの「閉じる」ボタンのイベントを設定します。ControlEventテーブルを開き、次のような新しい列を追加します。ここでFinishedFormは「完了」ダイアログを、CloseButtonは「閉じる」ボタンを意味していますので、これらが違う場合は適当に変更してください。 #prescroll(wrap=true){{ 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オプションをつけて非同期で呼び出す必要があります。 -[[Custom Action Return Processing Options>http://msdn.microsoft.com/library/en-us/msi/setup/custom_action_return_processing_options.asp]] ***テキストボックスに入力された文字を*で隠す [#m6d99a7f] 「テキストボックス」ダイアログを使ってユーザーにパスワードを入力してもらうときなど、テキストボックスに入力された文字がそのまま表示されては困るというケースもあるでしょう。このような場合、テキストボックスに入力された文字を*で隠すように設定することができますが、これはVS.NETだけでは無理で、Orcaを使わなければなりません。 ここでは、ユーザーインターフェイスエディタで追加された「テキストボックス」ダイアログの一番目のテキストボックスをパスワード入力用とし、入力された文字が表示されないようにします。 まずはOrcaでMSIファイルを開き、Controlテーブルを表示し、この中から対象となるテキストボックスを探します。ここでは、Dialog_列が「CustomTextA」で「Control」列が「Edit1」の行がそれです。 次にこのコントロールのAttributesにmsidbControlAttributesPasswordInputを追加します。具体的には、Attributes列にある数字に2097152を足した数を新しい値とします。通常は、2097159となるでしょう。 これで保存すれば終了です。 -[[Password Control Attribute>http://msdn.microsoft.com/library/en-us/msi/setup/password_control_attribute.asp]] //これより下は編集しないでください #pageinfo(,2010-03-19 (金) 01:28:20,DOBON!,2010-03-19 (金) 01:28:20,DOBON!) |