Vue d’ensemble des compléments WPF
Le .NET Framework inclut un modèle de complément que les développeurs peuvent utiliser pour créer des applications qui prennent en charge l’extensibilité du complément. Ce modèle de complément permet de créer des compléments qui s’intègrent aux applications et étendent leurs fonctionnalités. Dans certains scénarios, les applications doivent également afficher des interfaces utilisateur fournies par des compléments. Cette rubrique montre comment WPF augmente le modèle de complément .NET Framework pour activer ces scénarios, l’architecture derrière elle, ses avantages et ses limitations.
Prérequis
La connaissance du modèle de complément .NET Framework est requise. Pour plus d’informations, consultez Compléments et extensibilité.
Vue d’ensemble des compléments
Pour éviter la complexité des tâches de redéploiement et de recompilation des applications durant l’incorporation de nouvelles fonctionnalités, les applications offrent des mécanismes d’extensibilité qui permettent aux développeurs (aussi bien internes que tiers) de créer d’autres applications qui s’y intègrent. La méthode la plus répandue pour prendre en charge ce type d’extensibilité consiste à utiliser des compléments (également appelés « modules complémentaires », « extensions » et « plug-ins »). Voici quelques exemples d’applications réelles qui offrent une extensibilité à l’aide de compléments :
modules complémentaires d’Internet Explorer ;
plug-ins du Lecteur Windows Media ;
compléments Visual Studio.
Par exemple, le modèle de complément du Lecteur Windows Media permet aux développeurs tiers d’implémenter des « plug-ins » pour étendre le Lecteur Windows Media de différentes façons, notamment en créant des décodeurs et encodeurs de formats multimédias non pris en charge en mode natif par le Lecteur Windows Media (DVD, MP3, par exemple), des effets audio et des apparences. Chaque modèle de complément est conçu pour exposer les fonctionnalités uniques d’une application, bien que plusieurs entités et comportements soient communs à tous les modèles de compléments.
Les trois principales entités de solutions d’extensibilité des compléments classiques sont les contrats, les compléments et les applications hôtes. Les contrats définissent la manière dont les compléments s’intègrent aux applications hôtes de deux manières :
Les compléments s’intègrent aux fonctionnalités implémentées par les applications hôtes.
Les applications hôtes exposent les fonctionnalités auxquelles les compléments peuvent s’intégrer.
Pour permettre l’utilisation des compléments, les applications hôtes doivent les rechercher et les charger au moment de l’exécution. Ainsi, les applications qui prennent en charge des compléments ont les responsabilités supplémentaires suivantes :
Découverte : recherche des compléments adhérant aux contrats pris en charge par les applications hôtes.
Activation : chargement, exécution et établissement de la communication avec les compléments.
Isolation : utilisation de domaines ou de processus d’application pour établir des limites d’isolation protégeant les applications des problèmes potentiels de sécurité et d’exécution liés aux compléments.
Communication : autorisation pour les compléments et les applications hôtes de communiquer au travers des limites d’isolation via l’appel de méthodes et le passage de données.
Gestion de la durée de vie : chargement et déchargement des domaines et processus d’application de façon propre et prévisible (consultez Domaines d’application).
Gestion de versions : vérification de la communication entre les nouvelles versions des applications hôtes et des compléments.
Enfin, le développement d’un modèle de complément robuste est une tâche non négligeable. Pour cette raison, .NET Framework fournit une infrastructure permettant de créer des modèles de complément.
Remarque
Pour plus d’informations sur les compléments, consultez Compléments et extensibilité.
Vue d’ensemble du modèle de complément du .NET Framework
Le modèle de complément .NET Framework, trouvé dans l’espace System.AddIn de noms, contient un ensemble de types conçus pour simplifier le développement d’extensibilité des compléments. L’unité fondamentale du modèle de complément .NET Framework est le contrat, qui définit la façon dont une application hôte et un complément communiquent entre eux. Un contrat est exposé à une application hôte à l’aide d’une vue spécifique à l’application hôte du contrat. De même, une vue spécifique au complément du contrat est exposée au complément. Un adaptateur permet à une application hôte et à un complément de communiquer entre les vues respectives du contrat. Les contrats, les vues et les adaptateurs sont appelés des segments. Un ensemble de segments connexes constitue un pipeline. Les pipelines sont la base sur laquelle le modèle de complément .NET Framework prend en charge la découverte, l’activation, l’isolation de la sécurité, l’isolation de l’exécution (à l’aide de domaines d’application et de processus), la communication, la gestion de la durée de vie et le contrôle de version.
L’ensemble de cette prise en charge permet aux développeurs de générer des compléments qui s’intègrent aux fonctionnalités d’une application hôte. Toutefois, certains scénarios nécessitent que les applications hôtes affichent les interfaces utilisateur fournies par les compléments. Étant donné que chaque technologie de présentation du .NET Framework a son propre modèle pour implémenter des interfaces utilisateur, le modèle de complément .NET Framework ne prend pas en charge une technologie de présentation particulière. Au lieu de cela, WPF étend le modèle de complément .NET Framework avec prise en charge de l’interface utilisateur pour les compléments.
Compléments WPF
WPF, conjointement avec le modèle de complément .NET Framework, vous permet de traiter un large éventail de scénarios qui nécessitent des applications hôtes pour afficher des interfaces utilisateur à partir de compléments. En particulier, ces scénarios sont traités par WPF avec les deux modèles de programmation suivants :
Le complément retourne une IU (interface utilisateur). Un complément retourne une interface utilisateur à l’application hôte via un appel de méthode, tel que défini par le contrat. Ce scénario est utilisé dans les cas suivants :
L’apparence d’une interface utilisateur retournée par un complément dépend des données ou des conditions qui existent uniquement au moment de l’exécution, telles que les rapports générés dynamiquement.
L’interface utilisateur pour les services fournis par un complément diffère de l’interface utilisateur des applications hôtes qui peuvent utiliser le complément.
Le complément effectue principalement un service pour l’application hôte et signale l’état à l’application hôte avec une interface utilisateur.
Le complément est une interface utilisateur. Un complément est une interface utilisateur, telle que définie par le contrat. Ce scénario est utilisé dans les cas suivants :
Un complément ne fournit pas d’autres services que celui d’être affiché, par exemple une publicité.
L’interface utilisateur des services fournis par un complément est commune à toutes les applications hôtes qui peuvent utiliser ce complément, comme une calculatrice ou un sélecteur de couleurs.
Ces scénarios nécessitent que les objets d’interface utilisateur puissent être transmis entre l’application hôte et les domaines d’application de complément. Étant donné que le modèle de complément .NET Framework s’appuie sur la communication à distance pour communiquer entre les domaines d’application, les objets passés entre eux doivent être accessibles à distance.
Un objet accessible à distance est une instance d’une classe qui effectue une ou plusieurs des opérations suivantes :
Dérive de la MarshalByRefObject classe.
Implémente l'interface ISerializable.
L’attribut SerializableAttribute est appliqué.
Remarque
Pour plus d’informations sur la création d’objets .NET Framework remotables, consultez Making Objects Remotable.
Les types d’interface utilisateur WPF ne sont pas accessibles à distance. Pour résoudre le problème, WPF étend le modèle de complément .NET Framework pour permettre à l’interface utilisateur WPF créée par des compléments d’être affichés à partir d’applications hôtes. Cette prise en charge est fournie par WPF par deux types : l’interface INativeHandleContract et deux méthodes statiques implémentées par la FrameworkElementAdapters classe : ContractToViewAdapter et ViewToContractAdapter. À un niveau élevé, ces types et méthodes sont utilisés de la manière suivante :
WPF exige que les interfaces utilisateur fournies par des compléments sont des classes qui dérivent directement ou indirectement de FrameworkElement, telles que des formes, des contrôles, des contrôles utilisateur, des panneaux de disposition et des pages.
Chaque fois que le contrat déclare qu’une interface utilisateur sera passée entre le complément et l’application hôte, elle doit être déclarée comme une INativeHandleContractFrameworkElementINativeHandleContract représentation à distance de l’interface utilisateur du complément qui peut être passée entre les limites d’isolation.
Avant d’être transmis à partir du domaine d’application du complément, un FrameworkElement package est empaqueté en tant qu’appel INativeHandleContractViewToContractAdapter.
Après avoir été transmis au domaine d’application de l’application hôte, il INativeHandleContract doit être repackagené en tant qu’appel FrameworkElementContractToViewAdapter.
La façon dont INativeHandleContract, ContractToViewAdapteret ViewToContractAdapter sont utilisées dépend du scénario spécifique. Les sections suivantes fournissent des détails sur chaque modèle de programmation.
Le complément retourne une interface utilisateur
Pour qu’un complément retourne une interface utilisateur à une application hôte, les éléments suivants sont requis :
L’application hôte, le complément et le pipeline doivent être créés, comme décrit par la documentation sur les compléments et l’extensibilité .NET Framework.
Le contrat doit implémenter IContract et, pour retourner une interface utilisateur, le contrat doit déclarer une méthode avec une valeur de retour de type INativeHandleContract.
L’interface utilisateur passée entre le complément et l’application hôte doit dériver directement ou indirectement de FrameworkElement.
L’interface utilisateur retournée par le complément doit être convertie d’un à un FrameworkElementINativeHandleContract avant de traverser la limite d’isolation.
L’interface utilisateur retournée doit être convertie d’un INativeHandleContract à un FrameworkElement après avoir franchi la limite d’isolation.
L’application hôte affiche le retour FrameworkElement.
Pour obtenir un exemple qui montre comment implémenter un complément qui retourne une interface utilisateur, consultez Créer un complément qui renvoie une interface utilisateur.
Le complément est une interface utilisateur
Lorsqu’un complément est une interface utilisateur, les éléments suivants sont requis :
L’application hôte, le complément et le pipeline doivent être créés, comme décrit par la documentation sur les compléments et l’extensibilité .NET Framework.
L’interface de contrat pour le complément doit implémenter INativeHandleContract.
Le complément passé à l’application hôte doit dériver directement ou indirectement de FrameworkElement.
Le complément doit être converti d’un FrameworkElement à un INativeHandleContract avant de traverser la limite d’isolation.
Le complément doit être converti d’un INativeHandleContract à un FrameworkElement après avoir franchi la limite d’isolation.
L’application hôte affiche le retour FrameworkElement.
Pour obtenir un exemple qui montre comment implémenter un complément qui est une interface utilisateur, consultez Créer un complément qui est une interface utilisateur.
Retour de plusieurs interfaces utilisateur à partir d’un complément
Les compléments fournissent souvent plusieurs interfaces utilisateur pour que les applications hôtes s’affichent. Par exemple, considérez un complément qui est une interface utilisateur qui fournit également des informations d’état à l’application hôte, également en tant qu’interface utilisateur. Un complément de ce type peut être implémenté à l’aide d’une combinaison de techniques provenant des modèles Le complément retourne une interface utilisateur et Le complément est une interface utilisateur.
Compléments et applications de navigateur XAML
Dans les exemples présentés jusqu’à maintenant, l’application hôte a été installée en tant qu’application autonome. Toutefois, les applications de navigateur XAML (XBAPs) peuvent également héberger des compléments, mais avec les exigences de build et d’implémentation supplémentaires suivantes :
Le manifeste d’application XBAP doit être configuré spécialement pour télécharger le pipeline (dossiers et assemblys) et l’assembly de complément dans le cache d’application ClickOnce sur l’ordinateur client, dans le même dossier que le XBAP.
Le code XBAP à découvrir et charger des compléments doit utiliser le cache d’application ClickOnce pour le XBAP comme pipeline et emplacement du complément.
Le XBAP doit charger le complément dans un contexte de sécurité spécial si le complément fait référence à des fichiers libres situés sur le site d’origine ; lorsqu’ils sont hébergés par des XBAPs, les compléments ne peuvent référencer que des fichiers libres situés sur le site d’origine de l’application hôte.
Ces tâches sont décrites en détail dans les sous-sections suivantes.
Configuration du pipeline et du complément pour un déploiement ClickOnce
Les XBAPs sont téléchargés et exécutés à partir d’un dossier sécurisé dans le cache de déploiement ClickOnce. Pour qu’un XBAP héberge un complément, le pipeline et l’assembly de complément doivent également être téléchargés dans le dossier sécurisé. Ainsi, vous devez configurer le manifeste de l’application pour qu’il contienne l’assembly de pipeline et de complément à télécharger. Cela s’effectue le plus facilement dans Visual Studio, bien que le pipeline et l’assembly de complément doivent se trouver dans le dossier racine du projet XBAP hôte afin que Visual Studio détecte les assemblys de pipeline.
Par conséquent, la première étape consiste à générer l’assembly de pipeline et de complément à la racine du projet XBAP en définissant la sortie de build de chaque assembly de pipeline et projets d’assembly de complément. Le tableau suivant montre les chemins de sortie de build pour les projets d’assembly de pipeline et le projet d’assembly de complément qui se trouvent dans le même dossier solution et racine que le projet XBAP hôte.
Tableau 1 : Chemins de sortie de build des assemblys de pipeline hébergés par une application XBAP
Projet d’assembly de pipeline | Chemin de sortie de la génération |
---|---|
Contrat | ..\HostXBAP\Contracts\ |
Vue de complément | ..\HostXBAP\AddInViews\ |
Adaptateur côté complément | ..\HostXBAP\AddInSideAdapters\ |
Adaptateur côté hôte | ..\HostXBAP\HostSideAdapters\ |
Complément | ..\HostXBAP\AddIns\WPFAddIn1 |
L’étape suivante consiste à spécifier les assemblys de pipeline et l’assembly de complément en tant que fichiers de contenu XBAPs dans Visual Studio en procédant comme suit :
Ajoutez l’assembly de pipeline et de complément au projet en cliquant avec le bouton droit sur chaque dossier de pipeline dans l’Explorateur de solutions, puis choisissez Inclure dans le projet.
Affectez à l’Action de génération de chaque assembly de pipeline et de complément le Contenu de la fenêtre Propriétés.
La dernière étape consiste à configurer le manifeste de l’application pour inclure les fichiers d’assembly de pipeline et de complément à télécharger. Les fichiers doivent se trouver dans des dossiers à la racine du dossier dans le cache ClickOnce occupé par l’application XBAP. La configuration peut être obtenue dans Visual Studio en procédant comme suit :
Cliquez avec le bouton droit sur le projet XBAP, cliquez sur Propriétés, cliquez sur Publier, puis sur le bouton Fichiers d’application.
Dans la boîte de dialogue Fichiers d’application, affectez à l’État de la publication de chaque DLL de pipeline et de complément la valeur Inclure (automatique), puis affectez au Groupe de téléchargement de chaque DLL de pipeline et de complément la valeur (Requis).
Utilisation du pipeline et du complément à partir de la base de l’application
Lorsque le pipeline et le complément sont configurés pour le déploiement ClickOnce, ils sont téléchargés dans le même dossier de cache ClickOnce que le XBAP. Pour utiliser le pipeline et le complément à partir du XBAP, le code XBAP doit les obtenir à partir de la base de l’application. Les différents types et membres du modèle de complément .NET Framework pour l’utilisation de pipelines et de compléments fournissent une prise en charge spéciale pour ce scénario. Tout d’abord, le chemin d’accès est identifié par la valeur d’énumération ApplicationBase . Vous utilisez cette valeur avec les surcharges des membres de complément adéquats pour utiliser des pipelines incluant les éléments suivants :
Accès au site d’origine de l’hôte
Pour garantir qu’un complément puisse référencer des fichiers à partir du site d’origine, ce complément doit être chargé avec l’isolation de sécurité équivalente à l’application hôte. Ce niveau de sécurité est identifié par la AddInSecurityLevel.Host valeur d’énumération et transmis à la Activate méthode lorsqu’un complément est activé.
Architecture des compléments WPF
Au niveau le plus élevé, comme nous l’avons vu, WPF permet aux compléments .NET Framework d’implémenter des interfaces utilisateur (qui dérivent directement ou indirectement de ) à l’aide FrameworkElementINativeHandleContract, ViewToContractAdapter et ContractToViewAdapter. Le résultat est que l’application hôte est retournée à FrameworkElement partir de l’interface utilisateur dans l’application hôte.
Pour les scénarios de complément d’interface utilisateur simples, il s’agit autant de détails qu’un développeur en a besoin. Pour les scénarios plus complexes, en particulier ceux qui tentent d’utiliser des services WPF supplémentaires tels que la disposition, les ressources et la liaison de données, des connaissances plus détaillées sur la façon dont WPF étend le modèle de complément .NET Framework avec prise en charge de l’interface utilisateur est nécessaire pour comprendre ses avantages et ses limitations.
En fait, WPF ne transmet pas d’interface utilisateur d’un complément à une application hôte ; Au lieu de cela, WPF transmet le handle de fenêtre Win32 pour l’interface utilisateur à l’aide de l’interopérabilité WPF. Par conséquent, lorsqu’une interface utilisateur à partir d’un complément est passée à une application hôte, les événements suivants se produisent :
Côté complément, WPF acquiert un handle de fenêtre pour l’interface utilisateur qui sera affichée par l’application hôte. Le handle de fenêtre est encapsulé INativeHandleContractpar une classe WPF interne qui dérive et HwndSource implémente . Une instance de cette classe est retournée ViewToContractAdapter et marshalée du domaine d’application du complément vers le domaine d’application de l’application hôte.
Côté application hôte, WPF repackage le HwndSource sous forme de classe WPF interne qui dérive HwndHost et consomme INativeHandleContract. Une instance de cette classe est retournée par ContractToViewAdapter l’application hôte.
HwndHost existe pour afficher les interfaces utilisateur, identifiées par les handles de fenêtre, à partir des interfaces utilisateur WPF. Pour plus d’informations, consultez Interopérabilité WPF et Win32.
En résumé, INativeHandleContractet ViewToContractAdapterContractToViewAdapter il existe pour autoriser le handle de fenêtre d’une interface utilisateur WPF à passer d’un complément à une application hôte, où il est encapsulé par une HwndHost interface utilisateur de l’application hôte et affiché.
Remarque
Étant donné que l’application hôte obtient un HwndHost, l’application hôte ne peut pas convertir l’objet retourné par ContractToViewAdapter le type qu’elle est implémenté comme par le complément (par exemple, un UserControl).
Par sa nature, HwndHost certaines limitations affectent la façon dont les applications hôtes peuvent les utiliser. Toutefois, WPF s’étend avec plusieurs fonctionnalités pour les scénarios HwndHost de complément. Ces avantages et limitations sont décrits ci-dessous.
Avantages des compléments WPF
Étant donné que les interfaces utilisateur du complément WPF sont affichées à partir d’applications hôtes à l’aide d’une classe interne qui dérive de , ces interfaces utilisateur sont limitées HwndHostpar les fonctionnalités des services d’interface HwndHost utilisateur WPF tels que la disposition, le rendu, la liaison de données, les styles, les modèles et les ressources. Toutefois, WPF augmente sa sous-classe interne HwndHost avec des fonctionnalités supplémentaires qui incluent les éléments suivants :
Tabulation entre l’interface utilisateur d’une application hôte et l’interface utilisateur d’un complément. Notez que le modèle de programmation « complément est une interface utilisateur » nécessite que l’adaptateur côté complément soit substitué QueryContract pour activer la tabulation, que le complément soit entièrement approuvé ou partiellement approuvé.
Respect des exigences d’accessibilité pour les interfaces utilisateur de complément affichées à partir des interfaces utilisateur de l’application hôte.
Activation des applications WPF pour s’exécuter en toute sécurité dans plusieurs scénarios de domaine d’application.
Empêcher l’accès illégal aux handles de fenêtre d’interface utilisateur de complément lorsque les compléments s’exécutent avec une isolation de sécurité (autrement dit, un bac à sable de sécurité de confiance partielle). L’appel ViewToContractAdapter garantit cette sécurité :
Pour le modèle de programmation « complément retourne une interface utilisateur », la seule façon de passer le handle de fenêtre d’une interface utilisateur de complément sur la limite d’isolation consiste à appeler ViewToContractAdapter.
Pour le modèle de programmation « complément est une interface utilisateur », la QueryContract substitution de l’adaptateur côté complément et de l’appel ViewToContractAdapter (comme illustré dans les exemples précédents) est requise, comme l’appel de l’implémentation de
QueryContract
l’adaptateur côté complément à partir de l’adaptateur côté hôte.
Protection de l’exécution de plusieurs domaines d’application. En raison des limitations liées aux domaines d’application, les exceptions non prises en charge qui sont levées dans les domaines d’application de complément entraînent l’arrêt brutal de l’application, même s’il existe une limite d’isolation. Toutefois, WPF et le modèle de complément .NET Framework offrent un moyen simple de contourner ce problème et d’améliorer la stabilité de l’application. Un complément WPF qui affiche une interface utilisateur crée un Dispatcher thread sur lequel le domaine d’application s’exécute, si l’application hôte est une application WPF. Vous pouvez détecter toutes les exceptions non gérées qui se produisent dans le domaine d’application en gérant l’événement UnhandledExceptionDispatcherdu complément WPF. Vous pouvez obtenir la DispatcherCurrentDispatcher propriété.
Limitations des compléments WPF
Au-delà des avantages que WPF ajoute aux comportements par défaut fournis par HwndSource, HwndHostet les handles de fenêtre, il existe également des limitations pour les interfaces utilisateur de complément affichées à partir d’applications hôtes :
Les interfaces utilisateur de complément affichées à partir d’une application hôte ne respectent pas le comportement de découpage de l’application hôte.
Le concept d’espace de rendu des scénarios d’interopérabilité s’applique également aux compléments (consultez Vue d’ensemble des régions de technologie).
Les services d’interface utilisateur d’une application hôte, tels que l’héritage des ressources, la liaison de données et la commande, ne sont pas automatiquement disponibles pour les interfaces utilisateur de complément. Pour fournir ces services au complément, vous devez mettre à jour le pipeline.
Une interface utilisateur de complément ne peut pas être pivotée, mise à l’échelle, asymétrique ou affectée par une transformation (voir Vue d’ensemble des transformations).
Le contenu à l’intérieur des interfaces utilisateur du complément qui est rendu en dessinant des opérations à partir de l’espace System.Drawing de noms peut inclure un mélange alpha. Toutefois, une interface utilisateur de complément et l’interface utilisateur de l’application hôte qui le contient doivent être opaques de 100 % ; en d’autres termes, la
Opacity
propriété sur les deux doit être définie sur 1.Si la AllowsTransparency propriété d’une fenêtre dans l’application hôte qui contient une interface utilisateur de complément est définie
true
sur , le complément est invisible. Cela est vrai même si l’interface utilisateur du complément est opaque de 100 % (autrement dit, laOpacity
propriété a la valeur 1).Une interface utilisateur de complément doit apparaître sur d’autres éléments WPF dans la même fenêtre de niveau supérieur.
Aucune partie de l’interface utilisateur d’un complément ne peut être rendue à l’aide d’un VisualBrush. Au lieu de cela, le complément peut prendre une instantané de l’interface utilisateur générée pour créer une bitmap qui peut être transmise à l’application hôte à l’aide de méthodes définies par le contrat.
Les fichiers multimédias ne peuvent pas être lus à partir d’une MediaElement interface utilisateur de complément.
Les événements de souris générés pour l’interface utilisateur du complément ne sont ni reçus ni déclenchés par l’application hôte, et la propriété de l’interface
IsMouseOver
utilisateur de l’application hôte a la valeurfalse
.Lorsque le focus se déplace entre les contrôles d’une interface utilisateur de complément, les événements et
LostFocus
lesGotFocus
événements ne sont ni reçus ni déclenchés par l’application hôte.La partie d’une application hôte qui contient une interface utilisateur de complément s’affiche en blanc lors de l’impression.
Tous les répartiteurs (voir Dispatcher) créés par l’interface utilisateur du complément doivent être arrêtés manuellement avant que le complément propriétaire ne soit déchargé si l’application hôte continue son exécution. Le contrat peut implémenter des méthodes qui permettent à l’application hôte de signaler le complément avant le déchargement du complément, ce qui permet à l’interface utilisateur du complément d’arrêter ses répartiteurs.
Si une interface utilisateur de complément est une InkCanvas ou contient un InkCanvascomplément, vous ne pouvez pas décharger le complément.
Optimisation des performances
Par défaut, lorsque plusieurs domaines d’application sont utilisés, les différents assemblys .NET Framework requis par chaque application sont tous chargés dans le domaine de cette application. Ainsi, le temps nécessaire à la création de domaines d’application et au démarrage des applications dans ces domaines peut affecter les performances. Toutefois, le .NET Framework vous permet de réduire les temps de démarrage en demandant aux applications de partager des assemblys entre les domaines d’application s’ils sont déjà chargés. Pour ce faire, utilisez l’attribut LoaderOptimizationAttribute , qui doit être appliqué à la méthode de point d’entrée (Main
). Dans ce cas, utilisez uniquement du code pour implémenter votre définition d’application (consultez Vue d’ensemble de la gestion d’applications).
Voir aussi
.NET Desktop feedback