Compartilhar via


Conceder o identificador de pacote por empacotamento com localização externa manualmente

Para obter as motivações por trás da adição da identidade do pacote, bem como as diferenças entre a criação de pacotes de identidade no Visual Studio e a criação manual, consulte Visão geral.

Este tópico descreve como criar e registrar um pacote de identidade manualmente. Para obter informações sobre como criar um pacote de identidade no Visual Studio, consulte Conceder identidade ao pacote através do empacotamento com localização externa no Visual Studio.

Estas são as etapas (que este tópico descreve em detalhes) para criar e registrar um pacote de identidade manualmente:

  1. Criar um manifesto do pacote para o pacote de identidade
  2. Compilar e assinar o pacote de identidade
  3. Adicionar aos manifests de aplicativos desktop os metadados de identidade
  4. Registrar o pacote de identidade no instalador
  5. Etapas opcionais

Criar um manifesto do pacote para o pacote de identidade

A primeira etapa para criar um pacote de identidade é criar um manifesto de pacote com base no modelo abaixo. Esse é um manifesto MSIX, mas é usado apenas para identidade e não altera o comportamento de runtime do aplicativo.

<?xml version="1.0" encoding="utf-8"?>
<Package IgnorableNamespaces="uap uap10"
  xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
  xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
  xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10"
  xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities">
  <Identity Name="ContosoPhotoStore" Publisher="CN=Contoso" Version="1.0.0.0" ProcessorArchitecture="neutral" />
  <Properties>
    <DisplayName>Contoso PhotoStore</DisplayName>
    <PublisherDisplayName>Contoso</PublisherDisplayName>
    <Logo>Assets\storelogo.png</Logo>
    <uap10:AllowExternalContent>true</uap10:AllowExternalContent>
  </Properties>
  <Resources>
    <Resource Language="en-us" />
  </Resources>
  <Dependencies>
    <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.19041.0" MaxVersionTested="10.0.26100.0" />
  </Dependencies>
  <Capabilities>
    <rescap:Capability Name="runFullTrust" />
    <rescap:Capability Name="unvirtualizedResources"/>
  </Capabilities>
  <Applications>
    <Application Id="ContosoPhotoStore" Executable="ContosoPhotoStore.exe" uap10:TrustLevel="mediumIL" uap10:RuntimeBehavior="win32App"> 
      <uap:VisualElements AppListEntry="none" DisplayName="Contoso PhotoStore" Description="Contoso PhotoStore App" BackgroundColor="transparent" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" />
    </Application>
  </Applications>
</Package>

Observe os detalhes importantes abaixo sobre este manifesto:

  • Preencha os atributos de Identity elemento com os detalhes do aplicativo
    • Name é o nome desejado do pacote de identidade
    • Publisher deve corresponder ao Subject certificado usado para assinar o aplicativo
    • Version é a versão desejada do pacote de identidade. Uma prática comum é alinhar a versão do pacote de identidade com a versão do aplicativo. Você não poderá registrar uma versão de um pacote de identidade em um sistema se essa versão do pacote já estiver registrada. Primeiro, você deve cancelar o registro do pacote existente para reinstalar um pacote com a mesma versão.
    • ProcessorArchitecture deve ser neutral como mostrado para que o pacote de identidade funcione em todas as arquiteturas (x86, x64 e ARM64)
  • Preencha os elementos DisplayName e PublisherDisplayName com os detalhes do seu aplicativo
    • A menos que você adicione recursos adicionais ao manifesto além da identidade simples, esses valores não são exibidos em nenhum lugar
  • Atualize o elemento Logo para um caminho relativo dentro do diretório de instalação do aplicativo que será resolvido para uma imagem .png, .jpg ou .jpeg
  • Verifique se o AllowExternalContent elemento está definido true como mostrado, o que permite reutilizar seu instalador existente
  • Defina TargetDeviceFamilyMinVersion e MaxVersionTested conforme abaixo:
    • Defina MinVersion como 10.0.19041.0 conforme mostrado para o máximo de alcance e uniformidade nas versões do sistema operacional Windows 10 e Windows 11
    • Defina MinVersion para 10.0.26100.0 restringir o pacote de identidade ao Windows 11, versão 24H2 e superior
    • Configure MaxVersionTested para 10.0.26100.0 conforme mostrado
    • Observação: o AllowExternalContent recurso usado aqui foi introduzido no Windows build 10.0.19041.0. Se o aplicativo for executado em versões mais antigas do que essa, você deverá executar uma verificação de versão do sistema operacional no instalador e não registrar o pacote de identidade em versões do sistema operacional anteriores à 10.0.19041.0. Consulte Registrar o pacote de identidade no instalador.
  • Verifique se as capacidades runFullTrust e unvirtualizedResources são declaradas conforme mostrado para a compatibilidade com o Win32
  • Adicionar um Application elemento conforme mostrado para cada executável associado ao seu aplicativo
    • Verifique se TrustLevel está mediumIL e RuntimeBehavior está win32App conforme mostrado para a compatibilidade do Win32
  • O elemento filho VisualElements é necessário, mas o atributo AppListEntry="none" garante que o pacote de identidade não seja mostrado entre os aplicativos instalados
    • Atualize os atributos DisplayName e Description com detalhes relevantes e mantenha os outros atributos como mostrado (os caminhos de imagem referenciados não precisam ser resolvidos)
    • Consulte Localização e Ativos Visuais para ver cenários em que a localização e as imagens podem ser necessárias aqui.

O pacote de identidade criado com base nesse manifesto será conectado ao diretório de instalação do aplicativo quando você registrar o pacote em uma etapa posterior.

Compilar e assinar o pacote de identidade

Depois de criar o manifesto do pacote de identidade, crie o pacote de identidade usando a ferramentaMakeAppx.exe no SDK do Windows.

MakeAppx.exe pack /o /d <path to directory that contains manifest> /nv /p <output path>\MyPackage.msix

Observação: a flag /nv é necessária para ignorar a validação de caminhos de arquivo referenciados no manifesto.

Para ser instalado em computadores de usuário final, o pacote de identidade deve ser assinado com um certificado confiável no computador de destino. Você pode criar um novo certificado autoassinado para fins de desenvolvimento e assinar seu pacote de identidade usando o SignTool, que está disponível no SDK do Windows, mas um certificado de produção de um Departamento de TI ou de um serviço como a Assinatura Confiável do Azure será necessário para registrar o pacote em computadores de usuário final.

SignTool.exe sign /fd SHA256 /a /f <path to certificate>\MyCertificate.pfx /p <certificate password> <path to package with external location>\MyPackage.msix

Observação: para saber como criar e assinar o pacote de identidade em um pipeline de CI/CD com certificados de produção, consulte a Visão geral do pipeline de CI/CD e MSIX para obter exemplos.

Adicione metadados de identidade aos manifestos do aplicativo da área de trabalho

Você conecta o pacote de identidade com os executáveis do aplicativo incluindo manifestos de aplicativo (também conhecidos como manifestos lado a lado ou de fusão) com metadados que correspondem aos metadados do manifesto do pacote de identidade.

No Visual Studio, você pode adicionar um manifesto de aplicativo a um projeto executável abrindo o menu de contexto do Projeto e selecionando Adicionar>Novo Arquivo de Manifesto do Aplicativo>.

Veja abaixo um trecho de exemplo do manifesto do aplicativo demonstrando o elemento msix necessário para conectar seus binários com metadados do pacote de identidade.

<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
  <assemblyIdentity version="0.0.0.0" name="ContosoPhotoStore"/>
  <msix xmlns="urn:schemas-microsoft-com:msix.v1"
          publisher="CN=Contoso"
          packageName="ContosoPhotoStore"
          applicationId="ContosoPhotoStore"
        />
</assembly>

Os atributos do elemento msix devem corresponder a estes valores do manifesto do pacote de identidade:

  • Os atributos packageName e publisher devem corresponder aos atributos Name e Publisher no elemento Identity no manifesto do pacote de identidade, respectivamente.
  • O atributo applicationId deve corresponder ao atributo Id do elemento Application correspondente no manifesto do pacote de identidade

Registrar o pacote de identidade no instalador

A última etapa para associar a identidade ao aplicativo é registrar o pacote de identidade no instalador e associá-lo ao diretório de instalação do aplicativo.

PowerShell

Executar powershell.exe com os parâmetros certos é a maneira mais simples de registrar o pacote. As diretrizes diferem para instalações por usuário versus instalações em todo o computador.

Por Usuário (PowerShell)

Para registrar o pacote de identidade durante uma instalação por usuário:

powershell.exe -NoLogo -NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -Command "Add-AppxPackage -Path <PackagePath> -ExternalLocation <ExternalLocation>"
  • Defina <PackagePath> como o caminho absoluto do pacote de identidade assinado produzido na etapa anterior (com o nome do arquivo).
  • Defina <ExternalLocation> como o caminho absoluto do diretório de instalação do aplicativo (sem nomes executáveis).

Para cancelar o registro do pacote de identidade durante uma desinstalação por usuário:

powershell.exe -NoLogo -NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -Command "Get-AppxPackage <PackageName> | Remove-AppxPackage"
  • Defina <PackageName> como o nome do pacote que você definiu no manifesto do pacote de identidade (o atributo Name do elemento Identity )

Por Máquina (PowerShell)

Para registrar o pacote de identidade durante uma instalação em todo o computador:

powershell.exe -NoLogo -NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -Command "Add-AppxPackage -Stage <PackagePath> -ExternalLocation <ExternalLocation>; Add-AppxProvisionedPackage -Online -PackagePath <PackagePath>"
  • Defina <PackagePath> como o caminho absoluto do pacote de identidade assinado produzido na etapa anterior (com o nome do arquivo).
  • Defina <ExternalLocation> como o caminho absoluto do diretório de instalação do aplicativo (sem nomes executáveis).

Para cancelar o registro do pacote de identidade durante uma desinstalação em todo o computador:

powershell.exe -NoLogo -NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -Command "$packages = Get-AppxPackage <PackageName>; foreach ($package in $packages) { Remove-AppxProvisionedPackage -PackageName $package.PackageFullName -Online }; foreach ($package in $packages) { Remove-AppxPackage -Package $package.PackageFullName -AllUsers }
  • Defina <PackageName> como o nome do pacote que você definiu no manifesto do pacote de identidade (o atributo Name do elemento Identity )

PackageManager APIs

Se você preferir chamar as APIs do sistema operacional para registrar e desregistrar o pacote de identidade, a API PackageManager fornecerá funcionalidade equivalente ao PowerShell. As diretrizes diferem para instalações por usuário versus instalações em todo o computador.

Abaixo estão snippets que demonstram a API. Para obter código pronto para produção em C# e C++, consulte Exemplo de aplicativos.

Per-User (Gerenciador de Pacotes)

A listagem de código abaixo demonstra o registro do pacote de identidade usando o método AddPackageByUriAsync e cancelando o registro do pacote de identidade usando o método RemovePackageAsync .

using Windows.Management.Deployment;

...

// Register the identity package during install

var externalUri = new Uri(externalLocation);
var packageUri = new Uri(packagePath);

var packageManager = new PackageManager();

var options = new AddPackageOptions();
options.ExternalLocationUri = externalUri;

await packageManager.AddPackageByUriAsync(packageUri, options);

...

// Unregister the identity package during uninstall

var packageManager = new PackageManager();
var packages = packageManager.FindPackagesForUserWithPackageTypes("", "<IdentityPackageFamilyName>", PackageType.Main);
foreach (var package in packages)
{
  await packageManager.RemovePackageAsync(package.Id.FamilyName);
}

Observe os detalhes importantes abaixo sobre este código:

  • Defina externalLocation como o caminho absoluto do diretório de instalação do aplicativo (sem nomes executáveis)
  • Defina packagePath como o caminho absoluto do pacote de identidade assinado produzido na etapa anterior (com o nome do arquivo)
  • <IdentityPackageFamilyName> pode ser encontrado executando o comando PowerShell Get-AppxPackage <IdentityPackageName> em um sistema onde o pacote de identidade está registrado. A PackageFamilyName propriedade contém o valor a ser usado aqui.

Per-Machine (Gerenciador de Pacotes)

A listagem de código abaixo demonstra o registro do pacote de identidade usando os métodos StagePackageByUriAsync e ProvisionPackageForAllUsersAsync e cancelando o registro do pacote de identidade usando os métodos DeprovisionPackageForAllUsersAsync e RemovePackageAsync .

// Register the identity package during install

var externalUri = new Uri(externalLocation);
var packageUri = new Uri(packagePath);

var packageManager = new PackageManager();

var options = new StagePackageOptions();
options.ExternalLocationUri = externalUri;

await packageManager.StagePackageByUriAsync(packageUri, options);
await packageManager.ProvisionPackageForAllUsersAsync(packageFamilyName);

...

// Unregister the identity package during uninstall

var packageManager = new PackageManager();

var packages = packageManager.FindPackagesForUserWithPackageTypes("", "<IdentityPackageFamilyName>", PackageType.Main);
foreach (var package in packages)
{
  await packageManager.DeprovisionPackageForAllUsersAsync(package.Id.FamilyName);
  await packageManager.RemovePackageAsync(package.Id.FamilyName, RemovalOptions.RemoveForAllUsers);
}

Observe os detalhes importantes abaixo sobre este código:

  • Defina externalLocation como o caminho absoluto do diretório de instalação do aplicativo (sem nomes executáveis)
  • Defina packagePath como o caminho absoluto do pacote de identidade assinado produzido na etapa anterior (com o nome do arquivo)
  • <IdentityPackageFamilyName> pode ser encontrado ao executar o comando PowerShell Get-AppxPackage <IdentityPackageName> em um sistema onde o pacote de identidade esteja registrado. A PackageFamilyName propriedade contém o valor a ser usado aqui.

Aplicativos de exemplo

Consulte os exemplos de PackageWithExternalLocation para aplicativos C# e C++ totalmente funcionais que demonstram como registrar e cancelar o registro de um pacote de identidade.

Etapas opcionais

Localização e ativos visuais

Alguns recursos que compreendem a identidade do pacote podem fazer com que cadeias de caracteres e imagens do manifesto do pacote de identidade sejam exibidas no sistema operacional Windows. Por exemplo:

  • Um aplicativo que usa APIs de câmera, microfone ou localização terá um alternador de controle dedicado nas Configurações de Privacidade do Windows, juntamente com um prompt de consentimento mediado que os usuários podem usar para conceder ou negar acesso a esses recursos sensíveis.
  • Um aplicativo que registra um destino de compartilhamento aparecerá na caixa de diálogo de compartilhamento.

Para localizar as cadeias de caracteres no manifesto do pacote de identidade, consulte Localize o manifesto.

Ao fornecer caminhos para imagens nos atributos VisualElements no manifesto de pacote de identidade, os caminhos fornecidos devem ser relativos dentro do diretório de instalação do aplicativo, apontando para uma imagem .png, .jpg ou .jpeg. Os nomes de atributo indicam as dimensões esperadas das imagens (150 x 150 e 40x40).