Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Windows fournit plusieurs technologies qui permettent à votre application de fournir des fonctionnalités à d’autres applications ou d’utiliser des compléments tiers. Cet article compare les options d’extensibilité disponibles pour les applications de bureau SDK d'application Windows.
Vue d’ensemble des options d’extensibilité
| Technologie | Description | Identité de package requise | Système d’exploitation minimal |
|---|---|---|---|
| Services d’application | Communication de demande/réponse entre les applications via AppServiceConnection |
Oui | Windows 10 1607 |
| Extensions d'application | Modèle de plug-in : l’application hôte découvre du contenu à partir de packages d’extension | Oui | Windows 10 1607 |
| Extensions de package | Extensibilité au niveau du package plus large avec uap17:PackageExtension |
Oui | Windows 11 |
| Packages facultatifs | Packages de contenu supplémentaires qui complètent une application principale | Oui | Windows 10 1709 |
| Packages de ressources | Ressources de langue, d’échelle et d’accessibilité séparées par le marché | Oui | Windows 10 |
Choix de la technologie appropriée
Utiliser les services d’application quand
- Vous avez besoin d’une communication bidirectionnelle entre des applications distinctes.
- L’application consommateur envoie une demande et attend une réponse.
- Vous souhaitez exposer une interface de type API à d’autres applications.
Exemple : service de traduction que d’autres applications peuvent appeler pour traduire du texte.
Utiliser des extensions d’application quand
- Votre application a besoin d’un modèle de plug-in où des tiers fournissent du contenu, des thèmes ou des compléments.
- Les extensions sont découvertes au moment de l’exécution à partir de packages installés.
- Les extensions fournissent des données ou une configuration, et non du code exécutable (l’exécution du code doit utiliser les services d’application).
Exemple : Éditeur d’images qui découvre les packs de filtre à partir de packages d’extension installés.
Utiliser des extensions de paquet lorsque
- Vous avez besoin d’une extensibilité plus large au niveau du package sur Windows 11.
- Les extensions doivent accéder à plus de contenu de package que le modèle l’autorise
PublicFolder.
Utiliser des paquets facultatifs lorsque
- Vous disposez d’un contenu supplémentaire (DLC, fonctionnalités Premium) distribué en tant que packages distincts.
- Le contenu est créé par le même éditeur.
Modèles d’architecture
App Service avec découverte d’extensions
Combinez les extensions d’application avec les services d’application pour une architecture de plug-in complète :
- Votre application hôte utilise
AppExtensionCatalogpour découvrir les extensions installées. - Chaque extension déclare des propriétés qui décrivent ses fonctionnalités.
- Lorsque l’utilisateur active une extension, l’application hôte se connecte au service d’application de l’extension pour la communication bidirectionnelle.
┌─────────────────┐ ┌──────────────────┐
│ Host app │ │ Extension app │
│ │ │ │
│ AppExtension │◄────►│ AppExtension │
│ Catalog │ │ declaration │
│ │ │ │
│ AppService │◄────►│ AppService │
│ Connection │ │ provider │
└─────────────────┘ └──────────────────┘
Extension de contenu uniquement
Pour des scénarios plus simples où les extensions fournissent du contenu statique (thèmes, modèles, fichiers de données) :
- L’application hôte découvre les extensions via
AppExtensionCatalog. - Il lit les fichiers depuis
PublicFolderde l’extension. - Aucun service d’application n’est nécessaire.
Différences par rapport à l’extensibilité UWP
Les technologies d’extensibilité décrites ici fonctionnent de la même façon dans SDK d'application Windows applications de bureau que dans UWP, avec une exigence : identité de package MSIX. Toutes les fonctionnalités d’extensibilité s’appuient sur le manifeste du package pour les déclarations et le catalogue de packages pour la découverte.
Si votre application de bureau n’est pas empaquetée, vous ne pouvez pas utiliser ces technologies d’extensibilité. Envisagez d’autres approches telles que :
- Interfaces de modules d’extension basées sur COM
- Découverte d’extensions basées sur le système de fichiers
- Canaux nommés ou autres mécanismes d’IPC
Découverte de plug-ins basé sur des fichiers pour les applications non empaquetées
Pour les applications WinUI 3 non empaquetées, vous pouvez implémenter un système de plug-in à l'aide de AssemblyLoadContext .NET pour charger des extensions à partir d'un dossier connu :
public class PluginLoader
{
private readonly string _pluginDirectory;
public PluginLoader(string pluginDirectory)
{
_pluginDirectory = pluginDirectory;
}
public IEnumerable<T> LoadPlugins<T>() where T : class
{
if (!Directory.Exists(_pluginDirectory))
yield break;
foreach (var dll in Directory.GetFiles(_pluginDirectory, "*.dll"))
{
var context = new PluginLoadContext(dll);
var assembly = context.LoadFromAssemblyPath(Path.GetFullPath(dll));
foreach (var type in assembly.GetTypes()
.Where(t => typeof(T).IsAssignableFrom(t) && !t.IsAbstract))
{
if (Activator.CreateInstance(type) is T plugin)
yield return plugin;
}
}
}
}
// Custom AssemblyLoadContext to isolate plugin dependencies
public class PluginLoadContext : AssemblyLoadContext
{
private readonly AssemblyDependencyResolver _resolver;
public PluginLoadContext(string pluginPath) : base(isCollectible: true)
{
_resolver = new AssemblyDependencyResolver(pluginPath);
}
protected override Assembly? Load(AssemblyName assemblyName)
{
var path = _resolver.ResolveAssemblyToPath(assemblyName);
return path != null ? LoadFromAssemblyPath(path) : null;
}
}
Warning
Le chargement d’assemblys à partir d’un disque sans validation est un risque de sécurité. En production, vérifiez les signatures d’assembly (telles que Authenticode) avant le chargement, limitez les autorisations ACL du répertoire de plug-in et envisagez d’exécuter des plug-ins dans un processus distinct avec des privilèges réduits.
Définissez un contrat d’interface partagée dans un assembly distinct que l’hôte et les plug-ins référencent :
// Contoso.App.Contracts (shared assembly)
public interface IPluginExtension
{
string Name { get; }
string Description { get; }
void Execute(IServiceProvider services);
}
Note
L’utilisation isCollectible: true dans le fichier AssemblyLoadContext vous permet de décharger des plug-ins au moment de l’exécution. Cette approche évite les problèmes de gestion des versions que MEF (Managed Extensibility Framework) peut introduire dans les applications de bureau.
Contenu connexe
Windows developer