Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Windows предоставляет несколько технологий, которые позволяют приложению предоставлять функциональные возможности другим приложениям или использовать сторонние надстройки. В этой статье сравниваются доступные параметры расширяемости для Windows App SDK классических приложений.
Общие сведения о параметрах расширяемости
| Технология | Description | Требуется идентификатор пакета | Минимальная ОС |
|---|---|---|---|
| Службы приложений | Взаимодействие между приложениями по модели «запрос-ответ» AppServiceConnection |
Да | Windows 10 1607 |
| Расширения приложений | Модель подключаемого модуля — ведущее приложение обнаруживает содержимое из пакетов расширений | Да | Windows 10 1607 |
| Расширения пакетов | Более широкая расширяемость на уровне пакета с помощью uap17:PackageExtension |
Да | Windows 11 |
| Дополнительные пакеты | Дополнительные пакеты содержимого, дополняющие основное приложение | Да | Windows 10 1709 |
| Пакеты ресурсов | Языковые ресурсы, ресурсы для масштабирования и доступности, разделённые по рынкам | Да | Windows 10 |
Выбор правильной технологии
Используйте службы приложений, когда
- Требуется двустороннее взаимодействие между отдельными приложениями.
- Клиентское приложение отправляет запрос и ожидает ответа.
- Вы хотите предоставить интерфейс, похожий на API, другим приложениям.
Пример: служба перевода, которую другие приложения могут вызывать для перевода текста.
Используйте расширения приложений, когда
- Для вашего приложения требуется модель подключаемого модуля, в которой сторонние стороны предоставляют содержимое, темы или надстройки.
- Расширения обнаруживаются во время выполнения среди установленных пакетов.
- Расширения предоставляют данные или конфигурацию, а не исполняемый код (выполнение кода должно использовать службы приложений).
Пример: редактор изображений, который обнаруживает пакеты фильтров из установленных пакетов расширений.
Используйте расширения пакетов, когда
- Для Windows 11 требуется более широкая расширяемость на уровне пакета.
- Расширениям требуется доступ к большему содержимому пакета, чем
PublicFolderпозволяет модель.
Используйте необязательные пакеты, когда
- У вас есть дополнительное содержимое (DLC, премиум-функции), распределенное в виде отдельных пакетов.
- Содержимое создается тем же издателем.
Шаблоны архитектуры
Служба приложений с обнаружением расширений
Объединение расширений приложений со службами приложений для полной архитектуры подключаемых модулей:
- Ваше основное приложение использует
AppExtensionCatalogдля обнаружения установленных расширений. - Каждое расширение объявляет свойства, описывающие его возможности.
- Когда пользователь активирует расширение, ведущее приложение подключается к службе приложений расширения для двустороннего взаимодействия.
┌─────────────────┐ ┌──────────────────┐
│ Host app │ │ Extension app │
│ │ │ │
│ AppExtension │◄────►│ AppExtension │
│ Catalog │ │ declaration │
│ │ │ │
│ AppService │◄────►│ AppService │
│ Connection │ │ provider │
└─────────────────┘ └──────────────────┘
Только расширение содержимого
Для более простых сценариев, когда расширения предоставляют статическое содержимое (темы, шаблоны, файлы данных):
- Хост-приложение обнаруживает расширения через
AppExtensionCatalog. - Он считывает файлы из расширения
PublicFolder. - Служба приложений не требуется.
Различия от расширяемости UWP
Технологии расширяемости, описанные здесь, работают так же, как и в классических приложениях Windows App SDK, как и в UWP, с одним требованием: удостоверение пакета MSIX. Все возможности расширения опираются на манифест пакета для объявления и на каталог пакетов для обнаружения.
Если классическое приложение не упаковано, вы не можете использовать эти технологии расширения. Рассмотрим альтернативные подходы, такие как:
- Интерфейсы подключаемых модулей на основе COM
- Обнаружение расширений на основе файловой системы
- Именованные каналы или другие механизмы межпроцессного взаимодействия
Обнаружение плагинов на основе файлов для приложений без пакета
Для неупакованных приложений WinUI 3 можно реализовать систему подключаемых модулей с помощью AssemblyLoadContext в .NET для загрузки расширений из определённой папки:
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;
}
}
Предупреждение
Загрузка сборок с диска без проверки является угрозой безопасности. В рабочей среде проверьте подписи сборок (например, Authenticode) перед загрузкой, ограничьте разрешения ACL каталога подключаемого модуля и рассмотрите возможность запуска подключаемых модулей в отдельном процессе с ограниченными привилегиями.
Определите общий контракт интерфейса в отдельной сборке, на которую ссылаются как основное приложение, так и подключаемые модули:
// Contoso.App.Contracts (shared assembly)
public interface IPluginExtension
{
string Name { get; }
string Description { get; }
void Execute(IServiceProvider services);
}
Замечание
Использование isCollectible: true в AssemblyLoadContext позволяет выгружать подключаемые модули в процессе выполнения. Этот подход позволяет избежать проблем с версионированием, которые MEF (Managed Extensibility Framework) может вызывать в классических приложениях.
Связанные материалы
Windows developer