Share via


逐步解說:依需求使用設計工具以 ClickOnce 部署 API 下載組件

第一次執行 ClickOnce 應用程式時,預設會下載該應用程式中包含的所有組件。 不過,可能是小部分使用者所使用之應用程式的組件。 在此情況下,只有在建立組件的其中一種類型時,才會想要下載組件。 下列逐步解說示範如何將應用程式中的特定組件標示為「選擇性」,以及在 Common Language Runtime 需要時,使用 System.Deployment.Application 中的類別來如何下載它們。

注意

.NET Core 和 .NET 5 和更新版本中不支援 System.Deployment.Application 命名空間中的 ApplicationDeployment 類別和 API。 .NET 7 支援存取應用程式部署屬性的新方法。 如需詳細資訊,請參閱在 .NET 中存取 ClickOnce 部署屬性。 .NET 7 不支援 ApplicationDeployment 方法的同等項。

注意

您的應用程式必須以完全信任執行,才能使用此程序。

注意

您看到的對話方塊與功能表命令,可能會因您所使用的設定或版本,而與說明中所述不同。 若要變更設定,請在 [工具] 功能表上按一下 [匯入和匯出設定] 。 如需詳細資訊,請參閱重設設定

建立專案

使用 Visual Studio 建立使用隨選組件的專案

  1. 在 Visual Studio 中隨即建立新的 Windows Forms 專案。 在 [檔案] 功能表上,指向 [加入],然後按一下 [新增專案]。 選擇對話方塊中的 [類別庫] 專案,並將它命名為 ClickOnceLibrary

    注意

    在 Visual Basic 中,建議您修改專案屬性,以將此專案的根命名空間變更為 Microsoft.Samples.ClickOnceOnDemand 或您選擇的命名空間。 為求簡單起見,本逐步解說中的兩個專案都位於相同的命名空間中。

  2. 定義具有單一屬性 DynamicClassMessage類別。

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace Microsoft.Samples.ClickOnceOnDemand
    {
        public class DynamicClass
        {
            public DynamicClass() {}
    
            public string Message
            {
                get
                {
                    return ("Hello, world!");
                }
            }
        }
    }
    
  3. 在方案總管 中,選取 Windows Forms 專案。 將參考新增至 System.Deployment.Application 組件,並將專案參考新增至 ClickOnceLibrary 專案。

    注意

    在 Visual Basic 中,建議您修改專案屬性,以將此專案的根命名空間變更為 Microsoft.Samples.ClickOnceOnDemand 或您選擇的命名空間。 為求簡單起見,本逐步解說中的兩個專案都位於相同的命名空間中。

  4. 以滑鼠右鍵按一下表單,並從功能表中按一下 [檢視程式碼] ,然後在表單中新增下列參考。

    using System.Reflection;
    using System.Deployment.Application;
    using Microsoft.Samples.ClickOnceOnDemand;
    using System.Security.Permissions;
    
  5. 新增下列程式碼,以視需要下載此組件。 此程式碼示範如何使用泛型 Dictionary 類別將一組組件對應至群組名稱。 因為我們只會下載本逐步解說中的單一組件,所以我們的群組中只會有一個組件。 在實際的應用程式中,您可能會想要同時下載與應用程式中單一功能相關的所有組件。 對應資料表可讓您輕鬆地進行這項作業,方法是將屬於某個功能的所有 DLL 都與下載群組名稱產生關聯。

    // Maintain a dictionary mapping DLL names to download file groups. This is trivial for this sample,
    // but will be important in real-world applications where a feature is spread across multiple DLLs,
    // and you want to download all DLLs for that feature in one shot. 
    Dictionary<String, String> DllMapping = new Dictionary<String, String>();
    
    [SecurityPermission(SecurityAction.Demand, ControlAppDomain=true)]
    public Form1()
    {
        InitializeComponent();
    
        DllMapping["ClickOnceLibrary"] = "ClickOnceLibrary";
        AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
    }
    
    /*
     * Use ClickOnce APIs to download the assembly on demand.
     */
    private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        Assembly newAssembly = null;
    
        if (ApplicationDeployment.IsNetworkDeployed)
        {
            ApplicationDeployment deploy = ApplicationDeployment.CurrentDeployment;
    
            // Get the DLL name from the Name argument.
            string[] nameParts = args.Name.Split(',');
            string dllName = nameParts[0];
            string downloadGroupName = DllMapping[dllName];
    
            try
            {
                deploy.DownloadFileGroup(downloadGroupName);
            }
            catch (DeploymentException de)
            {
                MessageBox.Show("Downloading file group failed. Group name: " + downloadGroupName + "; DLL name: " + args.Name);
                throw (de);
            }
    
            // Load the assembly.
            // Assembly.Load() doesn't work here, as the previous failure to load the assembly
            // is cached by the CLR. LoadFrom() is not recommended. Use LoadFile() instead.
            try
            {
                newAssembly = Assembly.LoadFile(Application.StartupPath + @"\" + dllName + ".dll");
            }
            catch (Exception e)
            {
                throw (e);
            }
        }
        else
        {
            //Major error - not running under ClickOnce, but missing assembly. Don't know how to recover.
            throw (new Exception("Cannot load assemblies dynamically - application is not deployed using ClickOnce."));
        }
    
    
        return (newAssembly);
    }
    
  6. 在 [檢視] 功能表上,按一下 [工具箱]。 將 Button 從 [工具箱] 拖曳至表單。 按兩下按鈕,並將下列程式碼新增至 Click 事件處理常式。

    private void getAssemblyButton_Click(object sender, EventArgs e)
    {
        DynamicClass dc = new DynamicClass();
        MessageBox.Show("Message: " + dc.Message);
    }
    

將組件標示為選擇性

使用 Visual Studio 將組件標示為 ClickOnce 應用程式中的選用項目

  1. 以滑鼠右鍵按一下方案總管 中的 Windows Forms 專案,然後按一下 [屬性] 。 選取 [發行] 索引標籤。

  2. 按一下 [應用程式檔案] 按鈕。

  3. 尋找 ClickOnceLibrary.dll 的清單。 將 [發行狀態] 下拉式方塊設定成 [包含]

  4. 展開 [群組] 下拉式方塊,然後選取 [新增] 。 輸入名稱 ClickOnceLibrary 作為新的群組名稱。

  5. 作法:使用發佈精靈發佈 ClickOnce 應用程式中所述,繼續發佈應用程式。

使用資訊清單產生和編輯工具 (圖形化用戶端 (MageUI.exe)) 將組件標示為 ClickOnce 應用程式中的選用項目

  1. 逐步解說:手動部署 ClickOnce 應用程式中所述,建立 ClickOnce 資訊清單。

  2. 關閉 MageUI.exe 之前,請選取包含您部署之應用程式資訊清單的索引標籤,然後在該索引標籤內選取 [檔案] 索引標籤。

  3. 在應用程式檔案清單中尋找 ClickOnceLibrary.dll,並將其 [檔案類型] 資料行設定成 [無] 。 在 [群組] 資料行中,輸入 ClickOnceLibrary.dll

測試新的組件

測試隨選組件:

  1. 啟動使用 ClickOnce 所部署的應用程式。

  2. 您的主要表單出現時,請按 Button。 您應該會在訊息方塊視窗中看到 "Hello, World!" 字串。