Tutorial: Usar una acción personalizada para compilar un binario en código nativo durante la instalación
Puede definir acciones personalizadas a fin de especificar comandos que se ejecutan después de una instalación. Por ejemplo, en este tutorial, definiremos una acción personalizada y pasaremos el nombre de ruta de acceso de un archivo EXE a la propiedad CustomActionData, a fin de compilar el archivo ejecutable a código nativo una vez instalada la aplicación.
Nota
Es posible que su equipo muestre nombres o ubicaciones diferentes para algunos de los elementos de la interfaz de usuario de Visual Studio incluidos en las instrucciones siguientes. La edición de Visual Studio que se tenga y la configuración que se utilice determinan estos elementos. Para obtener más información, vea Valores de configuración de Visual Studio.
Para crear una aplicación de explorador web que se va a implementar
En el menú Archivo, elija Nuevo y haga clic en Proyecto.
Haga clic en Aplicación de Windows Forms.
En el Nombre, escriba BrowserSample y, a continuación, haga clic en Aceptar.
En el menú Ver, haga clic en Cuadro de herramientas.
Expanda Todos los formularios de Windows Forms y arrastre un control Panel hasta la parte superior izquierda del formulario.
En el Diseñador de Windows Forms, arrastre un control TextBox y un control Button al control Panel.
En el Diseñador de Windows Forms, arrastre un control WebBrowser y sitúelo debajo del Panel.
Expanda el tamaño del formulario para que se ajuste a todos los controles.
En el Diseñador de Windows Forms, haga doble clic en el control Panel.
En la Ventana Propiedades, cambie la propiedad Dock que aparece en Diseño a Top.
En el Diseñador de Windows Forms, haga doble clic en el control WebBrowser.
En la ventana Propiedades, cambie la propiedad Dock que aparece en Diseño a Fill.
En el Diseñador de Windows Forms, haga clic en el control Button.
En la Ventana Propiedades, cambie la propiedad Text bajo Apariencia a Ir.
Cambie el tamaño de los elementos Form, Panel, Textbox, Button y WebBrowser según sus preferencias.
En el Diseñador de Windows Forms, haga doble clic en el botón Ir.
Aparecerá la vista de código del archivo de código Form1.
Agregue el siguiente código, que agrega la funcionalidad de exploración web a la aplicación. El texto del control TextBox es la barra de direcciones del control WebBrowser. La acción tiene lugar al hacer clic en el botón Ir.
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); }
Para probar el explorador, presione F5.
Se abrirá el formulario.
En el cuadro de texto, escriba https://www.microsoft.com. A continuación, haga clic en Ir.
Se abre el sitio web de Microsoft.
Para crear la clase de acción personalizada
En el menú Archivo, elija Agregar y, después, haga clic en Nuevo proyecto.
En el cuadro de diálogo Agregar nuevo proyecto, haga clic en Windows y en Biblioteca de clases.
En el cuadro Nombre, escriba NGenCustomAction y, a continuación, haga clic en Aceptar.
En el menú Proyecto, haga clic en Agregar nuevo elemento.
En el cuadro de diálogo Agregar nuevo elemento, haga clic en General y, a continuación, en Clase del instalador. En el cuadro Nombre, escriba NGenCustomAction y, a continuación, haga clic en Agregar.
Nota
Asegúrese de agregar una Clase del instalador; de lo contrario, el archivo de código no tendrá las instrucciones using necesarias.
En el Explorador de soluciones, elimine el archivo de código Class1 del proyecto NGenCustomAction.
Para agregar código a la acción personalizada
En el Explorador de soluciones (o en la superficie de diseño), haga clic con el botón secundario del mouse en el archivo de código NGenCustomAction. A continuación, haga clic en Ver código para abrir el Editor de código. Agregue el código siguiente al principio del módulo.
Imports System.IO Imports System.Diagnostics
using System.IO; using System.Diagnostics;
Actualice la declaración de clase de modo que herede de la clase System.Configuration.Install.Installer.
Inherits System.Configuration.Install.Installer
: System.Configuration.Install.Installer
En el archivo de código NGenCustomAction, agregue el siguiente método auxiliar para generar el archivo de código de imagen nativa de cualquier ensamblado.
<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); } } }
En el archivo de código NGenCustomAction, agregue el siguiente procedimiento para invalidar los procedimientos Install, Commit, Rollback y Uninstall de la clase base.
<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"); }
Para agregar un proyecto de implementación para la aplicación de ejemplo de explorador
En el menú Archivo, elija Agregar y, después, haga clic en Nuevo proyecto.
En el cuadro de diálogo Agregar nuevo proyecto, abra Otros tipos de proyectos, abra Proyectos de instalación e implementación, haga clic en Instalador de Visual Studio y, a continuación, en Proyecto de instalación.
En el cuadro Nombre, escriba Instalador de ejemplo de explorador y, a continuación, haga clic en Aceptar.
En el Editor del sistema de archivos, seleccione la Carpeta de la aplicación. En el menú Acción, haga clic en Agregar.
Aparecerá el cuadro de diálogo Agregar grupo de resultados del proyecto.
En el cuadro combinado desplegable Proyecto, seleccione BrowserSample, haga clic en Resultados del proyecto y, a continuación, haga clic en Aceptar.
En el Editor del sistema de archivos, seleccione la Carpeta de la aplicación. En el menú Acción, haga clic en Agregar.
Aparecerá el cuadro de diálogo Agregar grupo de resultados del proyecto.
En el cuadro combinado desplegable Proyecto, seleccione NGenCustomAction, haga clic en Resultados del proyecto y, a continuación, haga clic en Aceptar.
Para agregar la acción personalizada NGEN al proyecto de instalación
En el Explorador de soluciones, haga en el proyecto Instalador de ejemplo de explorador.
En el menú Ver, elija Editor y, a continuación, haga clic en Acciones personalizadas.
En el Editor de acciones personalizadas, seleccione el nodo Acciones personalizadas.
En el menú Acción, haga clic en Agregar acción personalizada.
En el cuadro de diálogo Seleccionar elemento en el proyecto, haga doble clic en la Carpeta de la aplicación y, a continuación, seleccione Resultado principal desde NGenCustomAction (activa) y haga clic en Aceptar.
Se agrega la acción personalizada NGen a los cuatro nodos de acción personalizada.
En el nodo Instalar, haga clic en Resultado principal desde NGenCustomAction (activa).
En la ventana Propiedades, cambie la propiedad CustomActionData a /Args="[TARGETDIR]BrowserSample.exe". Incluya las comillas.
Nota
La propiedad [TARGETDIR] es la ubicación del archivo ejecutable instalado. La acción personalizada utiliza ngen.exe para convertir el archivo ejecutable instalado en una imagen nativa.
En el Explorador de soluciones, haga en el proyecto de instalación Instalador de ejemplo de explorador.
En el menú Compilar, haga clic en Compilar Instalador de ejemplo de explorador.
Para comprobar la generación de código nativo
Navegue a la carpeta de instalación y busque el archivo BrowserSample.exe. Por ejemplo %Archivos de programa%\CompanyName\Instalador de ejemplo de explorador\BrowserSample.exe.
En el símbolo del sistema de Visual Studio, compruebe que el archivo ejecutable se precompiló a código nativo ejecutando el siguiente código:
ngen.exe display FullPathToExe
Por ejemplo, puede ejecutar el siguiente comando:
ngen.exe display "C:\Program Files (x86)\Microsoft\Browser Sample Installer\BrowserSample.exe"
Se muestra la siguiente salida del comando.
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>
Nota
Si ngen.exe no muestra una imagen nativa, puede encontrar los registros de ngen en uno de los siguientes directorios:
%SystemRoot%\Microsoft.NET\Framework\v<versión de CLR> %SystemRoot%\Microsoft.NET\Framework64\v<versión de CLR>
El archivo ngen.log es el más reciente para la solución de problemas.
Vea también
Referencia
Ngen.exe (Generador de imágenes nativas)
Conceptos
Proceso de ejecución administrada
Otros recursos
Administración de acciones personalizadas en la implementación