逐步解說:建立 ClickOnce 應用程式的自訂安裝程式Walkthrough: Create a custom installer for a ClickOnce application

任何以 .exe 檔案為基礎的 ClickOnce 應用程式,都可以由自訂安裝程式以無訊息方式安裝和更新 Any ClickOnce application based on an .exe file can be silently installed and updated by a custom installer. 自訂安裝程式可以在安裝期間執行自訂的使用者體驗,包括安全性和維護作業的自訂對話方塊。A custom installer can implement custom user experience during installation, including custom dialog boxes for security and maintenance operations. 若要執行安裝作業,自訂安裝程式會使用 InPlaceHostingManager 類別。To perform installation operations, the custom installer uses the InPlaceHostingManager class. 本逐步解說示範如何建立以無訊息方式安裝 ClickOnce 應用程式的自訂安裝程式。This walkthrough demonstrates how to create a custom installer that silently installs a ClickOnce application.

PrerequisitesPrerequisites

若要建立自訂 ClickOnce 應用程式安裝程式To create a custom ClickOnce application installer

  1. 在您的 ClickOnce 應用程式中,新增對 System.web 和 System.web 的參考。In your ClickOnce application, add references to System.Deployment and System.Windows.Forms.

  2. 將新類別新增至您的應用程式,並指定任何名稱。Add a new class to your application and specify any name. 這個逐步解說使用的名稱為 MyInstallerThis walkthrough uses the name MyInstaller.

  3. 將下列 Importsusing 指示詞新增至新類別的頂端。Add the following Imports or using directives to the top of your new class.

    Imports System.Deployment.Application
    Imports System.Windows.Forms
    
    using System.Deployment.Application;
    using System.Windows.Forms;
    
  4. 將下列方法新增至您的類別。Add the following methods to your class.

    這些方法會呼叫 InPlaceHostingManager 方法來下載部署資訊清單、判斷提示適當的許可權、要求使用者提供安裝的許可權,然後將應用程式下載並安裝到 ClickOnce 快取。These methods call InPlaceHostingManager methods to download the deployment manifest, assert appropriate permissions, ask the user for permission to install, and then download and install the application into the ClickOnce cache. 自訂安裝程式可以指定 ClickOnce 應用程式是預先信任的,或可將信任決策延後至 AssertApplicationRequirements 方法呼叫。A custom installer can specify that a ClickOnce application is pre-trusted, or can defer the trust decision to the AssertApplicationRequirements method call. 此程式碼會預先信任應用程式。This code pre-trusts the application.

    注意

    預先信任指派的許可權不能超過自訂安裝程式碼的許可權。Permissions assigned by pre-trusting cannot exceed the permissions of the custom installer code.

        Dim WithEvents iphm As InPlaceHostingManager = Nothing
    
        Public Sub InstallApplication(ByVal deployManifestUriStr As String)
            Try
                Dim deploymentUri As New Uri(deployManifestUriStr)
                iphm = New InPlaceHostingManager(deploymentUri, False)
                MessageBox.Show("Created the object.")
            Catch uriEx As UriFormatException
                MessageBox.Show("Cannot install the application: " & _
                                "The deployment manifest URL supplied is not a valid URL." & _
                                "Error: " & uriEx.Message)
                Return
            Catch platformEx As PlatformNotSupportedException
                MessageBox.Show("Cannot install the application: " & _
                                "This program requires Windows XP or higher. " & _
                                "Error: " & platformEx.Message)
                Return
            Catch argumentEx As ArgumentException
                MessageBox.Show("Cannot install the application: " & _
                                "The deployment manifest URL supplied is not a valid URL." & _
                                "Error: " & argumentEx.Message)
                Return
            End Try
    
            iphm.GetManifestAsync()
        End Sub
    
        Private Sub iphm_GetManifestCompleted(ByVal sender As Object, ByVal e As GetManifestCompletedEventArgs) Handles iphm.GetManifestCompleted
            ' Check for an error.
            If (e.Error IsNot Nothing) Then
                ' Cancel download and install.
                MessageBox.Show("Could not download manifest. Error: " & e.Error.Message)
                Return
            End If
    
            ' Dim isFullTrust As Boolean = 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 ex As Exception
                MessageBox.Show("An error occurred while verifying the application. " & _
                                "Error text: " & ex.Message)
                Return
            End Try
    
            ' Use the information from GetManifestCompleted() to confirm 
            ' that the user wants to proceed.
            Dim appInfo As String = "Application Name: " & e.ProductName
            appInfo &= ControlChars.Lf & "Version: " & e.Version.ToString()
            appInfo &= ControlChars.Lf & "Support/Help Requests: "
    
            If Not (e.SupportUri Is Nothing) Then
                appInfo &= e.SupportUri.ToString()
            Else
                appInfo &= "N/A"
            End If
    
            appInfo &= ControlChars.Lf & ControlChars.Lf & _
                "Confirmed that this application can run with its requested permissions."
    
            ' If isFullTrust Then
            '    appInfo &= ControlChars.Lf & ControlChars.Lf & _
            '        "This application requires full trust in order to run."
            ' End If
    
            appInfo &= ControlChars.Lf & ControlChars.Lf & "Proceed with installation?"
    
            Dim dr As DialogResult = MessageBox.Show(appInfo, _
                "Confirm Application Install", MessageBoxButtons.OKCancel, MessageBoxIcon.Question)
            If dr <> System.Windows.Forms.DialogResult.OK Then
                Return
            End If
    
            ' Download the deployment manifest. 
            ' Usually, this shouldn't throw an exception unless 
            ' AssertApplicationRequirements() failed, or you did not call that method
            ' before calling this one.
            Try
                iphm.DownloadApplicationAsync()
            Catch downloadEx As Exception
                MessageBox.Show("Cannot initiate download of application. Error: " & downloadEx.Message)
                Return
            End Try
        End Sub
    
    #If 0 Then
        Private Function CheckForFullTrust(ByVal appManifest As XmlReader) As Boolean
            Dim isFullTrust As Boolean = False
    
            If (appManifest Is Nothing) Then
                Throw New ArgumentNullException("appManifest cannot be null.")
            End If
    
            Dim xaUnrestricted As 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 Then
                If xaUnrestricted.Value = "true" Then
                    Return True
                End If
            End If
    
            Return False
        End Function
    #End If
    
        Private Sub iphm_DownloadProgressChanged(ByVal sender As Object, ByVal e As DownloadProgressChangedEventArgs) Handles iphm.DownloadProgressChanged
            ' you can show percentage of task completed using e.ProgressPercentage
        End Sub
    
        Private Sub iphm_DownloadApplicationCompleted(ByVal sender As Object, ByVal e As DownloadApplicationCompletedEventArgs) Handles iphm.DownloadApplicationCompleted
            ' Check for an error.
            If (e.Error IsNot Nothing) Then
                ' Cancel download and install.
                MessageBox.Show("Could not download and install application. Error: " & e.Error.Message)
                Return
            End If
    
            ' Inform the user that their application is ready for use. 
            MessageBox.Show("Application installed! You may now run it from the Start menu.")
        End Sub
    
    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. 若要從您的程式碼嘗試安裝,請呼叫 InstallApplication 方法。To attempt installation from your code, call the InstallApplication method. 例如,如果您將類別命名為 MyInstaller,您可能會以下列方式呼叫 InstallApplicationFor example, if you named your class MyInstaller, you might call InstallApplication in the following way.

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

後續步驟Next steps

ClickOnce 應用程式也可以新增自訂的更新邏輯,包括要在更新程式中顯示的自訂使用者介面。A ClickOnce application can also add custom update logic, including a custom user interface to show during the update process. 如需詳細資訊,請參閱UpdateCheckInfoFor more information, see UpdateCheckInfo. ClickOnce 應用程式也可以使用 <customUX> 元素來隱藏標準 [開始] 功能表項目、快捷方式和 [新增或移除程式] 專案。A ClickOnce application can also suppress the standard Start menu entry, shortcut, and Add or Remove Programs entry by using a <customUX> element. 如需詳細資訊,請參閱<entryPoint > 元素ShortcutAppIdFor more information, see <entryPoint> element and ShortcutAppId.

請參閱See also