Procedura dettagliata: Scaricare assembly su richiesta con l'API di distribuzione ClickOnce

Per impostazione predefinita, tutti gli assembly inclusi in un'applicazione ClickOnce vengono scaricati quando l'applicazione viene eseguita per la prima volta. Tuttavia, potrebbero essere presenti parti dell'applicazione usate da un piccolo set di utenti. In questo caso, è consigliabile scaricare un assembly solo quando si crea uno dei relativi tipi. La procedura dettagliata riportata di seguito illustra come contrassegnare come "facoltativi" determinati assembly nell'applicazione e come scaricarli tramite le classi nello spazio dei nomi System.Deployment.Application quando sono richiesti da Common Language Runtime (CLR).

Nota

La ApplicationDeployment classe e le API nello System.Deployment.Application spazio dei nomi non sono supportate in .NET Core e .NET 5 e versioni successive. In .NET 7 è supportato un nuovo metodo di accesso alle proprietà di distribuzione dell'applicazione. Per altre informazioni, vedere Accedere alle proprietà di distribuzione ClickOnce in .NET. .NET 7 non supporta l'equivalente dei metodi ApplicationDeployment.

Nota

Per usare questa procedura, è necessario eseguire l'applicazione con attendibilità totale.

Prerequisiti

Per completare questa procedura dettagliata, è necessario uno dei componenti seguenti:

  • The Windows SDK. Windows SDK può essere scaricato dall'Area download Microsoft.

  • Visual Studio.

Creare i progetti

Per creare un progetto che usa un assembly su richiesta

  1. Creare una directory denominata ClickOnceOnDemand.

  2. Aprire il prompt dei comandi di Windows SDK o il prompt dei comandi di Visual Studio.

  3. Passare alla directory ClickOnceOnDemand.

  4. Generare una coppia di chiavi pubblica/privata usando il comando seguente:

    sn -k TestKey.snk
    
  5. Usando Blocco note o un altro editor di testo, definire una classe denominata con una singola proprietà denominata DynamicClassMessage.

    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. Salvare il testo come file denominato ClickOnceLibrary.cs o ClickOnceLibrary.vb, a seconda della lingua usata, nella directory ClickOnceOnDemand.

  7. Compilare il file in un assembly.

    csc /target:library /keyfile:TestKey.snk ClickOnceLibrary.cs
    
  8. Per ottenere il token di chiave pubblica per l'assembly, usare il comando seguente:

    sn -T ClickOnceLibrary.dll
    
  9. Creare un nuovo file usando l'editor di testo e immettere il codice seguente. Questo codice crea un'applicazione Windows Form che scarica l'assembly ClickOnceLibrary quando necessario.

    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. Nel codice individuare la chiamata a LoadFile.

  11. ImpostarePublicKeyToken sul valore recuperato in precedenza.

  12. Salvare il file come Form1.cs o Form1.vb.

  13. Compilarlo in un eseguibile usando il comando seguente.

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

Contrassegnare gli assembly come facoltativi

Per contrassegnare gli assembly come facoltativi nell'applicazione ClickOnce usando MageUI.exe

  1. Usando MageUI.exe, creare un manifesto dell'applicazione come descritto in Procedura dettagliata: Distribuire manualmente un'applicazione ClickOnce. Usare le impostazioni seguenti per il manifesto dell'applicazione:

    • Assegnare al manifesto ClickOnceOnDemanddell'applicazione il nome .

    • Nella riga ClickOnceLibrary.dll della pagina File impostare la colonna Tipo di file su Nessuno.

    • Nella pagina File digitare nella riga ClickOnceLibrary.dll ClickOnceLibrary.dll nella colonna Gruppo.

  2. Usando MageUI.exe, creare un manifesto della distribuzione come descritto in Procedura dettagliata: Distribuire manualmente un'applicazione ClickOnce. Usare le impostazioni seguenti per il manifesto della distribuzione:

    • Denominare il manifesto ClickOnceOnDemanddella distribuzione .

Test del nuovo assembly

Per testare l'assembly su richiesta

  1. Caricare la distribuzione ClickOnce in un server Web.

  2. Avviare l'applicazione distribuita con ClickOnce da un Web browser immettendo l'URL al manifesto della distribuzione. Se si chiama l'applicazione ClickOnceOnDemandClickOnce e la si carica nella directory radice di adatum.com, l'URL sarà simile al seguente:

    http://www.adatum.com/ClickOnceOnDemand/ClickOnceOnDemand.application
    
  3. Quando viene visualizzato il modulo principale, premere l'oggetto Button. Verrà visualizzata una stringa in una finestra di messaggio con il testo "Hello, World!".