Поделиться через


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

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

ПримечаниеПримечание

Чтобы использовать эту процедуру, приложение должно выполняться с полным доверием.

ПримечаниеПримечание

Отображаемые диалоговые окна и команды меню могут отличаться от описанных в справке в зависимости от текущих настроек или выпуска.Чтобы изменить параметры, выберите Параметры импорта и экспорта в меню Сервис.Дополнительные сведения см. в разделе Параметры Visual Studio.

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

Создание проекта, который использует сборку по требованию, при помощи Visual Studio

  1. Создайте в Visual Studio новый проект Windows Forms.В меню Файл выберите Добавить, затем Новый проект.В диалоговом окне выберите проект Библиотека классов и назовите его ClickOnceLibrary.

    ПримечаниеПримечание

    В Visual Basic мы рекомендуем изменить свойства проекта, чтобы изменить корневое пространство имен для этого проекта на Microsoft.Samples.ClickOnceOnDemand или на произвольное пространство имен.Для простоты два проекта в этом пошаговом руководстве расположены в одном пространстве имен.

  2. Определите класс с именем DynamicClass и одним свойством Message.

    Public Class DynamicClass
        Sub New()
    
        End Sub
    
        Public ReadOnly Property Message() As String
            Get
                Message = "Hello, world!"
            End Get
        End Property
    End Class
    
    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. Правой кнопкой мыши щелкните форму, из меню выберите Просмотреть код и добавьте следующие ссылки на форму.

    Imports System.Reflection
    Imports System.Deployment.Application
    Imports System.Collections.Generic
    Imports Microsoft.Samples.ClickOnceOnDemand
    Imports System.Security.Permissions
    
    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. 
    Dim DllMappingTable As New Dictionary(Of String, String)()
    
    <SecurityPermission(SecurityAction.Demand, ControlAppDomain:=True)> _
    Sub New()
        ' This call is required by the Windows Form Designer.
        InitializeComponent()
    
        ' Add any initialization after the InitializeComponent() call.
        DllMappingTable("ClickOnceLibrary") = "ClickOnceLibrary"
    End Sub
    
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        AddHandler AppDomain.CurrentDomain.AssemblyResolve, AddressOf Me.CurrentDomain_AssemblyResolve
    End Sub
    
    Private Function CurrentDomain_AssemblyResolve(ByVal sender As Object, ByVal args As ResolveEventArgs) As System.Reflection.Assembly
        Dim NewAssembly As Assembly = Nothing
    
        If (ApplicationDeployment.IsNetworkDeployed) Then
            Dim Deploy As ApplicationDeployment = ApplicationDeployment.CurrentDeployment
    
            ' Get the DLL name from the argument.
            Dim NameParts As String() = args.Name.Split(",")
            Dim DllName As String = NameParts(0)
            Dim DownloadGroupName As String = DllMappingTable(DllName)
    
            Try
                Deploy.DownloadFileGroup(DownloadGroupName)
            Catch ex As Exception
                MessageBox.Show("Could not download file group from Web server. Contact administrator. Group name: " & DownloadGroupName & "; DLL name: " & args.Name)
                Throw (ex)
            End Try
    
            ' 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 ex As Exception
                Throw (ex)
            End Try
        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.")
        End If
    
        Return NewAssembly
    End Function
    
    // 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 Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim DC As New DynamicClass()
        MessageBox.Show("Message is " & DC.Message)
    End Sub
    
    private void getAssemblyButton_Click(object sender, EventArgs e)
    {
        DynamicClass dc = new DynamicClass();
        MessageBox.Show("Message: " + dc.Message);
    }
    

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

Пометка сборок как необязательные в приложении ClickOnce при помощи Visual Studio

  1. В обозревателе решений щелкните правой кнопкой мыши проект Windows Forms и выберите Свойства.Перейдите на вкладку Публикация.

  2. Нажмите кнопку Файлы приложения.

  3. Найдите список для ClickOnceLibrary.dll.В раскрывающемся списке Состояние публикации выберите Включить.

  4. Раскройте раскрывающийся список Группа и выберите Создать.Введите имя ClickOnceLibrary в качестве имени новой группы.

  5. Продолжите публиковать приложение, как описано в разделе Практическое руководство. Публикация приложения ClickOnce с помощью мастера публикации.

Пометка сборок как необязательные в приложении ClickOnce при помощи средства создания и изменения манифеста — графический клиент (MageUI.exe)

  1. Создайте манифест ClickOnce, как описано в разделе Разбор примера: развертывание вручную приложения ClickOnce.

  2. Перед закрытием MageUI.exe выберите вкладку, содержащую манифест приложения развертывания, и на этой вкладке перейдите на вкладку Файлы.

  3. В списке файлов приложения найдите ClickOnceLibrary.dll и установите для него в столбце Тип файла значение Отсутствует.В столбце Группа введите ClickOnceLibrary.dll.

Проверка новой сборки

Чтобы проверить сборку по требованию

  1. Запустите приложение, развернутое при помощи ClickOnce.

  2. Когда появится главная форма, нажмите кнопку Button.В окне сообщения должна быть видна строка "Hello, World!".

См. также

Ссылки

ApplicationDeployment