Procédure pas à pas : créer un programme d’installation personnalisé pour une application ClickOnce

Toute application ClickOnce basée sur un fichier .exe peut être installée et mise à jour en mode silencieux par un programme d’installation personnalisé. Un programme d’installation personnalisé peut implémenter une expérience utilisateur personnalisée pendant l’installation, y compris des boîtes de dialogue personnalisées pour les opérations de sécurité et de maintenance. Pour effectuer des opérations d’installation, le programme d’installation personnalisé utilise la classe InPlaceHostingManager. Cette procédure pas à pas montre comment créer un programme d’installation personnalisé qui installe en mode silencieux une application ClickOnce.

Notes

La classe ApplicationDeployment et les API de l’espace de noms System.Deployment.Application ne sont pas prises en charge dans .NET Core, .NET 5 et les versions ultérieures. Dans .NET 7, une nouvelle méthode d’accès aux propriétés de déploiement d’application est prise en charge. Pour plus d’informations, consultez Accéder aux propriétés de déploiement ClickOnce dans .NET. .NET 7 ne prend pas en charge l’équivalent des méthodes ApplicationDeployment.

Prérequis

Pour créer un programme d’installation d’application ClickOnce personnalisé

  1. Dans votre application ClickOnce, ajoutez des références à System.Deployment et System.Windows.Forms.

  2. Ajoutez une nouvelle classe à votre application et spécifiez n’importe quel nom. Cette procédure pas à pas utilise le nom MyInstaller.

  3. Ajoutez les directives Imports ou using suivantes en haut de votre nouvelle classe.

    using System.Deployment.Application;
    using System.Windows.Forms;
    
  4. Ajoutez la méthode suivante à votre classe.

    Ces méthodes appellent des méthodes InPlaceHostingManager pour télécharger le manifeste de déploiement, demander les autorisations appropriées, demander à l’utilisateur l’autorisation d’installer l’application, puis télécharger et installer l’application dans le cache ClickOnce. Un programme d’installation personnalisé peut spécifier qu’une application ClickOnce est pré-approuvée, ou peut reporter la décision d’approbation à l’appel de méthode AssertApplicationRequirements. Ce code pré-approuve l’application.

    Notes

    Les autorisations attribuées par pré-approbation ne peuvent pas dépasser les autorisations du code du programme d’installation personnalisé.

    InPlaceHostingManager iphm = null;
    
    public void InstallApplication(string deployManifestUriStr)
    {
        try
        {
            Uri deploymentUri = new Uri(deployManifestUriStr);
            iphm = new InPlaceHostingManager(deploymentUri, false);
        }
        catch (UriFormatException uriEx)
        {
            MessageBox.Show("Cannot install the application: " + 
                "The deployment manifest URL supplied is not a valid URL. " +
                "Error: " + uriEx.Message);
            return;
        }
        catch (PlatformNotSupportedException platformEx)
        {
            MessageBox.Show("Cannot install the application: " + 
                "This program requires Windows XP or higher. " +
                "Error: " + platformEx.Message);
            return;
        }
        catch (ArgumentException argumentEx)
        {
            MessageBox.Show("Cannot install the application: " + 
                "The deployment manifest URL supplied is not a valid URL. " +
                "Error: " + argumentEx.Message);
            return;
        }
    
        iphm.GetManifestCompleted += new EventHandler<GetManifestCompletedEventArgs>(iphm_GetManifestCompleted);
        iphm.GetManifestAsync();
    }
    
    void iphm_GetManifestCompleted(object sender, GetManifestCompletedEventArgs e)
    {
        // Check for an error.
        if (e.Error != null)
        {
            // Cancel download and install.
            MessageBox.Show("Could not download manifest. Error: " + e.Error.Message);
            return;
        }
    
        // bool isFullTrust = CheckForFullTrust(e.ApplicationManifest);
    
        // Verify this application can be installed.
        try
        {
            // the true parameter allows InPlaceHostingManager
            // to grant the permissions requested in the applicaiton manifest.
            iphm.AssertApplicationRequirements(true) ; 
        }
        catch (Exception ex)
        {
            MessageBox.Show("An error occurred while verifying the application. " +
                "Error: " + ex.Message);
            return;
        }
    
        // Use the information from GetManifestCompleted() to confirm 
        // that the user wants to proceed.
        string appInfo = "Application Name: " + e.ProductName;
        appInfo += "\nVersion: " + e.Version;
        appInfo += "\nSupport/Help Requests: " + (e.SupportUri != null ?
            e.SupportUri.ToString() : "N/A");
        appInfo += "\n\nConfirmed that this application can run with its requested permissions.";
        // if (isFullTrust)
        // appInfo += "\n\nThis application requires full trust in order to run.";
        appInfo += "\n\nProceed with installation?";
    
        DialogResult dr = MessageBox.Show(appInfo, "Confirm Application Install",
            MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
        if (dr != System.Windows.Forms.DialogResult.OK)
        {
            return;
        }
    
        // Download the deployment manifest. 
        iphm.DownloadProgressChanged += new EventHandler<DownloadProgressChangedEventArgs>(iphm_DownloadProgressChanged);
        iphm.DownloadApplicationCompleted += new EventHandler<DownloadApplicationCompletedEventArgs>(iphm_DownloadApplicationCompleted);
    
        try
        {
            // Usually this shouldn't throw an exception unless AssertApplicationRequirements() failed, 
            // or you did not call that method before calling this one.
            iphm.DownloadApplicationAsync();
        }
        catch (Exception downloadEx)
        {
            MessageBox.Show("Cannot initiate download of application. Error: " +
                downloadEx.Message);
            return;
        }
    }
    
    /*
    private bool CheckForFullTrust(XmlReader appManifest)
    {
        if (appManifest == null)
        {
            throw (new ArgumentNullException("appManifest cannot be null."));
        }
    
        XAttribute xaUnrestricted =
            XDocument.Load(appManifest)
                .Element("{urn:schemas-microsoft-com:asm.v1}assembly")
                .Element("{urn:schemas-microsoft-com:asm.v2}trustInfo")
                .Element("{urn:schemas-microsoft-com:asm.v2}security")
                .Element("{urn:schemas-microsoft-com:asm.v2}applicationRequestMinimum")
                .Element("{urn:schemas-microsoft-com:asm.v2}PermissionSet")
                .Attribute("Unrestricted"); // Attributes never have a namespace
    
        if (xaUnrestricted != null)
            if (xaUnrestricted.Value == "true")
                return true;
    
        return false;
    }
    */
    
    void iphm_DownloadApplicationCompleted(object sender, DownloadApplicationCompletedEventArgs e)
    {
        // Check for an error.
        if (e.Error != null)
        {
            // Cancel download and install.
            MessageBox.Show("Could not download and install application. Error: " + e.Error.Message);
            return;
        }
    
        // Inform the user that their application is ready for use. 
        MessageBox.Show("Application installed! You may now run it from the Start menu.");
    }
    
    void iphm_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        // you can show percentage of task completed using e.ProgressPercentage
    }
    
  5. Pour tenter l’installation à partir de votre code, appelez la méthode InstallApplication. Par exemple, si vous avez nommé votre classe MyInstaller, vous pouvez appeler InstallApplication de la manière suivante.

    MyInstaller installer = new MyInstaller();
    installer.InstallApplication(@"\\myServer\myShare\myApp.application");
    MessageBox.Show("Installer object created.");
    

Étapes suivantes

Une application ClickOnce peut également ajouter une logique de mise à jour personnalisée, notamment une interface utilisateur personnalisée à afficher pendant le processus de mise à jour. Pour plus d’informations, consultez UpdateCheckInfo. Une application ClickOnce peut également supprimer l’entrée de menu Démarrer standard, le raccourci et l’entrée Ajouter ou supprimer des programmes à l’aide d’un élément <customUX>. Pour plus d’informations, consultez Élément <entryPoint> et ShortcutAppId.