Compartilhar via


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

Por padrão, todos os assemblies incluídos em um ClickOnce aplicativo são baixados quando o aplicativo é executado pela primeira vez. No entanto, você pode ter partes da aplicação que são usados por um pequeno conjunto de seus usuários. Nesse caso, você deseja fazer o download de um assembly somente quando você cria um de seus tipos. A instrução a seguir demonstra como marcar determinados assemblies em seu aplicativo como "opcional", e como baixá-los usando classes de System.Deployment.Application namespace quando o common language runtime (CLR) os requer.

Dica

Seu aplicativo terá executado em confiança total para usar este procedimento.

Pré-requisitos

Você precisará de um dos seguintes componentes para concluir este passo a passo:

  • O SDK do Windows. O SDK do Windows pode ser baixado do Centro de Download da Microsoft.

  • O Visual Studio.

Criação de projetos

Para criar um projeto que usa um assembly sob demanda

  1. Crie um diretório chamado ClickOnceOnDemand.

  2. Abra o Prompt de comando do Windows SDK ou o Visual Studio o Prompt de comando.

  3. Mude para o diretório ClickOnceOnDemand.

  4. Gere um par de chaves pública/privada usando o seguinte comando:

    sn -k TestKey.snk
    
  5. Usando o bloco de notas ou outro editor de texto, definir uma classe chamada DynamicClass com uma propriedade única chamada 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!");
                }
            }
        }
    }
    
  6. Salvar o texto como um arquivo chamado ClickOnceLibrary.cs ou ClickOnceLibrary.vb, dependendo do idioma usado para o diretório ClickOnceOnDemand.

  7. Compile o arquivo em um assembly.

    csc /target:library /keyfile:TestKey.snk ClickOnceLibrary.cs
    
    vbc /target:library /keyfile:TestKey.snk ClickOnceLibrary.vb
    
  8. Para obter a chave pública token para o assembly, use o seguinte comando:

    sn -T ClickOnceLibrary.dll
    
  9. Crie um novo arquivo usando seu texto editor e digite o seguinte código. Esse código cria um aplicativo Windows Forms que baixa o conjunto de ClickOnceLibrary, quando necessário.

    Imports System
    Imports System.Windows.Forms
    Imports System.Deployment.Application
    Imports System.Drawing
    Imports System.Reflection
    Imports System.Collections.Generic
    Imports Microsoft.Samples.ClickOnceOnDemand
    
    
    Namespace Microsoft.Samples.ClickOnceOnDemand
       <System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, Unrestricted:=true)> _
       Class Form1
          Inherits 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.  
            Dim DllMapping as Dictionary(Of String, String) = new Dictionary(of String, String)()
    
          Public Sub New()
             ' Add button to form. 
                Dim GetAssemblyButton As New Button()
                GetAssemblyButton.Location = New Point(100, 100)
                GetAssemblyButton.Text = "Get assembly on demand" 
                AddHandler GetAssemblyButton.Click, AddressOf GetAssemblyButton_Click
    
                Me.Controls.Add(GetAssemblyButton)
    
                DllMapping("ClickOnceLibrary") = "ClickOnceLibrary" 
                AddHandler AppDomain.CurrentDomain.AssemblyResolve, AddressOf CurrentDomain_AssemblyResolve
          End Sub
    
            <STAThread()> _
            Shared Sub Main()
                Application.EnableVisualStyles()
                Application.Run(New Form1())
            End Sub 
    
            Private Function CurrentDomain_AssemblyResolve(ByVal sender As Object, ByVal args As ResolveEventArgs) As Assembly
                If ApplicationDeployment.IsNetworkDeployed Then 
                    Dim deploy As ApplicationDeployment = ApplicationDeployment.CurrentDeployment
    
                    ' Get the DLL name from the Name argument. 
                    Dim nameParts() as String = args.Name.Split(",")
                    Dim dllName as String = nameParts(0)
            Dim downloadGroupName as String = DllMapping(dllName)
    
                    Try
                        deploy.DownloadFileGroup(downloadGroupName)
                    Catch de As DeploymentException
    
                    End Try 
    
                    ' Load the assembly. 
                    Dim newAssembly As Assembly = Nothing 
    
                    Try
                        newAssembly = Assembly.LoadFile(Application.StartupPath & "\\" & dllName & ".dll," & _  
                "Version=1.0.0.0, Culture=en, PublicKeyToken=03689116d3a4ae33")
                    Catch ex As Exception
                        MessageBox.Show("Could not download assembly on demand.")
                    End Try
    
                    CurrentDomain_AssemblyResolve = newAssembly
                Else
                    CurrentDomain_AssemblyResolve = Nothing 
                End If 
            End Function 
    
            Private Sub GetAssemblyButton_Click(ByVal sender As Object, ByVal e As EventArgs)
                Dim ourClass As New DynamicClass()
                MessageBox.Show("DynamicClass string is: " + ourClass.Message)
            End Sub 
        End Class 
    End Namespace
    
    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. No código, localize a chamada para LoadFile.

  11. Definir PublicKeyToken o valor que você recuperou anteriormente.

  12. Salve o arquivo como um Form1. cs ou Form1. vb.

  13. Compilá-lo em um executável usando o comando a seguir.

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

Marcando os Assemblies como opcional

Marcar assemblies como opcionais em seu aplicativo de ClickOnce usando MageUI.exe

  1. Usando MageUI.exe, criar um manifesto de aplicativo, conforme descrito em Instruções passo a passo: implantando um aplicativo ClickOnce manualmente. Use as configurações a seguir para obter o manifesto de aplicativo:

    • Nomeie o manifesto do aplicativo ClickOnceOnDemand.

    • Sobre o arquivos página, na linha ClickOnceLibrary.dll, defina a Tipo de arquivo coluna para Nenhum.

    • Sobre o arquivos página, na linha ClickOnceLibrary.dll, tipo ClickOnceLibrary.dll na grupo coluna.

  2. Usando MageUI.exe, criar um manifesto de implantação, conforme descrito em Instruções passo a passo: implantando um aplicativo ClickOnce manualmente. Use as configurações a seguir para obter o manifesto de implantação:

    • Nomeie o manifesto de implantação ClickOnceOnDemand.

Novo conjunto de teste.

Para testar seu assembly sob demanda

  1. Carregar seu ClickOnce a implantação em um servidor Web.

  2. Iniciar o aplicativo implantado com ClickOnce em um navegador da Web digitando a URL para o manifesto de implantação. Se você chamar o ClickOnce aplicativo ClickOnceOnDemande carregá-lo para o diretório raiz de adatum.com, seu URL ficaria assim:

    http://www.adatum.com/ClickOnceOnDemand/ClickOnceOnDemand.application
    
  3. Quando o formulário principal for exibida, pressione a Button. Você deve ver uma seqüência de caracteres em uma janela de caixa de mensagem que diz "Hello, World!".

Consulte também

Referência

ApplicationDeployment