Пошаговое руководство. Скачивание сборок по запросу с помощью API развертывания ClickOnce

По умолчанию все сборки, включенные в приложение ClickOnce, загружаются при первом запуске приложения. Однако у вас могут быть части приложения, которые используются небольшим набором пользователей. В этом случае рекомендуется скачивать сборку только при создании одного из ее типов. В следующем примере показано, как пометить определенные сборки в приложении как "необязательные" и скачивать их с помощью классов в пространстве имен System.Deployment.Application, когда среда CLR нуждается в них.

Примечание.

Класс ApplicationDeployment и API в System.Deployment.Application пространстве имен не поддерживаются в .NET Core и .NET 5 и более поздних версиях. В .NET 7 поддерживается новый метод доступа к свойствам развертывания приложения. Дополнительные сведения см. в разделе "Свойства развертывания Access ClickOnce" в .NET. .NET 7 не поддерживает эквивалент методов ApplicationDeployment.

Примечание.

Для выполнения данной процедуры приложение должно выполняться с полным доверием.

Необходимые компоненты

Для выполнения этого пошагового руководства потребуется один из следующих компонентов:

  • Пакет SDK для Windows. Пакет SDK для Windows можно скачать из Центра загрузки Майкрософт.

  • Visual Studio.

Создание проектов

Создание проекта, использующего сборку по запросу

  1. Создайте каталог с именем ClickOnceOndemand.

  2. Откройте командную строку пакета SDK для Windows или командную строку Visual Studio.

  3. Перейдите в каталог ClickOnceOnDemand.

  4. Создайте пару открытого и закрытого ключа с помощью следующей команды:

    sn -k TestKey.snk
    
  5. С помощью Блокнот или другого текстового редактора определите класс с именем DynamicClass одного свойстваMessage.

    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!");
                }
            }
        }
    }
    
  6. Сохраните текст в виде файла с именем ClickOnceLibrary.cs или ClickOnceLibrary.vb в зависимости от используемого языка в каталог ClickOnceOnDemand.

  7. Скомпилируйте файл в сборку.

    csc /target:library /keyfile:TestKey.snk ClickOnceLibrary.cs
    
  8. Чтобы получить маркер открытого ключа для сборки, используйте следующую команду:

    sn -T ClickOnceLibrary.dll
    
  9. Создайте файл с помощью текстового редактора и введите следующий код. Этот код создает приложение Windows Forms, которое загружает сборку ClickOnceLibrary при необходимости.

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Reflection;
    using System.Deployment.Application;
    using Microsoft.Samples.ClickOnceOnDemand;
    
    namespace ClickOnceOnDemand
    {
        [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, Unrestricted=true)]
        public class Form1 : Form
        {
            // 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>();
    
            public static void Main()
            {
                Form1 NewForm = new Form1();
                Application.Run(NewForm);
            }
    
            public Form1()
            {
                // Configure form. 
                this.Size = new Size(500, 200);
                Button getAssemblyButton = new Button();
                getAssemblyButton.Size = new Size(130, getAssemblyButton.Size.Height);
                getAssemblyButton.Text = "Test Assembly";
                getAssemblyButton.Location = new Point(50, 50);
                this.Controls.Add(getAssemblyButton);
                getAssemblyButton.Click += new EventHandler(getAssemblyButton_Click);
    
                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," +  
                "Version=1.0.0.0, Culture=en, PublicKeyToken=03689116d3a4ae33");
                    }
                    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);
            }
    
            private void getAssemblyButton_Click(object sender, EventArgs e)
            {
                DynamicClass dc = new DynamicClass();
                MessageBox.Show("Message: " + dc.Message);
            }
        }
    }
    
  10. В коде найдите вызов LoadFile.

  11. ЗадайтеPublicKeyToken значение, полученное ранее.

  12. Сохраните файл как Form1.cs или Form1.vb.

  13. Скомпилируйте его в исполняемый файл с помощью следующей команды.

    csc /target:exe /reference:ClickOnceLibrary.dll Form1.cs
    

Пометка сборок как необязательных

Чтобы пометить сборки как необязательные в приложении ClickOnce с помощью MageUI.exe

  1. С помощью MageUI.exe создайте манифест приложения, как описано в пошаговом руководстве. Вручную разверните приложение ClickOnce. Используйте следующие параметры для манифеста приложения:

    • Присвойте манифесту ClickOnceOnDemandприложения имя.

    • На странице "Файлы" в строке ClickOnceLibrary.dll задайте для столбца "Тип файла" значение None.

    • На странице "Файлы" в строке ClickOnceLibrary.dll введите ClickOnceLibrary.dll столбец "Группа".

  2. С помощью MageUI.exe создайте манифест развертывания, как описано в пошаговом руководстве. Вручную разверните приложение ClickOnce. Используйте следующие параметры для манифеста развертывания:

    • Присвойте манифесту ClickOnceOnDemandразвертывания имя.

Тестирование новой сборки

Тестирование сборки по запросу

  1. Отправьте развертывание ClickOnce на веб-сервер.

  2. Запустите приложение, развернутое с помощью ClickOnce из веб-браузера, введя URL-адрес манифеста развертывания. Если вы вызываете приложение ClickOnceOnDemandClickOnce и отправляете его в корневой каталог adatum.com, URL-адрес будет выглядеть следующим образом:

    http://www.adatum.com/ClickOnceOnDemand/ClickOnceOnDemand.application
    
  3. Когда появится основная форма, нажмите Button. В окне сообщения вы должны видеть строку "Hello, World!".