Создание размещенных приложений
Начиная с Windows 10 версии 2004, вы можете создавать размещенные приложения. Размещенное приложение использует тот же исполняемый файл и определение, что и родительское приложение узла , но выглядит и ведет себя как отдельное приложение в системе.
Размещенные приложения полезны в сценариях, где требуется, чтобы компонент (например, исполняемый файл или файл сценария) работал как автономное приложение Windows 10, но для работы компонента требуется процесс узла. Например, скрипт PowerShell или Python можно доставить как размещенное приложение, которое требует установки узла для запуска. Размещенное приложение может иметь собственные плитку начального экрана, удостоверение и глубокую интеграцию с такими компонентами Windows 10, как фоновые задачи, уведомления, плитки и получатели данных.
Функция размещенных приложений поддерживается несколькими элементами и атрибутами в манифесте пакета, которые позволяют размещенного приложения использовать исполняемый файл и определение в пакете ведущего приложения. Когда пользователь запускает размещенное приложение, ОС автоматически запускает исполняемый файл узла под удостоверением размещенного приложения. Затем узел может загружать визуальные ресурсы, содержимое или вызывать API в качестве размещенного приложения. Размещенное приложение получает пересечение возможностей, объявленных между узлом и размещенным приложением. Это означает, что размещенное приложение не может запрашивать больше возможностей, чем предоставляет узел.
Узел — это основной исполняемый процесс или процесс среды выполнения для размещенного приложения. В настоящее время единственными поддерживаемыми узлами являются классические приложения (.NET или C++ desktop), имеющие удостоверение пакета. Существует несколько способов для классического приложения, чтобы иметь удостоверение пакета:
- Наиболее распространенным способом предоставления удостоверения пакета классическому приложению является упаковка его в пакет MSIX.
- В некоторых случаях можно также предоставить удостоверение пакета, создав пакет с внешним расположением (см . раздел "Предоставить удостоверение пакета путем упаковки с внешним расположением"). Этот параметр полезен, если вы не можете применить MSIX для установки классического приложения.
Узел объявлен в манифесте пакета расширением uap10:HostRuntime . Это расширение имеет атрибут id , который должен быть назначен значением, на которое также ссылается манифест пакета для размещенного приложения. При активации размещенного приложения узел запускается под удостоверением размещенного приложения и может загружать содержимое или двоичные файлы из размещенного пакета приложения.
В следующем примере показано, как определить узел в манифесте пакета. Расширение uap10:HostRuntime является расширением package-wide и поэтому объявляется дочерним элементом Package .
<Package xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10">
<Extensions>
<uap10:Extension Category="windows.hostRuntime"
Executable="PyScriptEngine\PyScriptEngine.exe"
uap10:RuntimeBehavior="packagedClassicApp"
uap10:TrustLevel="mediumIL">
<uap10:HostRuntime Id="PythonHost" />
</uap10:Extension>
</Extensions>
</Package>
Запишите эти важные сведения о следующих элементах.
Элемент | Сведения |
---|---|
uap10:Extension | Категория windows.hostRuntime объявляет расширение на уровне пакета, определяющее сведения о среде выполнения, которые будут использоваться при активации размещенного приложения. Размещенное приложение будет работать с определениями, объявленными в расширении. При использовании ведущего приложения, объявленного в предыдущем примере, размещенное приложение будет работать в качестве исполняемого PyScriptEngine.exe на уровне доверия среднего уровня.Атрибуты Исполняемого файла, uap10:RuntimeBehavior и uap10:TrustLevel указывают имя двоичного файла процесса узла в пакете и способ выполнения размещенных приложений. Например, размещенное приложение, использующее атрибуты в предыдущем примере, будет выполняться как исполняемый PyScriptEngine.exe на уровне доверия среднего уровня. |
uap10:HostRuntime | Атрибут Id объявляет уникальный идентификатор этого конкретного ведущего приложения в пакете. Пакет может иметь несколько ведущих приложений, и каждый из них должен иметь элемент uap10:HostRuntime с уникальным идентификатором. |
Размещенное приложение объявляет зависимость пакета от узла. Размещенное приложение использует идентификатор узла (то есть атрибут идентификатора расширения uap10:HostRuntime в пакете узла) для активации вместо указания исполняемого файла точки входа в собственном пакете. Размещенное приложение обычно содержит содержимое, визуальные ресурсы, скрипты или двоичные файлы, к которым может обращаться узел. Значение TargetDeviceFamily в размещенном пакете приложения должно быть нацелено на то же значение, что и узел.
Размещенные пакеты приложений можно подписать или отменить знак:
- Подписанные пакеты могут содержать исполняемые файлы. Это полезно в сценариях с двоичным механизмом расширения, что позволяет узлу загружать библиотеку DLL или зарегистрированный компонент в размещенном пакете приложения.
- В большинстве случаев пакет без знака будет содержать исполняемое содержимое. Но неподписанный пакет, содержащий только не исполняемые файлы, полезен в сценариях, когда узел должен загружать только изображения, ресурсы и файлы содержимого или скрипта. Неподписанные пакеты должны содержать специальное
OID
значение в элементе Identity или они не будут разрешены для регистрации. Это предотвращает конфликт с неподписанными пакетами или спуфингом удостоверения подписанного пакета.
Чтобы определить размещенное приложение, объявите следующие элементы в манифесте пакета:
- Элемент uap10:HostRuntimeDependency . Это дочерний элемент элемента Dependencies .
- Атрибут uap10:HostId элемента Application (для приложения) или элемента Extension (для активируемого расширения).
В следующем примере показаны соответствующие разделы манифеста пакета для неназначенных размещенных приложений.
<Package xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10">
<Identity Name="NumberGuesserManifest"
Publisher="CN=AppModelSamples, OID.2.25.311729368913984317654407730594956997722=1"
Version="1.0.0.0" />
<Dependencies>
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.19041.0" MaxVersionTested="10.0.19041.0" />
<uap10:HostRuntimeDependency Name="PyScriptEnginePackage" Publisher="CN=AppModelSamples" MinVersion="1.0.0.0"/>
</Dependencies>
<Applications>
<Application Id="NumberGuesserApp"
uap10:HostId="PythonHost"
uap10:Parameters="-Script "NumberGuesser.py"">
</Application>
</Applications>
</Package>
Запишите эти важные сведения о следующих элементах.
Элемент | Сведения |
---|---|
Identity | Так как размещенный пакет приложения в этом примере не указан, атрибут Publisher должен включать OID.2.25.311729368913984317654407730594956997722=1 строку. Это гарантирует, что неподписанный пакет не может подделывать удостоверение подписанного пакета. |
TargetDeviceFamily | Атрибут MinVersion должен указать версию 10.0.19041.0 или более позднюю версию ОС. |
uap10:HostRuntimeDependency | Этот элемент элемента объявляет зависимость от пакета ведущего приложения. Это состоит из имени и издателя пакета узла, а minVersion зависит от него. Эти значения можно найти в элементе Identity в пакете узла. |
Приложение | Атрибут uap10:HostId выражает зависимость от узла. Пакет размещенного приложения должен объявлять этот атрибут вместо обычных атрибутов Исполняемого файла и EntryPoint для элемента Application или Extension. В результате размещенное приложение наследует атрибуты исполняемого файла, EntryPoint и среды выполнения от узла с соответствующим значением HostId . Атрибут uap10:Parameters задает параметры, передаваемые в функцию точки входа исполняемого файла узла. Так как узел должен знать, что делать с этими параметрами, существует подразумеваемый контракт между узлом и размещенным приложением. |
Одним из преимуществ расширения uap10:HostRuntime является то, что узел позволяет узлу динамически создавать размещенный пакет приложения во время выполнения и регистрировать его с помощью API PackageManager без необходимости подписывать его. Это позволяет узлу динамически создавать содержимое и манифест для размещенного пакета приложения, а затем зарегистрировать его.
Чтобы зарегистрировать неподписанный пакет приложения, используйте следующие методы класса PackageManager . Эти методы доступны начиная с Windows 10 версии 2004.
- AddPackageByUriAsync: регистрирует неподписанный пакет MSIX с помощью свойства AllowUnsigned параметра options.
- RegisterPackageByUriAsync: выполняет регистрацию свободного файла манифеста пакета. Если пакет подписан, папка, содержащая манифест, должна содержать P7X-файл и каталог. При отмене знака необходимо задать свойство AllowUnsigned параметра options.
- Элементы приложения или расширения в манифесте пакета не могут содержать данные активации, такие как атрибуты Исполняемого файла, EntryPoint или TrustLevel. Вместо этого эти элементы могут содержать только атрибут uap10:HostId , который выражает зависимость от узла и атрибута uap10:Parameters .
- Пакет должен быть основным пакетом. Он не может быть пакетом, пакетом платформы, ресурсом или необязательным пакетом.
- Узел должен иметь удостоверение пакета.
- Узел должен иметь ограниченную возможность packageManagement.
<rescap:Capability Name="packageManagement" />
Полный функциональный пример приложения, который объявляет себя в качестве узла, а затем динамически регистрирует размещенный пакет приложения во время выполнения, см. в примере размещенного приложения.
Узел называется PyScriptEngine. Это оболочка, написанная на C# с скриптами Python. При запуске с -Register
параметром подсистема скриптов устанавливает размещенное приложение, содержащее скрипт Python. Когда пользователь пытается запустить только что установленное размещенное приложение, узел запускается и выполняет скрипт Python NumberGuesser .
Манифест пакета для ведущего приложения (файл Package.appxmanifest в папке PyScriptEnginePackage) содержит расширение uap10:HostRuntime , которое объявляет приложение как узел с идентификатором PythonHost и исполняемым PyScriptEngine.exe.
Примечание
В этом примере манифест пакета называется Package.appxmanifest и является частью проекта упаковки приложений Windows. При построении этого проекта он создает манифест с именем AppxManifest.xml и создает пакет MSIX для ведущего приложения.
Размещенное приложение состоит из скрипта Python и артефактов пакета, таких как манифест пакета. Он не содержит файлы PE.
Манифест пакета для размещенного приложения (файл NumberGuesser/AppxManifest.xml) содержит следующие элементы:
- Атрибут Publisher элемента Identity содержит
OID.2.25.311729368913984317654407730594956997722=1
идентификатор, который требуется для неподписавшегося пакета. - Атрибут uap10:HostId элемента Application определяет PythonHost в качестве узла.
Для примера требуется версия 10.0.19041.0 или более поздняя версия Windows 10 и Windows SDK.
Скачайте пример в папку на компьютере разработки.
Откройте решение PyScriptEngine.sln в Visual Studio и задайте проект PyScriptEnginePackage в качестве запускаемого проекта.
Создайте проект PyScriptEnginePackage.
В Обозреватель решений щелкните правой кнопкой мыши проект PyScriptEnginePackage и выберите "Развернуть".
Откройте окно командной строки в каталог, где вы скопировали примеры файлов и выполните следующую команду, чтобы зарегистрировать пример приложения NumberGuesser (размещенное приложение). Перейдите
D:\repos\HostedApps
к пути, в котором вы скопировали примеры файлов.D:\repos\HostedApps>pyscriptengine -Register D:\repos\HostedApps\NumberGuesser\AppxManifest.xml
Примечание
Можно запустить
pyscriptengine
в командной строке, так как узел в примере объявляет AppExecutionAlias.Откройте меню "Пуск" и нажмите кнопку NumberGuesser, чтобы запустить размещенное приложение.