Instruções passo a passo: baixando assemblies por demanda com a API de implantação do ClickOnce usando o designer

Por padrão, todos os assemblies incluídos em um aplicativo ClickOnce são baixados quando o aplicativo é executado pela primeira vez. No entanto, pode haver partes do aplicativo que são usadas por um pequeno conjunto de usuários. Nesse caso, você deseja baixar um assembly somente quando criar um de seus tipos. O passo a passo a seguir demonstra como marcar determinados assemblies em seu aplicativo como "opcionais" e como baixá-los usando classes no namespace System.Deployment.Application quando o common language runtime os exige.

Observação

A classe ApplicationDeployment e as APIs no namespace System.Deployment.Application não têm suporte no .NET Core e no .NET 5 e versões posteriores. No .NET 7, há suporte para um novo método de acesso às propriedades de implantação de aplicativos. Para obter mais informações, consulte Acessar propriedades de implantação do ClickOnce no .NET. O .NET 7 não oferece suporte ao equivalente aos métodos ApplicationDeployment.

Observação

Seu aplicativo terá que ser executado com confiança total para usar esse procedimento.

Observação

As caixas de diálogo e os comandos de menu encontrados podem diferir daqueles descritos na Ajuda, dependendo das configurações ativas ou edição. Para alterar as configurações, clique em Importar e exportar configurações no menu Ferramentas. Para obter mais informações, consulte Redefinir as configurações.

Criar os projetos

Para criar um projeto que usa um assembly sob demanda com o Visual Studio

  1. Crie um novo projeto do Windows Forms no Visual Studio. No menu Arquivo, aponte para Adicionar e clique em Novo Projeto. Escolha um projeto da Biblioteca de Classes na caixa de diálogo e nomeie-o como ClickOnceLibrary.

    Observação

    No Visual Basic, recomendamos que você modifique as propriedades do projeto para alterar o namespace raiz deste projeto para Microsoft.Samples.ClickOnceOnDemand ou para um namespace de sua escolha. Para simplificar, os dois projetos neste passo a passo estão no mesmo namespace.

  2. Defina uma classe chamada DynamicClass com uma única propriedade chamada 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!");
                }
            }
        }
    }
    
  3. Selecione o projeto do Windows Forms no Gerenciador de Soluções. Adicione uma referência ao assembly System.Deployment.Application e uma referência de projeto ao projeto ClickOnceLibrary.

    Observação

    No Visual Basic, recomendamos que você modifique as propriedades do projeto para alterar o namespace raiz deste projeto para Microsoft.Samples.ClickOnceOnDemand ou para um namespace de sua escolha. Para simplificar, os dois projetos neste passo a passo estão localizados no mesmo namespace.

  4. Clique com o botão direito do mouse no formulário, clique em Exibir Código no menu e adicione as referências a seguir ao formulário.

    using System.Reflection;
    using System.Deployment.Application;
    using Microsoft.Samples.ClickOnceOnDemand;
    using System.Security.Permissions;
    
  5. Adicione o código a seguir para baixar esse assembly sob demanda. Esse código mostra como mapear um conjunto de assemblies para um nome de grupo usando uma classe genérica Dictionary. Como estamos baixando um único assembly neste passo a passo, há apenas um assembly em nosso grupo. Em um aplicativo real, é provável que você queira baixar todos os assemblies relacionados a um único recurso em seu aplicativo ao mesmo tempo. A tabela de mapeamento permite que você faça isso facilmente associando todas as DLLs que pertencem a um recurso com um nome de grupo de download.

    // 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. No menu Exibir , clique em Caixa de Ferramentas. Arraste um Button da Caixa de Ferramentas para o formulário. Clique duas vezes no botão e adicione o seguinte código ao manipulador de eventos Click.

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

Marcar assemblies como opcionais

Para marcar assemblies como opcionais em seu aplicativo ClickOnce usando o Visual Studio

  1. Clique com o botão direito do mouse no projeto Windows Forms no Gerenciador de Soluções e clique em Propriedades. Selecione a guia Publicar.

  2. Clique no botão Arquivos de Aplicativo .

  3. Localize a listagem de ClickOnceLibrary.dll. Defina a caixa suspensa Publicar Status como Incluir.

  4. Expanda a caixa suspensa Grupo e selecione Novo. Insira ClickOnceLibrary como o novo nome do grupo.

  5. Continue publicando seu aplicativo conforme descrito em Como publicar um aplicativo ClickOnce usando o Assistente de Publicação.

Para marcar assemblies como opcionais em seu aplicativo ClickOnce usando a Manifest Generation and Editing Tool – Cliente Gráfico (MageUI.exe)

  1. Crie seus manifestos do ClickOnce conforme descrito em Passo a passo: implantar manualmente um aplicativo ClickOnce.

  2. Antes de fechar MageUI.exe, selecione a guia que contém o manifesto do aplicativo da implantação e, nessa guia, selecione a guia Arquivos.

  3. Localize ClickOnceLibrary.dll na lista de arquivos de aplicativo e defina sua coluna Tipo de Arquivo como Nenhum. Na coluna Grupo, digite ClickOnceLibrary.dll.

Testar o novo assembly

Para testar seu assembly sob demanda:

  1. Inicie seu aplicativo implantado com o ClickOnce.

  2. Quando o formulário principal for exibido, pressione o Button. Você verá uma cadeia de caracteres em uma janela de caixa de mensagem que diz: "Hello, World!"