チュートリアル: カスタム動作を使用した、インストール時におけるバイナリのネイティブ コードへのコンパイル
カスタム動作を定義して、インストール後に実行するコマンドを指定できます。 たとえば、このチュートリアルでは、カスタム動作を定義し、CustomActionData プロパティに EXE のパス名を渡して、アプリケーションのインストール後にこの実行可能ファイルをネイティブ コードにコンパイルします。
注意
お使いのマシンで、Visual Studio ユーザー インターフェイスの一部の要素の名前や場所が、次の手順とは異なる場合があります。 これらの要素は、使用している Visual Studio のエディションや独自の設定によって決まります。 詳細については、「Visual Studio の設定」を参照してください。
配置する Web ブラウザー アプリケーションを作成するには
[ファイル] メニューの [新規作成] をポイントし、[プロジェクト] をクリックします。
[Windows フォーム アプリケーション] をクリックします。
[名前] に「BrowserSample」と入力し、[OK] をクリックします。
[表示] メニューの [ツールボックス] をクリックします。
[すべての Windows フォーム] を展開し、Panel コントロールをフォームの左上へドラッグします。
フォーム デザイナーで、TextBox コントロールと Button コントロールを Panel コントロールにドラッグします。
フォーム デザイナーで、WebBrowser コントロールを Panel の下へドラッグします。
すべてのコントロールが収まるように、フォームのサイズを大きくします。
フォーム デザイナーで、Panel コントロールをクリックします。
[プロパティ] ウィンドウで、Layout の Dock プロパティを Top に変更します。
フォーム デザイナーで、WebBrowser コントロールをクリックします。
[プロパティ] ウィンドウで、Layout の Dock プロパティを Fill に変更します。
フォーム デザイナーで、Button コントロールをクリックします。
[プロパティ] ウィンドウで、Appearance の Text プロパティを Go に変更します。
必要に応じて、Form、Panel、Textbox、Button、および WebBrowser のサイズを変更します。
フォーム デザイナーで、[Go] ボタンをダブルクリックします。
Form1 コード ファイルのコード ビューが表示されます。
次のコードを追加します。このコードにより、Web ブラウズ機能がアプリケーションに追加されます。 TextBox コントロールのテキストは WebBrowser コントロールのアドレス バーになります。[Go] ボタンをクリックすると、動作が実行されます。
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click WebBrowser1.Navigate(TextBox1.Text) End Sub
private void button1_Click(object sender, EventArgs e) { webBrowser1.Navigate(textBox1.Text); }
ブラウザーをテストするには、F5 キーを押します。
フォームが開きます。
テキスト ボックスに、「https://www.microsoft.com」と入力し、[Go] をクリックします。
Microsoft Web サイトが表示されます。
カスタム動作クラスを作成するには
[ファイル] メニューの [追加] をポイントし、[新しいプロジェクト] をクリックします。
[新しいプロジェクトの追加] ダイアログ ボックスで、[Windows] をクリックし、[クラス ライブラリ] をクリックします。
[名前] ボックスに「NGenCustomAction」と入力し、[OK] をクリックします。
[プロジェクト] メニューの [新しい項目の追加] をクリックします。
[新しい項目の追加] ダイアログ ボックスで、[全般] をクリックし、[インストーラー クラス] をクリックします。 [名前] ボックスに「NGenCustomAction」と入力し、[追加] をクリックします。
注意
インストーラー クラスを必ず追加してください。そうしないと、必要な using ステートメントがコード ファイルに追加されません。
ソリューション エクスプローラーで、NGenCustomAction プロジェクトの Class1 コード ファイルを削除します。
カスタム動作にコードを追加するには
ソリューション エクスプローラー (またはデザイン サーフェイス) で NGenCustomAction コード ファイルを右クリックし、[コードの表示] をクリックしてコード エディターを開きます。 モジュールの先頭に次のコードを追加します。
Imports System.IO Imports System.Diagnostics
using System.IO; using System.Diagnostics;
System.Configuration.Install.Installer クラスを継承するようにクラス宣言を更新します。
Inherits System.Configuration.Install.Installer
: System.Configuration.Install.Installer
NGenCustomAction コード ファイルで、アセンブリのネイティブ イメージ コード ファイルを生成する次のヘルパー メソッドを追加します。
<System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)> _ Private Sub ngenCA(ByVal savedState As System.Collections.IDictionary, ByVal ngenCommand As String) Dim argsArray As [String]() If String.Compare(ngenCommand, "install", StringComparison.OrdinalIgnoreCase) = 0 Then Dim args As [String] = Context.Parameters("Args") If [String].IsNullOrEmpty(args) Then Throw New InstallException("No arguments specified") End If Dim separators As Char() = {";"c} argsArray = args.Split(separators) 'It is Ok to 'ngen uninstall' assemblies which were not installed savedState.Add("NgenCAArgs", argsArray) Else argsArray = DirectCast(savedState("NgenCAArgs"), [String]()) End If ' Gets the path to the Framework directory. Dim fxPath As String = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory() For i As Integer = 0 To argsArray.Length - 1 Dim arg As String = argsArray(i) ' Quotes the argument, in case it has a space in it. arg = """" & arg & """" Dim command As String = (ngenCommand & " ") + arg Dim si As New ProcessStartInfo(Path.Combine(fxPath, "ngen.exe"), command) si.WindowStyle = ProcessWindowStyle.Hidden Dim p As Process Try Context.LogMessage((">>>>" & Path.Combine(fxPath, "ngen.exe ")) + command) p = Process.Start(si) p.WaitForExit() Catch ex As Exception Throw New InstallException("Failed to ngen " & arg, ex) End Try Next End Sub
[System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)] private void ngenCA(System.Collections.IDictionary savedState, string ngenCommand) { String[] argsArray; if (string.Compare(ngenCommand, "install", StringComparison.OrdinalIgnoreCase) == 0) { String args = Context.Parameters["Args"]; if (String.IsNullOrEmpty(args)) { throw new InstallException("No arguments specified"); } char[] separators = { ';' }; argsArray = args.Split(separators); savedState.Add("NgenCAArgs", argsArray); //It is Ok to 'ngen uninstall' assemblies which were not installed } else { argsArray = (String[])savedState["NgenCAArgs"]; } // Gets the path to the Framework directory. string fxPath = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory(); for (int i = 0; i < argsArray.Length; ++i) { string arg = argsArray[i]; // Quotes the argument, in case it has a space in it. arg = "\"" + arg + "\""; string command = ngenCommand + " " + arg; ProcessStartInfo si = new ProcessStartInfo(Path.Combine(fxPath, "ngen.exe"), command); si.WindowStyle = ProcessWindowStyle.Hidden; Process p; try { Context.LogMessage(">>>>" + Path.Combine(fxPath, "ngen.exe ") + command); p = Process.Start(si); p.WaitForExit(); } catch (Exception ex) { throw new InstallException("Failed to ngen " + arg, ex); } } }
NGenCustomAction コード ファイルで、基本クラスの Install、Commit、Rollback、Uninstall の各プロシージャをオーバーライドする次のプロシージャを追加します。
<System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)> _ Public Overloads Overrides Sub Install(ByVal savedState As System.Collections.IDictionary) MyBase.Install(savedState) Context.LogMessage(">>>> ngenCA: install") ngenCA(savedState, "install") End Sub <System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)> _ Public Overrides Sub Commit(ByVal savedState As System.Collections.IDictionary) MyBase.Commit(savedState) Context.LogMessage(">>>> ngenCA: commit") End Sub <System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)> _ Public Overloads Overrides Sub Uninstall(ByVal savedState As System.Collections.IDictionary) MyBase.Uninstall(savedState) Context.LogMessage(">>>> ngenCA: uninstall") ngenCA(savedState, "uninstall") End Sub <System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)> _ Public Overloads Overrides Sub Rollback(ByVal savedState As System.Collections.IDictionary) MyBase.Rollback(savedState) Context.LogMessage(">>>> ngenCA: rollback") ngenCA(savedState, "uninstall") End Sub
[System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)] public override void Install(System.Collections.IDictionary savedState) { base.Install(savedState); Context.LogMessage(">>>> ngenCA: install"); ngenCA(savedState, "install"); } [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)] public override void Commit(IDictionary savedState) { base.Commit(savedState); Context.LogMessage(">>>> ngenCA: commit"); } [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)] public override void Uninstall(System.Collections.IDictionary savedState) { base.Uninstall(savedState); Context.LogMessage(">>>> ngenCA: uninstall"); ngenCA(savedState, "uninstall"); } [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)] public override void Rollback(System.Collections.IDictionary savedState) { base.Rollback(savedState); Context.LogMessage(">>>> ngenCA: rollback"); ngenCA(savedState, "uninstall"); }
Browser Sample アプリケーションの配置プロジェクトを追加するには
[ファイル] メニューの [追加] をポイントし、[新しいプロジェクト] をクリックします。
[新しいプロジェクトの追加] ダイアログ ボックスで、[その他のプロジェクトの種類] を展開し、[セットアップ/配置プロジェクト] を展開して、[Visual Studio インストーラー] をクリックします。次に、[セットアップ プロジェクト] をクリックします。
[名前] ボックスに「Browser Sample Installer」と入力し、[OK] をクリックします。
ファイル システム エディターで、[アプリケーション フォルダー] を選択します。 [操作] メニューの [追加] をクリックします。
[プロジェクト出力グループの追加] ダイアログ ボックスが表示されます。
プロジェクトのドロップダウン コンボ ボックスで、BrowserSample をクリックし、[プロジェクト出力] をクリックして、[OK] をクリックします。
ファイル システム エディターで、[アプリケーション フォルダー] を選択します。 [操作] メニューの [追加] をクリックします。
[プロジェクト出力グループの追加] ダイアログ ボックスが表示されます。
プロジェクトのドロップダウン コンボ ボックスで、NGenCustomAction をクリックし、[プロジェクト出力] をクリックして、[OK] をクリックします。
セットアップ プロジェクトに NGEN カスタム動作を追加するには
ソリューション エクスプローラーで、Browser Sample Installer プロジェクトをクリックします。
[表示] メニューの [エディター] をポイントし、[カスタム動作] をクリックします。
カスタム動作エディターで、[カスタム動作] ノードを選択します。
[操作] メニューの [カスタム動作の追加] をクリックします。
[プロジェクトから項目を選択] ダイアログ ボックスで、[アプリケーション フォルダー] をダブルクリックし、[NGenCustomAction (アクティブ) のプライマリ出力] をクリックして、[OK] をクリックします。
NGen カスタム動作が 4 つのカスタム動作ノードのすべてに追加されます。
[インストール] ノードで、[NGenCustomAction (アクティブ) のプライマリ出力] をクリックします。
[プロパティ] ウィンドウで、CustomActionData プロパティを「/Args="[TARGETDIR]BrowserSample.exe"」に変更します。 二重引用符も含めて入力してください。
注意
[TARGETDIR] プロパティは、インストールされた実行可能ファイルの場所です。 このカスタム動作では、ngen.exe を使用して、インストールされた実行可能ファイルをネイティブ イメージに変換します。
ソリューション エクスプローラーで、Browser Sample Installer セットアップ プロジェクトをクリックします。
[ビルド] メニューの [Browser Sample Installer のビルド] をクリックします。
ネイティブ コードの生成を確認するには
インストール フォルダーに移動し、BrowserSample.exe ファイルを見つけます。 パスは、%PROGRAMFILES%\CompanyName\Brower Sample Installer\BrowserSample.exe などです。
Visual Studio コマンド プロンプトで、次のコードを実行して、実行可能ファイルがネイティブ コードにプリコンパイルされたことを確認します。
ngen.exe display FullPathToExe
たとえば、次のコマンドを実行します。
ngen.exe display "C:\Program Files (x86)\Microsoft\Browser Sample Installer\BrowserSample.exe"
コマンド出力が表示されます。
Microsoft (R) CLR Native Image Generator - Version 4.0.21102.0 Copyright (c) Microsoft Corporation. All rights reserved. NGEN Roots: C:\Program Files (x86)\Microsoft\Browser Sample Installer\BrowserSample.exe NGEN Roots that depend on "c:\Program Files (x86)\Microsoft\Browser Sample Installer\BrowserSample.exe": C:\Program Files (x86)\Microsoft\Browser Sample Installer\BrowserSample.exe Native Images: BrowserSample, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null <debug>
注意
ngen.exe でネイティブ イメージが表示されない場合、次のディレクトリのいずれかで ngen ログを確認できます。
%SystemRoot%\Microsoft.NET\Framework\v<CLR version> %SystemRoot%\Microsoft.NET\Framework64\v<CLR version>
ngen.log ファイルは最新のトラブルシューティング ログです。