В Windows 10 версии 2004 представлено концепцию размещенных приложений в Windows App Model. Размещенные приложения регистрируются как независимые приложения в Windows, но для их запуска требуется хост-процесс. Примером может служить файл сценария, который требует установки его хоста (например, Powershell или Python). Сам по себе это всего лишь файл, и он не имеет возможности отображаться как приложение для Windows. С помощью модели размещенного приложения приложение может объявить себя хостом, а затем пакеты могут объявить зависимость от этого хоста и называться размещенными приложениями. Когда запускается размещенное приложение, исполняемый файл узла запускается с идентификатором пакета размещенного приложения, а не с его собственной идентификацией. Это позволяет хосту иметь доступ к содержимому пакета размещенного приложения, а при вызове API он делает это с помощью идентификатора размещенного приложения.
Предыстория
Современные приложения определяются для Windows через подписанные пакеты MSIX. Пакет обеспечивает идентификацию, поэтому он известен системе и содержит все файлы, активы и регистрационную информацию для приложения. У многих приложений есть сценарии, в которых они хотят разместить контент и двоичные файлы, такие как точки расширения, из других приложений. Существуют также сценарии, в которых хост-приложение представляет собой скорее механизм времени выполнения, который загружает содержимое сценария. Вдобавок ко всему, существует желание, чтобы эти размещенные приложения выглядели и вели себя как отдельное приложение в системе – где у него есть собственная стартовая плитка, идентификация и глубокая интеграция с такими функциями Windows, как BackgroundTasks, Notifications и Share. С помощью модели размещенного приложения можно легко переименовать приложение розничного киоска, или скрипт Python или Powershell теперь можно рассматривать как отдельное приложение.
Разработчики пытаются сделать это сегодня одним из двух способов. Во-первых, они просто используют ярлык на рабочем столе для запуска хоста. Но как показывает опыт, это не имеет какой-либо глубокой интеграции с Windows и оболочкой, поскольку «приложение» – это исполняемый файл узла, а не сценарий. Чтобы получить более глубокую интеграцию, разработчики могут создать упакованное приложение, включающее двоичные файлы хоста в пакете. Хотя пакет теперь будет отдельным приложением и будет иметь возможность глубокой интеграции с Windows, этот подход неэффективен, поскольку каждое приложение должно было бы перераспределять хост а это может повлечь за собой потенциальные проблемы с обслуживанием и лицензированием.
Модель размещенных приложений удовлетворяет потребности этих размещенных приложений. Это зависит от двух частей: «хоста», доступного для других приложений, и «размещенного приложения», которое указывает на зависимость от хоста. Когда запускается размещаемое приложение, в результате хост запускается под идентификатором пакета размещенного приложения, так что он может загружать визуальные ресурсы, содержимое из местоположения пакета размещенного приложения, и когда он вызывает API, он делает это с идентификатором, объявленным в размещенном приложении. Размещенное приложение получает пересечение возможностей, объявленных между хостом и размещенным приложением – это означает, что, если размещенное приложение не может запросить больше возможностей, чем предоставляет хост. В этом первоначальном выпуске модели размещенных приложений поддерживаются упакованные настольные приложения, и Windows будет расширять поддержку узлов UWP в будущих выпусках.
Что такое хост и размещенное приложение?
В частности, Host – это исполняемый файл в пакете, объявленном расширением HostRuntime который указывает на основной исполняемый файл или процесс выполнения для размещенного приложения. Расширение HostRuntime имеет атрибут Id, и этот идентификатор упоминается в качестве зависимости размещенным приложением в манифесте пакета. Хост может определить идентификатор пакета, под которым он в данный момент работает, ссылаясь на API Windows.ApplicationModel.Package.Current. Размещенное приложение – это приложение, которое объявляет зависимость пакета от хоста и использует для активации идентификатор HostRuntime вместо указания исполняемого файла Entrypoint в своем собственном пакете. Обычно он содержит контент, визуальные ресурсы, сценарии или двоичные файлы, к которым хост может получить доступ.
Пакеты размещенных приложений могут быть подписаны или не подписаны:
• Подписанные пакеты могут содержать исполняемые файлы. Это полезно в сценариях, которые имеют механизм расширения, загружать dll или зарегистрированный компонент в пакет размещенного приложения.
• Неподписанные пакеты могут содержать только неисполняемые файлы. Это полезно в сценариях, где hostruntime требуется только для загрузки изображений, ресурсов и контента. Неподписанные пакеты должны включать в свой идентификатор специальный OID неподписанного издателя, иначе им не будет разрешено зарегистрироваться. Это не позволяет неподписанным пакетам подделывать подписанные идентификаторы пакетов.
Объявление о хосте
Объявление хоста довольно просто. Все, что вам нужно сделать, это указать расширение пакета HostRuntime в вашем AppxManifest.xml. Расширение HostRuntime распространяется на весь пакет и поэтому объявляется дочерним элементом пакета. Ниже приведен отрывок из примера AppxManifest.xml, показывающий запись HostRuntime, которая объявляет приложение в качестве хоста с идентификатором «PythonHost».
• hostRuntime – расширение пакета, определяющее информацию о времени выполнения, используемую при активации размещенного приложения.
• Executable – исполняемый двоичный файл, который будет хост-процессом
•RuntimeBehavior и TrustLevel – размещенное приложение будет работать с определениями, выраженными в расширении. Например, размещенное приложение, использующее узел, объявленный выше, будет запускать исполняемый файл PyScriptEngine.exe с уровнем доверия MiddleIL.
• Host Runtime Is – уникальный идентификатор, используемый для указания хоста в пакете. Пакет может иметь несколько приложений хоста, и у каждого должен быть уникальный идентификатор HostRuntime. На этот идентификатор ссылается размещенное приложение.
Объявление о размещении приложения
Размещенное приложение должно объявить зависимость пакета от хоста и указать HostId для использования. Если пакет не подписан, он должен включать OID неподписанного издателя, чтобы удостоверение пакета не конфликтовало с подписанным пакетом. Также TargetDeviceFamily должен соответствовать хосту, поэтому он не пытается развертываться на устройствах, которые не поддерживаются хостом. Ниже приведен пример манифеста для размещенного приложения, который принимает зависимость от хоста Python.
• Unsigned Publisher OID – 2.25.311729368913984317654407730594956997722=1 Этот идентификатор требуется, когда размещенное приложение будет неподписанным. Этот идентификатор гарантирует, что любой неподписанный пакет не сможет подделать удостоверение подписанного пакета.
• HostRuntimeDependency – пакет размещенного приложения должен объявить HostRuntimeDependency в приложении хоста. Он состоит из имени и издателя пакета хоста и минимальной версии, от которой он зависит. Их можно найти в элементе в пакете Host. При развертывании, если HostRuntimeDependency не может быть найден, регистрация завершается неудачно.
• HostId – вместо того, чтобы объявлять обычный исполняемый файл и EntryPoint для приложения или расширения, атрибут HostId выражает зависимость от приложения хоста. В результате размещенное приложение наследует атрибуты Executable, EntryPoint и среды выполнения Host с указанным HostId. При регистрации, если HostId не найден, развертывание не выполняется.
• Parameters (необязательно) – параметры, которые передаются в командной строке приложению хоста. Хост должен знать, что делать с этими параметрами, и поэтому между хостом и размещенным приложением существует подразумеваемый договор.
Динамическая регистрация для неподписанных размещенных приложений
Одним из преимуществ нового HostRuntime является то, что он позволяет хосту динамически регистрировать пакет размещенного приложения во время выполнения. Этот динамически зарегистрированный пакет не требует подписи. Что позволяет хосту динамически генерировать контент и манифест для пакета размещенного приложения, а затем регистрировать его. Разработчики работают с новым браузером Microsoft Edge, чтобы использовать преимущества модели размещенных приложений для Progressive Web Apps (PWA) – преобразование манифеста веб-приложения в манифест приложения, упаковка дополнительного веб-содержимого в пакет MSIX и его регистрация. В этой модели PWA – это собственное независимое приложение, зарегистрированное в системе, даже если оно размещено на Edge.
Новые API для регистрации пакета:
• Management.Deployment.PackageManager.AddPackageByUriAsync () используется для регистрации пакета MSIX
• Management.Deployment.PackageManager.RegisterPackageByUriAsync () используется для регистрации свободного файла AppxManifest.xml.
В случае, когда размещенное приложение не подписано, его манифест должен соответствовать следующим требованиям:
1. Неподписанный пакет не может содержать никаких атрибутов Executable в своих элементах Application или Extension (например, нет или ), и он не может указывать какие-либо другие данные активации (Executable, TrustLevel и т. д.). Узел приложения поддерживает только элементы HostId и Parameters.
2. Неподписанный пакет должен быть основным типом пакета – он не может быть пакетом Bundle, Framework, Resource или Optional.
В свою очередь, хост-процесс, регистрирующий неподписанный размещенный пакет приложения, должен отвечать следующим требованиям:
1. Процесс должен иметь идентичность пакета
2. Процесс должен иметь возможность управления пакетами
Примеры хоста и размещенного приложения
Давайте посмотрим на два примера. Первый, WinFormsToastHost, – это хост с подписанным размещенным приложением, который показывает, как включить расширение, которое динамически загружается в хост. Второй, NumberGuesser, пример использования python в качестве хоста и файла сценария в качестве пакета размещенного приложения. Вы можете найти пример кода для обоих по адресу https://aka.ms/hostedappsample.
WinFormsToastHost
Хост
Хост в этом примере – это простое приложение Windows Forms, которое отображает идентификацию своего пакета, местоположение и вызывает API-интерфейсы ToastNotification. Он также может загружать двоичное расширение из пакета размещенного приложения. При запуске под собственной идентификацией он не отображает информацию о расширении. Приложение поставляется вместе с проектом упаковки приложений Windows, который включает декларации манифеста о том, что он является хостом.
WinformsToastHost-Extension
Размещенное приложение – это библиотека .NET, которая реализует механизм расширения для загрузки хоста. Он также включает в себя проект упаковки, который объявляет свою идентичность и зависимость от hostruntime. Эта личность будет отображаться в значениях, отображаемых при запуске приложения. После регистрации hostruntime имеет доступ к расположению пакета в hostedapp и, таким образом, может загрузить расширение.
Запуск образца
Вы можете загрузить исходный код в Visual Studio следующим образом:
1. Откройте WinformsToastHost.sln в VS2019
2. Build и deploy WinformsToastHost.Package
3. Build и deploy HostedAppExtension
4. Перейти в меню «Пуск» и запустить «WinformsToastHost»
5. Перейдите в меню «Пуск» и запустите «Hosted WinformsToastHost Extension»
Вот скриншот работающего хоста. Обратите внимание на его идентификатор пакета и путь, а UX для загрузки сборки недоступен, поскольку он не работает как размещенное приложение.
Теперь запустите размещенное приложение. Обратите внимание, что идентификатор и путь изменились, и что UX для динамической загрузки сборки расширения включен.
При нажатии кнопки «Run hosted» вы получите диалог из двоичного расширения:
Вот подробное представление диспетчера задач, показывающее, что оба приложения работают одновременно. Обратите внимание, что двоичный файл хоста является исполняемым для обоих:
При нажатии на кнопку «Показать тост» для каждого приложения система распознает две разные личности в центре действий:
NumberGuesser – Игры и Python
Хост
В этом примере хост состоит из 2 проектов. Первый – это PyScriptEngine, который является оболочкой, написанной на C #, и использует пакет nuget Python для запуска скриптов Python. Эта оболочка анализирует командную строку и имеет возможность динамически регистрировать манифест, а также запускать исполняемый файл python с путем к файлу сценария. Вторым проектом является PyScriptEnginePackage, который представляет собой проект упаковки приложений Windows, который устанавливает PyScriptEngine и регистрирует манифест, который включает расширение HostRuntime.
Хостинг приложения
Размещенное приложение состоит из скрипта Python, NumberGuesser.py и визуальных ресурсов. Он не содержит PE-файлов. Он имеет манифест приложения, в котором объявляются заявления для HostRuntimeDependency и HostId, которые идентифицируют PyScriptEngine в качестве своего хоста. Манифест также содержит запись OID неподписанного издателя, которая требуется для неподписанного пакета.
Запуск образца
Для запуска этого примера сначала необходимо создать и развернуть хост, затем вы можете использовать хост из командной строки для динамической регистрации размещенного приложения.
1. Откройте расширение PyScriptEngine.sln в Visual Studio
2. Установите PyScriptEnginePackage в качестве проекта запуска
3. Сборка PyScriptEnginePackage
4. Развернуть PyScriptEnginePackage
5. Поскольку приложение хоста объявляет appexecutionalias, вы сможете перейти в командную строку и запустить «pyscriptengine», чтобы получить уведомление об использовании:
6. Используйте хост python для регистрации игры Number Guesser из командной строки:
7. Теперь нажмите «Number Guesser (Manifest)» в меню «Пуск» и запустите игру! Посмотрите, сколько попыток нужно, чтобы угадать число:
Давайте подтвердим, что это работает. Обратите внимание, как PyScriptEngine выполняется под идентификатором пакета NumberGuesser!
Подведем итоги!
Таким образом, Microsoft предоставляет нам больше возможностей и возможностей для платформы Windows, и команды рады видеть, какие креативные идеи у вас есть для модели размещенного приложения. В дополнение к Microsoft Edge, ведется разработка с командами по всей компании и ожидается больше приложений, использующих Hosted App Model в будущем.
Источник