Procédure pas à pas : utilisation d'une action personnalisée pour compiler un fichier binaire en code natif au moment de l'installation

Vous pouvez définir des actions personnalisées pour spécifier des commandes exécutées après une installation. Par exemple, dans cette procédure pas à pas, vous définissez une action personnalisée et passez le nom de chemin d'accès d'un EXE à la propriété CustomActionData pour compiler le fichier exécutable en code natif après que l'application a été installée.

Notes

Il est possible que votre ordinateur affiche des noms ou des emplacements différents pour certains des éléments d'interface utilisateur de Visual Studio dans les instructions suivantes. L'édition de Visual Studio dont vous disposez et les paramètres que vous utilisez déterminent ces éléments. Pour plus d'informations, consultez Paramètres Visual Studio.

Pour créer une application de navigateur Web à déployer

  1. Dans le menu Fichier, pointez sur Nouveau, puis cliquez sur Projet.

  2. Cliquez sur Application Windows Forms.

  3. Dans Nom, tapez BrowserSample, puis cliquez sur OK.

  4. Dans le menu Affichage, cliquez sur Boîte à outils.

  5. Développez Tous les Windows Forms, puis fait glisser un contrôle Panel vers la partie supérieure gauche du formulaire.

  6. Dans le Concepteur de formulaires, faites glisser un contrôle TextBox et un contrôle Button vers le contrôle Panel.

  7. Dans le Concepteur de formulaires, faites glisser un contrôle WebBrowser sous le contrôle Panel.

  8. Développez la taille du formulaire afin qu'il puisse contenir tous les contrôles.

  9. Dans le Concepteur de formulaires, cliquez sur le contrôle Panel.

  10. Dans la Fenêtre Propriétés, remplacez la propriété Dock sous Disposition par Haut.

  11. Dans le Concepteur de formulaires, cliquez sur le contrôle WebBrowser.

  12. Dans la Fenêtre Propriétés, remplacez la propriété Dock sous Disposition par Remplir.

  13. Dans le Concepteur de formulaires, cliquez sur le contrôle Button.

  14. Dans la Fenêtre Propriétés, remplacez la propriété Text sous Apparence par Aller à.

  15. Redimensionnez les contrôles Form, Panel, Textbox, Button et WebBrowser à votre convenance.

  16. Dans le Concepteur de formulaires, double-cliquez sur le bouton Aller à.

    Le mode code pour le fichier de code Form1 apparaît.

  17. Ajoutez le code suivant, lequel ajoute les fonctionnalités de navigation Web à votre application. Le texte du contrôle TextBox est la barre d'adresses du contrôle WebBrowser, et l'action se produit lorsque vous cliquez sur le bouton Aller à.

    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);
    }
    
  18. Pour tester le navigateur, appuyez sur F5.

    Le formulaire s'ouvre.

  19. Dans la zone de texte, tapez https://www.microsoft.com, puis cliquez sur Aller à.

    Le site Web Microsoft apparaît.

Pour créer la classe d'action personnalisée

  1. Dans le menu Fichier, pointez sur Ajouter, puis cliquez sur Nouveau projet.

  2. Dans la boîte de dialogue Ajouter un nouveau projet, cliquez sur Windows, puis sur Bibliothèque de classes.

  3. Dans la zone Nom, tapez NGenCustomAction, puis cliquez sur OK.

  4. Dans le menu Projet, cliquez sur Ajouter un nouvel élément.

  5. Dans la boîte de dialogue Ajouter un nouvel élément, cliquez sur Général, puis sur Classe Installer. Dans la zone Nom, tapez NGenCustomAction, puis cliquez sur Ajouter.

    Notes

    Assurez-vous que vous ajoutez une Classe Installer ; sinon, le fichier de code n'aura pas les instructions using nécessaires.

  6. Dans l'Explorateur de solutions, supprimez le fichier de code Class1 du projet NGenCustomAction.

Pour ajouter du code à l'action personnalisée

  1. Cliquez avec le bouton droit sur le fichier de code source dans l'Explorateur de solutions (ou sur l'aire de conception), puis cliquez sur Afficher le code pour ouvrir l'Éditeur de code. Ajoutez le code suivant en haut du module.

    Imports System.IO
    Imports System.Diagnostics
    
    using System.IO;
    using System.Diagnostics;
    
  2. Mettez la déclaration de la classe à jour afin qu'elle hérite de la classe System.Configuration.Install.Installer.

    Inherits System.Configuration.Install.Installer
    
    : System.Configuration.Install.Installer
    
  3. Dans le fichier de code NGenCustomAction, ajoutez la méthode d'assistance suivante pour générer le fichier de code d'image natif pour n'importe quel assembly.

        <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);
                    }
                }
            }
    
    
  4. Dans le fichier de code NGenCustomAction, ajoutez la procédure suivante pour substituer les procédures Install, Commit, Rollback et Uninstall de la classe de 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");
    }
    

Pour ajouter un projet de déploiement pour l'exemple d'application de navigateur

  1. Dans le menu Fichier, pointez sur Ajouter, puis cliquez sur Nouveau projet.

  2. Dans la boîte de dialogue Ajouter un nouveau projet, développez Autres types de projets, développez Projets de configuration et de déploiement, cliquez sur Programme d'installation de Visual Studio, puis sur Projet d'installation.

  3. Dans la zone Nom, tapez Browser Sample Installer, puis cliquez sur OK.

  4. Dans l'Éditeur du système de fichiers, sélectionnez Dossier d'application. Dans le menu Action, cliquez sur Ajouter.

    La boîte de dialogue Ajouter le groupe de sorties du projet apparaît.

  5. Dans la zone de liste déroulante fixe du projet, sélectionnez BrowserSample, cliquez sur Sortie de projet, puis sur OK.

  6. Dans l'Éditeur du système de fichiers, sélectionnez Dossier d'application. Dans le menu Action, cliquez sur Ajouter.

    La boîte de dialogue Ajouter le groupe de sorties du projet apparaît.

  7. Dans la zone de liste déroulante fixe du projet, sélectionnez NGenCustomAction, cliquez sur Sortie de projet, puis sur OK.

Pour ajouter l'action personnalisée NGEN au projet d'installation

  1. Dans l'Explorateur de solutions, cliquez sur le projet Browser Sample Installer.

  2. Dans le menu Affichage, pointez sur Éditeur et cliquez sur Actions personnalisées.

  3. Dans l'Éditeur des actions personnalisées, sélectionnez le nœud Actions personnalisées.

  4. Dans le menu Action, cliquez sur Ajouter une action personnalisée.

  5. Dans la boîte de dialogue Sélectionner un élément dans le projet, double-cliquez sur le Dossier d'application, cliquez sur Sortie principale de NGenCustomAction (Actif), puis sur OK.

    L'action personnalisée NGen est ajoutée aux quatre nœuds d'actions personnalisées.

  6. Dans le nœud Installer, cliquez sur Sortie principale de NGenCustomAction (Actif).

  7. Dans la fenêtre Propriétés, remplacez la propriété CustomActionData par /Args ="[TARGETDIR] BrowserSample.exe". Incluez les guillemets.

    Notes

    La propriété [TARGETDIR] correspond à l'emplacement du fichier exécutable installé. L'action personnalisée utilise ngen.exe pour convertir le fichier exécutable installé en une image native.

  8. Dans l'Explorateur de solutions, cliquez sur le projet d'installation Browser Sample Installer.

  9. Dans le menu Générer, cliquez sur Générer Browser Sample Installer.

Pour vérifier la génération de code natif

  1. Naviguez jusqu'au dossier d'installation et recherchez le fichier BrowserSample.exe. Par exemple %PROGRAMFILES%\CompanyName\Browser Sample Installer\BrowserSample.exe.

  2. Dans une invite de commandes Visual Studio, vérifiez que le fichier exécutable a été précompilé en code natif en exécutant le code suivant :

    ngen.exe display FullPathToExe
    

    Par exemple, vous pouvez exécuter la commande suivante :

    ngen.exe display "C:\Program Files (x86)\Microsoft\Browser Sample Installer\BrowserSample.exe"
    

    La sortie de commande apparaît.

    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>
    

    Notes

    Si ngen.exe n'affiche pas d'image native, vous pouvez trouver les journaux de ngen dans l'un des répertoires suivants :

    %SystemRoot%\Microsoft.NET\Framework\v<version CLR> %SystemRoot%\Microsoft.NET\Framework64\v<version CLR>

    Le fichier ngen.log est le journal de résolution des problèmes le plus récent.

Voir aussi

Référence

CustomActionData, propriété

Ngen.exe (Native Image Generator)

Concepts

Processus d'exécution managée

Autres ressources

Gestion des actions personnalisées lors d'un déploiement