逐步解說:使用自訂動作在安裝時將二進位編譯為機器碼
您可以定義自訂動作,指定要在安裝後執行的命令。 例如,在這個逐步解說中,定義自訂動作並將 EXE 的路徑名稱傳遞至 CustomActionData 屬性,以在安裝應用程式之後將可執行檔編譯為機器碼。
注意事項 |
---|
您的電腦可能會在下列說明中,以不同名稱或位置顯示某些 Visual Studio 使用者介面項目。 您所擁有的 Visual Studio 版本以及使用的設定會決定這些項目。 如需詳細資訊,請參閱 Visual Studio 設定。 |
若要建立要部署的 Web 瀏覽器應用程式
在 [檔案] 功能表上,指向 [新增],然後按一下 [專案]。
按一下 [Windows Form 應用程式]。
在 [名稱] 中,輸入 BrowserSample,然後按一下 [確定]。
在 [檢視] 功能表上,按一下 [工具箱]。
展開 [所有 Windows Form],並將 [Panel] 控制項拖曳至表單左上角。
在 [表單設計工具] 中,將 [TextBox] 控制項和 [Button] 控制項拖曳至 [Panel] 控制項。
在 [表單設計工具] 中,將 [WebBrowser] 控制項拖曳至 [Panel] 之下。
展開表單大小,以放入所有控制項。
在 [表單設計工具] 中,按一下 [Panel] 控制項。
在 [屬性] 視窗中,將 [版面配置] 下的 [Dock] 屬性變更為 [Top]。
在 [表單設計工具] 中,按一下 [WebBrowser] 控制項。
在 [屬性] 視窗中,將 [版面配置] 下的 [Dock] 屬性變更為 [Fill]。
在 [表單設計工具] 中,按一下 [Button] 控制項。
在 [屬性] 視窗中,將 [外觀] 下的 [Text] 屬性變更為 [移至]。
根據您的偏好調整 [Form]、[Panel]、[Textbox]、[Button] 和 [WebBrowser] 的大小。
在 [表單設計工具] 中,按兩下 [移至] 按鈕。
Form1 程式碼檔的程式碼檢視隨即出現。
加入下列程式碼,將 Web 瀏覽功能加入至應用程式。 [TextBox] 控制項中的文字是 [WebBrowser] 控制項的位址列,而動作會在您按一下 [移至] 按鈕時發生。
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,然後按一下 [移至]。
Microsoft 網站隨即出現。
若要建立自訂動作類別
在 [檔案] 功能表上指向 [加入],然後按一下 [新增專案]。
在 [加入新的專案] 對話方塊中,按一下 [Windows],然後按一下 [類別庫]。
在 [名稱] 方塊中,輸入 NGenCustomAction,然後按一下 [確定]。
按一下 [專案] 功能表上的 [加入新項目]。
在 [加入新項目] 對話方塊中,按一下 [一般],然後按一下 [安裝程式類別]。 在 [名稱] 方塊中輸入 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 程式碼檔中,加入下列 Helper 方法,以產生任何組件的原生映像程式碼檔。
<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"); }
若要為瀏覽器範例應用程式加入部署專案
在 [檔案] 功能表上指向 [加入],然後按一下 [新增專案]。
在 [加入新的專案] 對話方塊中,依序展開 [其他專案類型] 和 [安裝和部署專案],按一下 [Visual Studio Installer],然後按一下 [安裝專案]。
在 [名稱] 方塊中輸入 Browser Sample Installer,然後按一下 [確定]。
在 [檔案系統編輯器] 中選取 [應用程式資料夾]。 按一下 [執行] 功能表上的 [加入]。
[加入專案輸出群組] 對話方塊隨即出現。
在 [專案] 下拉式方塊中,選取 [BrowserSample],按一下 [專案輸出],然後按一下 [確定]。
在 [檔案系統編輯器] 中選取 [應用程式資料夾]。 按一下 [執行] 功能表上的 [加入]。
[加入專案輸出群組] 對話方塊隨即出現。
在 [專案] 下拉式方塊中,選取 [NGenCustomAction],按一下 [專案輸出],然後按一下 [確定]。
若要將 NGEN 自訂動作加入至安裝專案
在 [方案總管] 中,按一下 [Browser Sample Installer] 專案。
在 [檢視] 功能表中指向 [編輯器],然後按一下 [自訂動作]。
在 [自訂動作編輯器] 中選取 [自訂動作] 節點。
在 [動作] 功能表上選擇 [加入自訂動作]。
在 [選取專案中項目] 對話方塊中,按兩下 [應用程式資料夾],按一下 [來自 NGenCustomAction 的主要輸出 (作用中)],然後按一下 [確定]。
NGen 自訂動作隨即加入至全部四個自訂動作節點中。
在 [安裝] 節點中,按一下 [來自 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 版本> %SystemRoot%\Microsoft.NET\Framework64\v<CLR 版本>
ngen.log 檔案是最新的疑難排解記錄檔。