Criar aplicativos hospedados

A partir do Windows 10, versão 2004, você pode criar aplicativos hospedados. Um aplicativo hospedado compartilha o mesmo executável e a mesma definição que um aplicativo host pai, mas ele parece e se comporta como um aplicativo separado no sistema.

Aplicativos hospedados são úteis para cenários em que você deseja que um componente (como um arquivo executável ou um arquivo de script) se comporte como um aplicativo autônomo do Windows 10, mas o componente requer um processo de host para ser executado. Por exemplo, um script do PowerShell ou python pode ser entregue como um aplicativo hospedado que exige que um host seja instalado para ser executado. Um aplicativo hospedado pode ter seu próprio bloco inicial, identidade e profunda integração com os recursos do Windows 10, como tarefas em segundo plano, notificações, blocos e destinos de compartilhamento.

O recurso de aplicativos hospedados tem suporte de vários elementos e atributos no manifesto do pacote que permitem que um aplicativo hospedado use um executável e uma definição em um pacote de aplicativo host. Quando um usuário executa o aplicativo hospedado, o sistema operacional inicia automaticamente o executável do host sob a identidade do aplicativo hospedado. Em seguida, o host pode carregar ativos visuais, conteúdo ou APIs de chamada como o aplicativo hospedado. O aplicativo hospedado obtém a interseção de recursos declarados entre o host e o aplicativo hospedado. Isso significa que um aplicativo hospedado não pode solicitar mais recursos do que o que o host fornece.

Definir um host

O host é o main processo executável ou de runtime para o aplicativo hospedado. Atualmente, os únicos hosts com suporte são aplicativos da área de trabalho (desktop.NET ou C++) que têm identidade do pacote. Há várias maneiras de um aplicativo da área de trabalho ter a identidade do pacote:

O host é declarado em seu manifesto de pacote pela extensão uap10:HostRuntime . Essa extensão tem um atributo Id que deve ser atribuído a um valor que também é referenciado pelo manifesto do pacote para o aplicativo hospedado. Quando o aplicativo hospedado é ativado, o host é iniciado sob a identidade do aplicativo hospedado e pode carregar conteúdo ou binários do pacote do aplicativo hospedado.

O exemplo a seguir demonstra como definir um host em um manifesto de pacote. A extensão uap10:HostRuntime é em todo o pacote e, portanto, é declarada como um filho do elemento 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>

Anote esses detalhes importantes sobre os elementos a seguir.

Elemento Detalhes
uap10:Extension A windows.hostRuntime categoria declara uma extensão em todo o pacote que define as informações de runtime a serem usadas ao ativar um aplicativo hospedado. Um aplicativo hospedado será executado com as definições declaradas na extensão. Ao usar o aplicativo host declarado no exemplo anterior, um aplicativo hospedado será executado como o executávelPyScriptEngine.exe no nível de confiança mediumIL .

Os atributos Executable, uap10:RuntimeBehavior e uap10:TrustLevel especificam o nome do binário do processo de host no pacote e como os aplicativos hospedados serão executados. Por exemplo, um aplicativo hospedado usando os atributos no exemplo anterior será executado como o executável PyScriptEngine.exe no nível de confiança mediumIL.
uap10:HostRuntime O atributo Id declara o identificador exclusivo desse aplicativo host específico no pacote. Um pacote pode ter vários aplicativos host e cada um deve ter um elemento uap10:HostRuntime com uma ID exclusiva.

Declarar um aplicativo hospedado

Um aplicativo hospedado declara uma dependência de pacote em um host. O aplicativo hospedado aproveita a ID do host (ou seja, o atributo ID da extensão uap10:HostRuntime no pacote de host) para ativação em vez de especificar um executável de ponto de entrada em seu próprio pacote. O aplicativo hospedado normalmente contém conteúdo, ativos visuais, scripts ou binários que podem ser acessados pelo host. O valor TargetDeviceFamily no pacote do aplicativo hospedado deve ter como destino o mesmo valor que o host.

Os pacotes de aplicativos hospedados podem ser assinados ou não assinados:

  • Os pacotes assinados podem conter arquivos executáveis. Isso é útil em cenários que têm um mecanismo de extensão binária, que permite que o host carregue uma DLL ou um componente registrado no pacote do aplicativo hospedado.
  • Na maioria dos cenários, o pacote não assinado conterá conteúdo executável. Mas um pacote sem sinal que contém apenas arquivos não executáveis é útil em cenários em que o host precisa carregar apenas imagens, ativos e arquivos de conteúdo ou script. Os pacotes não assinados devem incluir um valor especial OID em seu elemento Identity ou não poderão ser registrados. Isso impede que pacotes não assinados entrem em conflito ou falsifiquem a identidade de um pacote assinado.

Para definir um aplicativo hospedado, declare os seguintes itens no manifesto do pacote:

O exemplo a seguir demonstra as seções relevantes de um manifesto de pacote para um aplicativo hospedado sem sinal.

<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>

Anote esses detalhes importantes sobre os elementos a seguir.

Elemento Detalhes
Identidade Como o pacote do aplicativo hospedado neste exemplo não está assinado, o atributo Publisher deve incluir a OID.2.25.311729368913984317654407730594956997722=1 cadeia de caracteres. Isso garante que o pacote não assinado não possa falsificar a identidade de um pacote assinado.
TargetDeviceFamily O atributo MinVersion deve especificar 10.0.19041.0 ou uma versão posterior do sistema operacional.
uap10:HostRuntimeDependency Esse elemento declara uma dependência no pacote do aplicativo host. Isso consiste no Nome e no Publicador do pacote de host e no MinVersion do qual ele depende. Esses valores podem ser encontrados no elemento Identity no pacote de host.
Aplicativo O atributo uap10:HostId expressa a dependência no host. O pacote do aplicativo hospedado deve declarar esse atributo em vez dos atributos Executáveis e EntryPoint usuais para um elemento Application ou Extension . Como resultado, o aplicativo hospedado herda os atributos Executable, EntryPoint e runtime do host com o valor hostId correspondente.

O atributo uap10:Parameters especifica parâmetros que são passados para a função de ponto de entrada do executável do host. Como o host precisa saber o que fazer com esses parâmetros, há um contrato implícito entre o host e o aplicativo hospedado.

Registrar um pacote de aplicativo hospedado sem sinal em tempo de execução

Um benefício da extensão uap10:HostRuntime é que ela permite que um host gere dinamicamente um pacote de aplicativo hospedado em runtime e registre-o usando a API PackageManager , sem a necessidade de assiná-lo. Isso permite que um host gere dinamicamente o conteúdo e o manifesto para o pacote do aplicativo hospedado e registre-o.

Use os métodos a seguir da classe PackageManager para registrar um pacote de aplicativo hospedado sem sinal. Esses métodos estão disponíveis a partir do Windows 10, versão 2004.

  • AddPackageByUriAsync: registra um pacote MSIX sem sinal usando a propriedade AllowUnsigned do parâmetro options .
  • RegisterPackageByUriAsync: executa um registro de arquivo de manifesto de pacote flexível. Se o pacote estiver assinado, a pasta que contém o manifesto deverá incluir um arquivo .p7x e um catálogo. Se não for assinado, a propriedade AllowUnsigned do parâmetro options deverá ser definida.

Requisitos para aplicativos hospedados não assinados

  • Os elementos Application ou Extension no manifesto do pacote não podem conter dados de ativação, como os atributos Executable, EntryPoint ou TrustLevel . Em vez disso, esses elementos só podem conter um atributo uap10:HostId que expressa a dependência no host e um atributo uap10:Parameters .
  • O pacote deve ser um pacote main. Não pode ser um pacote, um pacote de estrutura, um recurso ou um pacote opcional.

Requisitos para um host que instala e registra um pacote de aplicativo hospedado sem sinal

Amostra

Para um aplicativo de exemplo totalmente funcional que se declara como um host e, em seguida, registra dinamicamente um pacote de aplicativo hospedado em runtime, consulte o exemplo de aplicativo hospedado.

O host

O host é chamado PyScriptEngine. Esse é um wrapper escrito em C# que executa scripts python. Quando executado com o -Register parâmetro , o mecanismo de script instala um aplicativo hospedado que contém um script Python. Quando um usuário tenta iniciar o aplicativo hospedado recém-instalado, o host é iniciado e executa o script Python NumberGuesser .

O manifesto do pacote para o aplicativo host (o arquivo Package.appxmanifest na pasta PyScriptEnginePackage) contém uma extensão uap10:HostRuntime que declara o aplicativo como um host com a ID PythonHost e o executável PyScriptEngine.exe.

Observação

Neste exemplo, o manifesto do pacote é chamado Package.appxmanifest e faz parte de um Projeto de Empacotamento de Aplicativos do Windows. Quando esse projeto é criado, ele gera um manifesto chamado AppxManifest.xml e compila o pacote MSIX para o aplicativo host.

O aplicativo hospedado

O aplicativo hospedado consiste em um script python e artefatos de pacote, como o manifesto do pacote. Ele não contém nenhum arquivo PE.

O manifesto do pacote para o aplicativo hospedado (o arquivo NumberGuesser/AppxManifest.xml) contém os seguintes itens:

  • O atributo Publisher do elemento Identity contém o OID.2.25.311729368913984317654407730594956997722=1 identifer, que é necessário para um pacote não assinado.
  • O atributo uap10:HostId do elemento Application identifica PythonHost como seu host.

Execute o exemplo

O exemplo requer a versão 10.0.19041.0 ou posterior do Windows 10 e do SDK do Windows.

  1. Baixe o exemplo em uma pasta no computador de desenvolvimento.

  2. Abra a solução PyScriptEngine.sln no Visual Studio e defina o projeto PyScriptEnginePackage como o projeto de inicialização.

  3. Crie o projeto PyScriptEnginePackage .

  4. Em Gerenciador de Soluções, clique com o botão direito do mouse no projeto PyScriptEnginePackage e escolha Implantar.

  5. Abra uma janela do Prompt de Comando para o diretório em que você copiou os arquivos de exemplo e execute o comando a seguir para registrar o aplicativo NumberGuesser de exemplo (o aplicativo hospedado). Altere D:\repos\HostedApps para o caminho em que você copiou os arquivos de exemplo.

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

    Observação

    Você pode executar pyscriptengine na linha de comando porque o host no exemplo declara um AppExecutionAlias.

  6. Abra o menu Iniciar e clique em NumberGuesser para executar o aplicativo hospedado.