Создание размещенных приложений

Начиная с Windows 10 версии 2004, можно создавать размещенные приложения. Размещенное приложение использует тот же исполняемый файл и определение, что и родительское ведущее приложение, но оно выглядит и ведет себя как отдельное приложение в системе.

Размещенные приложения полезны в сценариях, где требуется, чтобы компонент (например, исполняемый файл или файл сценария) работал как автономное приложение Windows 10, но для работы компонента требуется процесс узла. Например, скрипт PowerShell или Python можно доставить в качестве размещенного приложения, которое требует установки узла для запуска. Размещенное приложение может иметь собственные плитку начального экрана, удостоверение и глубокую интеграцию с такими компонентами Windows 10, как фоновые задачи, уведомления, плитки и получатели данных.

Функция размещенных приложений поддерживается несколькими элементами и атрибутами в манифесте пакета, которые позволяют размещенное приложение использовать исполняемый файл и определение в пакете ведущего приложения. Когда пользователь запускает размещенное приложение, ОПЕРАЦИОННая система автоматически запускает исполняемый файл узла под удостоверением размещенного приложения. Затем узел может загружать визуальные ресурсы, содержимое или вызывать API в качестве размещенного приложения. Размещенное приложение получает пересечение возможностей, объявленных между ведущим и размещенным приложением. Это означает, что размещенное приложение не может запрашивать больше возможностей, чем предоставляет узел.

Определение узла

Узел — это main исполняемый файл или процесс среды выполнения для размещенного приложения. В настоящее время единственными поддерживаемыми узлами являются классические приложения (классические приложения .NET или C++), имеющие удостоверение пакета. Существует несколько способов получения удостоверения пакета в классическом приложении:

Узел объявляется в манифесте пакета расширением uap10:HostRuntime . Это расширение имеет атрибут Id , которому необходимо присвоить значение, на которое также ссылается манифест пакета для размещенного приложения. При активации размещенного приложения узел запускается под удостоверением размещенного приложения и может загружать содержимое или двоичные файлы из пакета размещенного приложения.

В следующем примере показано, как определить узел в манифесте пакета. Расширение uap10:HostRuntime является расширением на уровне пакета и поэтому объявляется дочерним элементом элемента 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 на уровне доверия mediumIL .

Атрибуты Executable, uap10:RuntimeBehavior и uap10:TrustLevel указывают имя двоичного файла хост-процесса в пакете и способ выполнения размещенных приложений. Например, размещенное приложение, использующее атрибуты из предыдущего примера, будет выполняться как исполняемый PyScriptEngine.exe на уровне доверия mediumIL.
uap10:HostRuntime Атрибут Id объявляет уникальный идентификатор этого конкретного ведущего приложения в пакете. Пакет может содержать несколько ведущих приложений, и каждое из них должно иметь элемент uap10:HostRuntime с уникальным идентификатором.

Объявление размещенного приложения

Размещенное приложение объявляет зависимость пакета от узла. Размещенное приложение использует идентификатор узла (то есть атрибут Id расширения uap10:HostRuntime в пакете узла) вместо указания исполняемого файла точки входа в собственном пакете. Размещенное приложение обычно содержит содержимое, визуальные ресурсы, скрипты или двоичные файлы, к которым может обращаться узел. Значение TargetDeviceFamily в пакете размещенного приложения должно быть равно значению узла.

Пакеты размещенных приложений могут быть подписаны или неподписанны:

  • Подписанные пакеты могут содержать исполняемые файлы. Это полезно в сценариях с механизмом двоичного расширения, который позволяет узлу загружать библиотеку DLL или зарегистрированный компонент в пакет размещенного приложения.
  • В большинстве сценариев неподписанный пакет будет содержать исполняемое содержимое. Но неподписанный пакет, содержащий только неисполняемые файлы, полезен в сценариях, когда ведущему приложению необходимо загружать только изображения, ресурсы и файлы содержимого или скриптов. Неподписанные пакеты должны содержать специальное OID значение в элементе Identity , иначе регистрация не будет разрешена. Это предотвращает конфликт неподписанных пакетов с удостоверением подписанного пакета или подделывание.

Чтобы определить размещенное приложение, объявите следующие элементы в манифесте пакета:

В следующем примере показаны соответствующие разделы манифеста пакета для неподписаного размещенного приложения.

<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 &quot;NumberGuesser.py&quot;">
    </Application>
  </Applications>

</Package>

Запишите эти важные сведения о следующих элементах.

Элемент Сведения
Идентификация Так как пакет размещенного приложения в этом примере является неподписанным, атрибут Publisher должен включать OID.2.25.311729368913984317654407730594956997722=1 строку. Это гарантирует, что неподписанный пакет не сможет подделывать удостоверение подписанного пакета.
TargetDeviceFamily Атрибут MinVersion должен указывать версию 10.0.19041.0 или более позднюю версию ОС.
uap10:HostRuntimeDependency Этот элемент элемента объявляет зависимость от пакета ведущего приложения. Он состоит из имени и издателя пакета узла, а также значения MinVersion , от которых он зависит. Эти значения можно найти в элементе Identity пакета узла.
Приложение Атрибут uap10:HostId выражает зависимость от узла. Размещенный пакет приложения должен объявлять этот атрибут вместо обычных атрибутов Executable и EntryPoint для элемента Application или Extension . В результате размещенное приложение наследует атрибуты Executable, EntryPoint и среды выполнения от узла с соответствующим значением HostId .

Атрибут uap10:Parameters указывает параметры, которые передаются в функцию точки входа исполняемого файла узла. Так как узел должен знать, что делать с этими параметрами, существует подразумеваемый контракт между узлом и размещенным приложением.

Регистрация неподписаного пакета размещенного приложения во время выполнения

Одним из преимуществ расширения uap10:HostRuntime является то, что оно позволяет узлу динамически создавать размещенный пакет приложения во время выполнения и регистрировать его с помощью API PackageManager без необходимости подписывать его. Это позволяет узлу динамически создавать содержимое и манифест для пакета размещенного приложения, а затем регистрировать их.

Используйте следующие методы класса PackageManager , чтобы зарегистрировать неподписанный пакет размещенного приложения. Эти методы доступны начиная с Windows 10 версии 2004.

  • AddPackageByUriAsync: регистрирует неподписанный пакет MSIX с помощью свойства AllowUnsigned параметра options .
  • RegisterPackageByUriAsync: выполняет регистрацию свободного файла манифеста пакета. Если пакет подписан, папка, содержащая манифест, должна содержать P7X-файл и каталог. В случае без знака необходимо задать свойство AllowUnsigned параметра options .

Требования к неподписанным размещенным приложениям

  • Элементы Application или Extension в манифесте пакета не могут содержать данные активации, такие как атрибуты Executable, EntryPoint или TrustLevel . Вместо этого эти элементы могут содержать только атрибут uap10:HostId , который выражает зависимость от узла и атрибут uap10:Parameters .
  • Пакет должен быть пакетом main. Это не может быть пакет, пакет платформы, ресурс или необязательный пакет.

Требования к узлу, который устанавливает и регистрирует неподписанный пакет размещенного приложения

Образец

Полнофункциональный пример приложения, которое объявляет себя в качестве узла, а затем динамически регистрирует пакет размещенного приложения во время выполнения, см. в примере размещенного приложения.

Узел.

Узел называется 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.

  1. Скачайте пример в папку на компьютере разработчика.

  2. Откройте решение PyScriptEngine.sln в Visual Studio и задайте проект PyScriptEnginePackage в качестве запускаемого проекта.

  3. Выполните сборку проекта PyScriptEnginePackage .

  4. В Обозреватель решений щелкните правой кнопкой мыши проект PyScriptEnginePackage и выберите Развернуть.

  5. Откройте окно командной строки в каталоге, в который вы скопировали примеры файлов, и выполните следующую команду, чтобы зарегистрировать пример приложения NumberGuesser (размещенное приложение). Измените D:\repos\HostedApps путь, по которому вы скопировали примеры файлов.

    D:\repos\HostedApps>pyscriptengine -Register D:\repos\HostedApps\NumberGuesser\AppxManifest.xml
    

    Примечание

    Вы можете выполнить команду pyscriptengine в командной строке, так как узел в примере объявляет AppExecutionAlias.

  6. Откройте меню Пуск и выберите NumberGuesser , чтобы запустить размещенное приложение.