Freigeben über


Exemplarische Vorgehensweise: Erstellen eines benutzerdefinierten Installers für eine ClickOnce-Anwendung

Jede ClickOnce-Anwendung, die auf einer .exe Datei basiert, kann von einem benutzerdefinierten Installationsprogramm automatisch installiert und aktualisiert werden. Ein benutzerdefiniertes Installationsprogramm kann während der Installation benutzerdefinierte Benutzerfreundlichkeit implementieren, einschließlich benutzerdefinierter Dialogfelder für Sicherheits- und Wartungsvorgänge. Zum Ausführen von Installationsvorgängen verwendet das benutzerdefinierte Installationsprogramm die InPlaceHostingManager Klasse. In dieser exemplarischen Vorgehensweise wird veranschaulicht, wie Sie ein benutzerdefiniertes Installationsprogramm erstellen, das automatisch eine ClickOnce-Anwendung installiert.

Hinweis

Die ApplicationDeployment Klasse und APIs im System.Deployment.Application Namespace werden in .NET Core und .NET 5 und höher nicht unterstützt. In .NET 7 wird eine neue Methode für den Zugriff auf Anwendungsbereitstellungseigenschaften unterstützt. Weitere Informationen finden Sie unter Access ClickOnce-Bereitstellungseigenschaften in .NET. .NET 7 unterstützt nicht das Äquivalent von ApplicationDeployment-Methoden.

Voraussetzungen

So erstellen Sie ein benutzerdefiniertes ClickOnce-Anwendungsinstallationsprogramm

  1. Fügen Sie in Ihrer ClickOnce-Anwendung Verweise auf "System.Deployment" und "System.Windows.Forms" hinzu.

  2. Fügen Sie Ihrer Anwendung eine neue Klasse hinzu, und geben Sie einen beliebigen Namen an. In dieser exemplarischen Vorgehensweise wird der Name MyInstallerverwendet.

  3. Fügen Sie oben in Ihrer neuen Klasse die folgenden Imports oder using Direktiven hinzu.

    using System.Deployment.Application;
    using System.Windows.Forms;
    
  4. Fügen Sie der Klasse die folgenden Methoden hinzu.

    Diese Methoden rufen InPlaceHostingManager Methoden auf, um das Bereitstellungsmanifest herunterzuladen, geeignete Berechtigungen zu bestätigen, den Benutzer um die Berechtigung zum Installieren zu bitten und dann die Anwendung in den ClickOnce-Cache herunterzuladen und zu installieren. Ein benutzerdefiniertes Installationsprogramm kann angeben, dass eine ClickOnce-Anwendung vorab vertrauenswürdig ist, oder die Vertrauensentscheidung auf den AssertApplicationRequirements Methodenaufruf zurückstellen kann. Dieser Code vertraut der Anwendung im Voraus.

    Hinweis

    Berechtigungen, die aufgrund von Vorabvertrauen zugewiesen wurden, dürfen die Berechtigungen des benutzerdefinierten Installationscodes nicht überschreiten.

    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 application 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. Rufen Sie die InstallApplication Methode auf, um die Installation von Ihrem Code aus zu versuchen. Wenn Sie z. B. Ihre Klasse MyInstaller benannt haben, können Sie InstallApplication wie folgt aufrufen.

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

Nächste Schritte

Eine ClickOnce-Anwendung kann auch eine benutzerdefinierte Updatelogik hinzufügen, einschließlich einer benutzerdefinierten Benutzeroberfläche, die während des Aktualisierungsprozesses angezeigt werden soll. Weitere Informationen finden Sie unter UpdateCheckInfo. Eine ClickOnce-Anwendung kann auch den standardmäßigen Startmenüeintrag, die Verknüpfung und den Eintrag "Programme hinzufügen oder entfernen" mithilfe eines <customUX> Elements unterdrücken. Weitere Informationen finden Sie unter <entryPoint-Element> und ShortcutAppId.