Partager via


Procédure pas à pas : téléchargement d'assemblys à la demande avec l'API du déploiement ClickOnce

Par défaut, tous les assemblys inclus dans une application ClickOnce sont téléchargés lors de la première exécution de l'application. Toutefois, certaines parties de votre application peuvent n'être utilisées que par un petit nombre d'utilisateurs. Dans ce cas, vous souhaitez télécharger un assembly uniquement lorsque vous créez l'un de ses types. La procédure pas à pas suivante montre comment marquer certains assemblys de votre application comme « facultatifs » et les télécharger à l'aide de classes de l'espace de noms System.Deployment.Application lorsque le Common Language Runtime (CLR) en a besoin.

Notes

Votre application devra s'exécuter avec une confiance totale pour utiliser cette procédure.

Composants requis

Vous aurez besoin d'un des composants suivants pour exécuter cette procédure pas à pas :

  • Kit de développement logiciel Windows. Le Kit de développement logiciel (SDK) Windows peut être téléchargé à partir du Centre de téléchargement Microsoft.

  • Visual Studio.

Création du projet

Pour créer un projet qui utilise un assembly à la demande

  1. Créez un répertoire nommé ClickOnceOnDemand.

  2. Ouvrez l'invite de commandes du Kit de développement Windows SDK ou l'invite de commandes Visual Studio.

  3. Accédez au répertoire ClickOnceOnDemand.

  4. Générez une paire de clés publique/privée à l'aide de la commande suivante :

    sn -k TestKey.snk
    
  5. À l'aide du Bloc-notes ou d'un autre éditeur de texte, définissez une classe nommée DynamicClass avec une seule propriété appelée 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. Enregistrez le texte en tant que fichier nommé ClickOnceLibrary.cs ou ClickOnceLibrary.vb, selon le langage vous utilisez, dans le répertoire ClickOnceOnDemand.

  7. Compilez le fichier dans un assembly.

    csc /target:library /keyfile:TestKey.snk ClickOnceLibrary.cs
    
    vbc /target:library /keyfile:TestKey.snk ClickOnceLibrary.vb
    
  8. Pour obtenir le jeton de clé publique de l'assembly, utilisez la commande suivante :

    sn -T ClickOnceLibrary.dll
    
  9. Créez un fichier à l'aide de votre éditeur de texte et entrez le code suivant. Ce code crée une application Windows Forms qui télécharge l'assembly ClickOnceLibrary lorsqu'il est requis.

    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. Dans le code, localisez l'appel à LoadFile.

  11. Affectez à PublicKeyToken la valeur que vous avez récupérée précédemment.

  12. Enregistrez le fichier en tant que Form1.cs ou Form1.vb.

  13. Compilez-le dans un fichier exécutable à l'aide de la commande suivante.

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

Marquage d'assemblys comme étant facultatifs

Pour marquer des assemblys comme étant facultatifs dans votre application ClickOnce à l'aide de MageUI.exe

  1. À l'aide de MageUI.exe, créez un manifeste d'application comme décrit dans Procédure pas à pas : déploiement manuel d'une application ClickOnce. Utilisez les paramètres suivants pour le manifeste d'application :

    • Nommez le manifeste d'application ClickOnceOnDemand.

    • Dans la page Fichiers, sur la ligne ClickOnceLibrary.dll, affectez à la colonne Type de fichier la valeur Aucun.

    • Dans la page Fichiers, sur la ligne ClickOnceLibrary.dll, tapez ClickOnceLibrary.dll dans la colonne Groupe.

  2. À l'aide de MageUI.exe, créez un manifeste de déploiement comme décrit dans Procédure pas à pas : déploiement manuel d'une application ClickOnce. Utilisez les paramètres suivants pour le manifeste de déploiement :

    • Nommez le manifeste de déploiement ClickOnceOnDemand.

Test du nouvel assembly

Pour tester votre assembly à la demande

  1. Téléchargez votre déploiement ClickOnce sur un serveur Web.

  2. Lancez votre application déployée avec ClickOnce à partir d'un navigateur Web en entrant l'URL du manifeste de déploiement. Si vous appelez votre application ClickOnce ClickOnceOnDemand et si vous la téléchargez dans le répertoire racine de adatum.com, votre URL se présente comme suit :

    http://www.adatum.com/ClickOnceOnDemand/ClickOnceOnDemand.application
    
  3. Lorsque votre formulaire principal apparaît, appuyez sur Button. Vous devez voir la chaîne "Hello World!" dans une fenêtre de message.

Voir aussi

Référence

ApplicationDeployment