Tutorial: Descargar ensamblados a petición con la API de implementación de ClickOnce mediante el diseñador

Actualización: noviembre 2007

De forma predeterminada, todos los ensamblados incluidos en una aplicación ClickOnce se descargan la primera vez que se ejecuta la aplicación. No obstante, puede haber partes de la aplicación que sólo las utilice un pequeño conjunto de usuarios. En este caso, sólo descargará un ensamblado cuando cree uno de los tipos. En el tutorial siguiente se muestra cómo marcar determinados ensamblados de la aplicación como "opcional" y cómo descargarlos utilizando clases en el espacio de nombres System.Deployment.Application cuando el Common Language Runtime los solicite.

Nota:

Para poder utilizar este procedimiento, es necesario que la aplicación se ejecute con plena confianza.

Nota:

Los cuadros de diálogo y comandos de menú que se muestran pueden diferir de los que se describen en la Ayuda, todo depende de los valores de configuración o de edición activos. Para cambiar su configuración, haga clic en Importar y exportar configuraciones en el menú Herramientas. Para obtener más información, consulte Valores de configuración de Visual Studio.

Crear los proyectos

Para crear un proyecto que utilice un ensamblado a petición con Visual Studio

  1. Cree un nuevo proyecto de formularios Windows Forms en Visual Studio. En el menú Archivo, elija Agregar y, después, haga clic en Nuevo proyecto. Elija un proyecto de la Biblioteca de clases en el cuadro de diálogo y denomínelo ClickOnceLibrary.

    Nota:

    En Visual Basic, es recomendable que modifique las propiedades del proyecto para cambiar el espacio de nombres raíz de este proyecto por Microsoft.Samples.ClickOnceOnDemand o por un espacio de nombres de su elección. Por simplificar, los dos proyectos de este tutorial están en el mismo espacio de nombres.

  2. Defina una clase denominada DynamicClass con una propiedad única denominada 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. Seleccione el proyecto de formularios Windows Forms en el Explorador de soluciones. Agregue una referencia al ensamblado System.Deployment.Application y una referencia al proyecto ClickOnceLibrary.

    Nota:

    En Visual Basic, es recomendable que modifique las propiedades del proyecto para cambiar el espacio de nombres raíz de este proyecto por Microsoft.Samples.ClickOnceOnDemand o por un espacio de nombres de su elección. Por simplificar, los dos proyectos de este tutorial se encuentran en el mismo espacio de nombres.

  4. Haga clic con el botón secundario en el formulario, haga clic en Ver código en el menú y agregue las siguientes referencias al formulario.

    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. Agregue el código siguiente para descargar este ensamblado a petición. Este código muestra cómo asignar un conjunto de ensamblados a un nombre de grupo usando una clase Dictionary genérica. Puesto que para la realización este tutorial sólo se ha descargado un ensamblado, sólo habrá un ensamblado en el grupo. En una aplicación real, todos los ensamblados relacionados con una misma característica de la aplicación se descargarían al mismo tiempo. La tabla de asignación facilita esta tarea, ya que asocia todas las DLL pertenecientes a una misma característica con un nombre de grupo de descarga.

    ' 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. En el menú Ver, haga clic en Cuadro de herramientas. Arrastre un Button desde el Cuadro de herramientas hasta el formulario. Haga doble clic en el botón y agregue el código siguiente al controlador de evento 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);
    }
    

Marcar los ensamblados como opcional

Para marcar los ensamblados como opcionales en la aplicación ClickOnce utilizando Visual Studio

  1. Haga clic con el botón secundario en el proyecto de formularios Windows Forms en el Explorador de soluciones y, a continuación, haga clic en Propiedades. Seleccione la ficha Publicar.

  2. Haga clic en el botón Archivos de aplicación.

  3. Busque la lista de ClickOnceLibrary.dll. Establezca la lista desplegable Estado de la publicación en Incluir.

  4. Expanda la lista desplegable Grupo y seleccione Nuevo. Escriba el nombre ClickOnceLibrary como el nuevo nombre de grupo.

  5. Continúe la publicación de la aplicación como se describe en Cómo: Publicar aplicaciones ClickOnce.

Para marcar los ensamblados como opcionales en la aplicación ClickOnce utilizando la herramienta de generación y edición de manifiestos, cliente gráfico (MageUI.exe)

  1. Cree los manifiestos ClickOnce como se describe en Tutorial: Implementar manualmente una aplicación ClickOnce.

  2. Antes de cerrar MageUI.exe, seleccione la ficha que contiene el manifiesto de aplicación de implementación y, dentro de la misma, seleccione la ficha Archivos.

  3. Busque ClickOnceLibrary.dll en la lista de archivos de la aplicación y establezca la columna Tipo de archivo en Ninguno. En la columna Grupo, escriba ClickOnceLibrary.dll.

Probar el nuevo ensamblado

Para probar el ensamblado a petición

  1. Inicie la aplicación implementada con ClickOnce.

  2. Cuando aparezca el formulario principal, presione Button. Verá una cadena en una ventana de cuadro de mensaje con el texto, "Hello, World!"

Vea también

Referencia

ApplicationDeployment