Procédure pas à pas : téléchargement d'assemblys à la demande avec l'API du déploiement ClickOnce à l'aide du concepteur
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, il est possible que certaines parties de votre application ne soient 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 en a besoin.
Notes
Votre application devra s'exécuter avec une confiance totale pour utiliser cette procédure.
Notes
Les boîtes de dialogue et les commandes de menu qui s'affichent peuvent être différentes de celles qui sont décrites dans l'aide, en fonction de vos paramètres actifs ou de l'édition utilisée. Pour modifier vos paramètres, cliquez sur Importation et exportation de paramètres dans le menu Outils. Pour plus d'informations, consultez Utilisation des paramètres.
Création du projet
Pour créer un projet qui utilise un assembly à la demande avec Visual Studio
Créez un nouveau projet Windows Forms dans Visual Studio. Dans le menu Fichier, pointez sur Ajouter, puis cliquez sur Nouveau projet. Choisissez un projet Bibliothèque de classes dans la boîte de dialogue et nommez-le BibliothèqueClickOnce.
Notes
En Visual Basic, il est recommandé de modifier les propriétés du projet pour définir son espace de noms racine à Microsoft.Samples.ClickOnceOnDemand ou à un espace de noms de votre choix. Pour plus de simplicité, les deux projets de cette procédure pas à pas figurent dans le même espace de noms.
Définissez une classe nommée DynamicClass avec une seule propriété nommé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!"); } } } }
Sélectionnez le projet Windows Forms dans l'Explorateur de solutions. Ajoutez une référence à l'assembly System.Deployment.Application et une référence de projet au projet ClickOnceLibrary.
Notes
En Visual Basic, il est recommandé de modifier les propriétés du projet pour définir son espace de noms racine à Microsoft.Samples.ClickOnceOnDemand ou à un espace de noms de votre choix. Pour plus de simplicité, les deux projets de cette procédure pas à pas se trouvent dans le même espace de noms.
Cliquez avec le bouton droit sur le formulaire, cliquez sur Afficher le code dans le menu et ajoutez les références suivantes au formulaire.
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;
Ajoutez le code suivant pour télécharger cet assembly à la demande. Ce code indique comment mapper un jeu d'assemblys et un nom de groupe à l'aide d'une classe Dictionary générique. Comme nous ne téléchargeons qu'un seul assembly dans cette procédure pas à pas, notre groupe n'en comporte qu'un seul. Dans une application réelle, il est probable que vous souhaiteriez télécharger simultanément tous les assemblys liés à une même fonctionnalité de l'application. La table de mappage vous permet d'exécuter facilement cette opération en associant toutes les DLL qui appartiennent à une fonctionnalité à un nom de groupe de téléchargement.
' 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); }
Dans le menu Affichage, cliquez sur Boîte à outils. Faites glisser un contrôle Button de la Boîte à outils vers le formulaire. Double-cliquez sur le bouton et ajoutez le code suivant au gestionnaire d'événements 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); }
Marquage d'assemblys comme étant facultatifs
Pour marquer des assemblys comme facultatifs dans votre application ClickOnce à l'aide de Visual Studio
Cliquez avec le bouton droit sur le projet Windows Forms dans l'Explorateur de solutions, puis cliquez sur Propriétés. Sélectionnez l'onglet Publier.
Cliquez sur le bouton Fichiers d'application.
Recherchez ClickOnceLibrary.dll dans la liste. Affectez à la zone déroulante État de la publication la valeur Inclure.
Développez la liste déroulante Groupe et sélectionnez Nouveau. Entrez le nom BibliothèqueClickOnce comme nouveau nom de groupe.
Poursuivez la publication de votre application comme décrit dans Comment : publier une application ClickOnce à l'aide de l'Assistant Publication.
Pour marquer des assemblys comme facultatifs dans votre application ClickOnce à l'aide de l'outil Manifest Generation and Editing - client graphique (MageUI.exe)
Créez vos manifestes ClickOnce comme indiqué dans Procédure pas à pas : déploiement manuel d'une application ClickOnce.
Avant de fermer MageUI.exe, sélectionnez l'onglet qui contient le manifeste d'application de votre déploiement, et sous cet onglet, sélectionnez l'onglet Fichiers.
Recherchez ClickOnceLibrary.dll dans la liste des fichiers de l'application et attribuez à sa colonne File Type la valeur None. Pour la colonne Group, tapez ClickOnceLibrary.dll.
Test du nouvel assembly
Pour tester votre assembly à la demande
Démarrez votre application déployée avec ClickOnce.
Lorsque votre formulaire principal apparaît, appuyez sur Button. Vous devez voir la chaîne "Hello World!" dans une fenêtre de message.