Condividi tramite


Procedura dettagliata: download di assembly su richiesta con l'API della distribuzione ClickOnce tramite la finestra di progettazione

Aggiornamento: novembre 2007

Per impostazione predefinita, tutti gli assembly inclusi in un'applicazione ClickOnce vengono scaricati alla prima esecuzione dell'applicazione. È tuttavia possibile che alcune parti dell'applicazione vengano utilizzate da un gruppo limitato di utenti. In questo caso è preferibile scaricare un assembly solo quando viene creato uno dei relativi tipi. Nella procedura dettagliata riportata di seguito vengono illustrate le operazioni da eseguire per impostare come facoltativi determinati assembly inclusi nell'applicazione e per scaricarli, utilizzando classi dello spazio dei nomi System.Deployment.Application, quando richiesti da Common Language Runtime.

Nota:

L'applicazione dovrà essere eseguita in condizioni di attendibilità totale per utilizzare questa procedura.

Nota:

A seconda delle impostazioni attive o della versione del programma, è possibile che le finestre di dialogo e i comandi di menu visualizzati siano diversi da quelli descritti nella Guida. Per modificare le impostazioni, scegliere Importa/Esporta impostazioni dal menu Strumenti. Per ulteriori informazioni, vedere Impostazioni di Visual Studio.

Creazione dei progetti

Per creare un progetto che utilizza un assembly su richiesta mediante Visual Studio

  1. Creare un nuovo progetto Windows Form in Visual Studio. Scegliere Aggiungi dal menu File, quindi Nuovo progetto. Scegliere un progetto Libreria di classi nella finestra di dialogo e assegnare il nome ClickOnceLibrary a tale progetto.

    Nota:

    In Visual Basic si consiglia di modificare le proprietà del progetto, al fine di cambiare lo spazio dei nomi radice per il progetto in Microsoft.Samples.ClickOnceOnDemand o in uno spazio dei nomi a scelta. Per semplicità, i due progetti in questa procedura dettagliata sono nello stesso spazio dei nomi.

  2. Definire una classe DynamicClass con una singola proprietà 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. Selezionare il progetto Windows Forms in Esplora soluzioni. Aggiungere un riferimento all'assembly System.Deployment.Application e un riferimento al progetto ClickOnceLibrary.

    Nota:

    In Visual Basic si consiglia di modificare le proprietà del progetto, al fine di cambiare lo spazio dei nomi radice per il progetto in Microsoft.Samples.ClickOnceOnDemand o in uno spazio dei nomi a scelta. Per semplicità, i due progetti in questa procedura dettagliata sono nello stesso spazio dei nomi.

  4. Fare clic con il pulsante destro del mouse sul form, scegliere Visualizza codice dal menu, quindi aggiungere i seguenti riferimenti al form.

    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. Aggiungere il seguente codice per scaricare l'assembly su richiesta. Questo codice consente di eseguire il mapping di un set di assembly su un nome di gruppo utilizzando una classe Dictionary generica. Nel gruppo è presente un solo assembly perché la procedura dettagliata prevede che ne venga scaricato solo uno. Se si trattasse di una vera applicazione, verrebbero scaricati contemporaneamente tutti gli assembly relativi a un'unica funzionalità nell'applicazione. La tabella di mapping consente di eseguire questa operazione facilmente, associando tutte le DLL che appartengono a una funzionalità a un nome per il gruppo di 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. 
    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. Scegliere Casella degli strumenti dal menu Visualizza. Trascinare un controllo Button dalla Casella degli strumenti nel form. Fare doppio clic sul pulsante e aggiungere il seguente codice al gestore eventi 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);
    }
    

Impostazione degli assembly come facoltativi

Per impostare come facoltativi gli assembly nell'applicazione ClickOnce mediante Visual Studio

  1. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto Windows Forms e scegliere Proprietà. Fare clic sulla scheda Pubblica.

  2. Scegliere il pulsante File applicazione.

  3. Individuare l'elenco relativo al file ClickOnceLibrary.dll. Impostare la casella di riepilogo a discesa Stato pubblicazione su Includi.

  4. Selezionare Nuovo dalla casella di riepilogo a discesa Gruppo. Immettere il nome ClickOnceLibrarycome nuovo nome del gruppo.

  5. Continuare con la pubblicazione dell'applicazione come descritto in Procedura: pubblicare un'applicazione ClickOnce.

Per impostare come facoltativi gli assembly nell'applicazione ClickOnce mediante lo strumento client con interfaccia grafica per la generazione e la modifica di manifesti (MageUI.exe)

  1. Creare i manifesti ClickOnce come descritto in Procedura dettagliata: distribuzione manuale di un'applicazione ClickOnce.

  2. Prima di chiudere MageUI.exe, scegliere la scheda contenente il manifesto di distribuzione, quindi fare clic sulla scheda File.

  3. Individuare il file ClickOnceLibrary.dll nell'elenco di file dell'applicazione e impostare la relativa colonna Tipo file su Nessuno. Per la colonna Gruppo digitare ClickOnceLibrary.dll.

Test del nuovo assembly

Per testare l'assembly su richiesta

  1. Avviare l'applicazione distribuita con ClickOnce.

  2. Quando viene visualizzato il form principale, scegliere il controllo Button. Verrà visualizzata una finestra di messaggio contenente la stringa "Hello, World!".

Vedere anche

Riferimenti

ApplicationDeployment