SDK do Aplicativo Windows guia de implantação para aplicativos dependentes de estrutura empacotados com localização externa ou não empacotado

Este tópico fornece diretrizes sobre como implantar aplicativos empacotados com localização externa ou não empacotados e que usam o SDK do Aplicativo Windows.

  • Esses aplicativos são aplicativos da área de trabalho (não aplicativos UWP).
  • Eles podem ser escritos em uma linguagem .NET, como C#, ou em C++.
  • Para sua interface do usuário, eles podem usar WinUI 3, WPF, WinForms ou outra estrutura de interface do usuário.

Visão geral

Os desenvolvedores de aplicativos empacotados com localização externa e não empacotados são responsáveis por implantar pacotes de runtime necessários do SDK do Aplicativo Windows para seus usuários finais. Isso pode ser feito executando o instalador ou instalando os pacotes MSIX diretamente. Essas opções são descritas com mais detalhes na seção Implantar o runtime do SDK do Aplicativo Windows abaixo.

Aplicativos empacotados com localização externa e não empacotados também têm requisitos de runtime extras. Você deve inicializar o acesso ao runtime do SDK do Aplicativo Windows usando a API Bootstrapper. Além disso, a API de Dependências Dinâmicas pode ser usada se seu aplicativo usar outros pacotes de estrutura além do SDK do Aplicativo Windows. Esses requisitos são descritos com mais detalhes na seção Requisitos de runtime para aplicativos empacotados com localização externa ou não empacotado abaixo.

Pré-requisitos

Pré-requisitos adicionais

  • As versões experimental e de Preview do SDK do Aplicativo Windows exigem que o sideload esteja habilitado para instalar o runtime.
    • O sideload é ativado automaticamente no Windows 10 versão 2004 e posterior.

    • Se o computador de desenvolvimento ou o computador de implantação estiver executando o Windows 11, confirme se o sideload está habilitado:

      • Configurações>Privacidade e segurança>para desenvolvedores. Verifique se a configuração do Modo do desenvolvedor está ativada.
    • Se o computador de desenvolvimento ou o computador de implantação estiver executando o Windows 10 versão 1909 ou uma versão anterior, confirme se o sideload está habilitado:

      • Configurações>Atualização e segurança>para desenvolvedores>Use os recursos do desenvolvedor. Confirme se a opção aplicativos Sideload ou Modo do desenvolvedor está selecionada.
    • A configuração do modo do Desenvolvedor inclui sideload, bem como outros recursos.

      Observação

      Se o computador for gerenciado em um ambiente corporativo, pode haver uma política impedindo que essas configurações sejam alteradas. Nesse caso, caso receba um erro quando você ou seu aplicativo tentar instalar o runtime do SDK do Aplicativo Windows, entre em contato com o profissional de TI para habilitar o sideload ou o Modo do desenvolvedor.

Implantar o runtime do SDK do Aplicativo Windows

Aplicativos empacotados com localização externa e não empacotados têm duas opções para implantar o runtime do SDK do Aplicativo Windows:

  • Opção 1: Usar o instalador: o instalador silencioso distribui todos os pacotes MSIX do SDK do Aplicativo Windows. Um instalador separado está disponível para cada uma das arquiteturas X64,X86 e Arm64.
  • Opção 2: Instalar os pacotes diretamente: Você pode fazer com que sua configuração existente ou a ferramenta MSI carregue e instale os pacotes MSIX para o SDK do Aplicativo Windows.

Opção 1: usar o instalador

Você pode implantar todos os pacotes de runtime do SDK do Aplicativo Windows executando o instalador. O instalador está disponível em Downloads para o SDK do Aplicativo Windows. Ao executar o instalador (.exe), você verá uma saída semelhante a esta:

Deploying package: Microsoft.WindowsAppRuntime.1.0_0.318.928.0_x64__8wekyb3d8bbwe
Package deployment result : 0x0

Deploying package: Microsoft.WindowsAppRuntime.1.0_0.318.928.0_x86__8wekyb3d8bbwe
Package deployment result : 0x0

Deploying package: MicrosoftCorporationII.WindowsAppRuntime.Main.1.0_0.318.928.0_x64__8wekyb3d8bbwe
Package deployment result : 0x0
Provisioning result : 0x0

Deploying package: Microsoft.WindowsAppRuntime.Singleton_0.318.928.0_x64__8wekyb3d8bbwe
Package deployment result : 0x0
Provisioning result : 0x0

Deploying package: Microsoft.WinAppRuntime.DDLM.0.318.928.0-x6_0.318.928.0_x64__8wekyb3d8bbwe
Package deployment result : 0x0
Provisioning result : 0x0

Deploying package: Microsoft.WinAppRuntime.DDLM.0.318.928.0-x8_0.318.928.0_x86__8wekyb3d8bbwe
Package deployment result : 0x0
Provisioning result : 0x0

All install operations successful.

Você pode executar o instalador sem interação do usuário e suprimir toda a saída de texto com a opção --quiet:

WindowsAppRuntimeInstall.exe --quiet

Você também pode optar por forçar a atualização dos pacotes MSIX e desligar todos os processos do SDK do Aplicativo Windows em execução no momento usando a opção --force. Esse recurso foi introduzido em 1.1.

WindowsAppRuntimeInstall.exe --force

Opções de linha de comando para instalar o WindowsAppRuntimeInstall --h

Após a conclusão da instalação, você pode executar o aplicativo empacotado com localização externa ou não empacotado. Para obter um exemplo de como criar e executar um aplicativo empacotado com localização externa ou não empacotado que usa o SDK do aplicativo Windows, consulte o Tutorial: usar a API de bootstrapper em um aplicativo empacotado com localização externa ou não empacotado que usa o SDK do Aplicativo Windows

Encadear o instalador do SDK do Aplicativo Windows à configuração do seu aplicativo

Se você tiver um programa de instalação personalizado para seu aplicativo, poderá encadear o processo de configuração do SDK do aplicativo Windows no processo de configuração do seu aplicativo. No momento, o instalador do SDK do Aplicativo Windows não fornece uma interface do usuário padrão, portanto, você precisará encadear usando a interface do usuário personalizada da instalação.

Você pode iniciar e acompanhar silenciosamente a configuração do SDK do Aplicativo Windows enquanto mostra sua própria exibição do progresso da configuração usando o ShellExecute. O instalador do SDK do Aplicativo Windows descompacta silenciosamente o pacote MSIX de Aplicativos do Windows e chama o método PackageManager.AddPackageAsync para concluir a instalação. Ele é muito semelhante a outros instaladores de runtime que você pode ter usado, como .NET, Visual C++ ou DirectX.

Para obter um exemplo de código que demonstra como executar o instalador do SDK do Aplicativo Windows a partir do programa de instalação, confira a função RunInstaller nos testes funcionais do instalador.

Exemplo de instalador

Consulte o exemplo abaixo para ver como iniciar o instalador a partir de um programa de instalação do Win32 sem abrir uma janela de console durante a configuração:

Solução de problemas

Códigos de retorno

A tabela a seguir lista os códigos de retorno mais comuns para o instalador exe do SDK do Aplicativo Windows. Os códigos de retorno são os mesmos para todas as versões do instalador.

Código de retorno Descrição
0x0 A instalação ou o provisionamento do pacote foi concluído com êxito.
0x80073d06 Falha na instalação de um ou mais pacotes.
0x80070005 A instalação ou o provisionamento em todo o sistema não foi possível, pois o aplicativo não está sendo executado com privilégios elevados ou o usuário que está fazendo a instalação não tem privilégios de administrador.

Erros de instalação

Se o instalador do SDK do aplicativo Windows retornar um erro durante a instalação, ele retornará um código de erro que descreve o problema.

Opção 2: Implantar pacotes de pacote de runtime do SDK do Aplicativo Windows diretamente

Como alternativa ao uso do instalador do SDK do Aplicativo Windows para implantação para usuários finais, você pode implantar manualmente os pacotes MSIX por meio do programa ou MSI do seu aplicativo. Essa opção pode ser melhor para os desenvolvedores que desejam mais controle.

Para obter um exemplo que demonstra como o programa de instalação pode instalar os pacotes MSIX, confira install.cpp no código do instalador do SDK do Aplicativo Windows.

Para verificar se o SDK do Aplicativo Windows já está instalado (e, em caso afirmativo, qual versão), você pode verificar se há famílias de pacotes específicas chamando PackageManager.FindPackagesForUserWithPackageTypes.

Em um processo não empacotado mediumIL (confiança total) (consulte o elemento Application), você pode usar o seguinte código para verificar se há um pacote registrado para o usuário atual:

using Windows.Management.Deployment;

public class WindowsAppSDKRuntime
{
    public static IsPackageRegisteredForCurrentUser(
        string packageFamilyName,
        PackageVersion minVersion,
        Windows.System.ProcessorArchitecture architecture,
        PackageTypes packageType)
    {
        ulong minPackageVersion = ToVersion(minVersion);

        foreach (var p : PackageManager.FindPackagesForUserWithPackageTypes(
            string.Empty, packageFamilyName, packageType)
        {
            // Is the package architecture compatible?
            if (p.Id.Architecture != architecture)
            {
                continue;
            }

            // Is the package version sufficient for our needs?
            ulong packageVersion = ToVersion(p.Id.Version);
            if (packageVersion < minPackageVersion)
            {
                continue;
            }

            // Success.
            return true;
        }

        // No qualifying package found.
        return false;
    }

    private static ulong ToVersion(PackageVersion packageVersion)
    {
        return ((ulong)packageVersion.Major << 48) |
               ((ulong)packageVersion.Minor << 32) |
               ((ulong)packageVersion.Build << 16) |
               ((ulong)packageVersion.Revision);
    }
}

Para o cenário acima, chamar FindPackagesForUserWithPackageTypes é preferível a chamar FindPackagesForUser. Isso porque você pode restringir a pesquisa a (para este exemplo), apenas framework ou pacotes principais. E isso evita a correspondência de outros tipos de pacotes (como resource, optional ou bundle) que não são de interesse para este exemplo.

Para usar o contexto de usuário current/calling, defina o parâmetro userSecurityId is como uma cadeia de caracteres vazia.

E agora algumas informações para ajudá-lo a decidir como chamar a função no exemplo de código acima. Um runtime instalado corretamente é composto por vários pacotes que dependem da arquitetura da CPU do sistema:

  • Em uma máquina x86: Fwk=[x86], Main=[x86], Singleton=[x86], DDLM=[x86].
  • Em um computador x64: Fwk=[x86, x64], Main=[x64], Singleton=[x64], DDLM=[x86, x64].
  • Em uma máquina arm64: Fwk=[x86, x64, arm64], Main=[arm64], Singleton=[arm64], DDLM=[x86, x64, arm64].

Para os pacotes Main e Singleton , sua arquitetura deve corresponder à arquitetura de CPU do sistema; por exemplo, pacotes x64 em um sistema x64. Para o pacote Framework , um sistema x64 pode executar aplicativos x64 e x86; da mesma forma, um sistema arm64 pode executar aplicativos arm64, x64 e x86. Uma verificação de pacote DDLM é semelhante a uma verificação de Framework, exceto que PackageType=main, e o packagefamilyname é diferente, e mais de um packagefamilyname (diferente) pode ser aplicável, devido ao esquema de nomenclatura exclusivo do DDLM. Para obter mais informações, consulte a especificação de pacotes MSIX. Portanto, as verificações são mais assim:

public static bool IsRuntimeRegisteredForCurrentUser(PackageVersion minVersion)
{
    ProcessorArchitecture systemArchitecture = DetectSystemArchitecture();

    return IsFrameworkRegistered(systemArchitecture, minVersion) &&
           IsMainRegistered(systemArchitecture, minVersion) &&
           IsSingletonRegistered(systemArchitecture, minVersion) &&
           IsDDLMRegistered(systemArchitecture, minVersion);
}

private static ProcecssorArchitecture DetectSystemArchitecture()
{
    // ...see the call to IsWow64Process2(), and how the result is used...
    // ...as per `IsPackageApplicable()` in
    // [install.cpp](https://github.com/microsoft/WindowsAppSDK/blob/main/installer/dev/install.cpp)
    // line 99-116...
    // ...WARNING: Use IsWow64Process2 to detect the system architecture....
    // ...         Other similar APIs exist, but don't give reliably accurate results...
}

private static bool IsFrameworkRegistered(ProcessorArchitecture systemArchitecture,
    PackageVersion minVersion)
{
    // Check x86.
    if (!IsPackageRegisteredForCurrentUser(
        global::Microsoft.WindowsAppSDK.Runtime.Packages.Framework.PackageFamilyName,
        minVersion, ProcessorArchitecture.X86,
        PackageTypes.Framework))
    {
        return false;
    }

    // Check x64 (if necessary).
    if ((systemArchitecture == ProcessorArchitecture.X64) || 
        (systemArchitecture == ProcessorArchitcture.Arm64))
    {
        if (!IsPackageRegisteredForCurrentUser(
            global::Microsoft.WindowsAppSDK.Runtime.Packages.Framework.PackageFamilyName,
            minVersion, ProcessorArchitecture.X64,
            PackageTypes.Framework))
        {
            return false;
        }
    }

    // Check arm64 (if necessary).
    if (systemArchitecture == ProcessorArchitcture.Arm64)
    {
        if (!IsPackageRegisteredForCurrentUser(
            global::Microsoft.WindowsAppSDK.Runtime.Packages.Framework.PackageFamilyName,
            minVersion, ProcessorArchitecture.Arm64,
            PackageTypes.Framework))
        {
            return false;
        }
    }

    return true;
}

private static bool IsMainRegistered(ProcessorArchitecture systemArchitecture,
    PackageVersion minVersion)
{
    return IsPackageRegisteredForCurrentUser(
        global::Microsoft.WindowsAppSDK.Runtime.Packages.Main.PackageFamilyName,
        minVersion,
        systemArchitecture,
        PackageTypes.Main);
}

private static bool IsSingletonRegistered(ProcessorArchitecture systemArchitecture,
    PackageVersion minVersion)
{
    return IsPackageRegisteredForCurrentUser(
        global::Microsoft.WindowsAppSDK.Runtime.Packages.Singleton.PackageFamilyName,
        minVersion,
        systemArchitecture,
        PackageTypes.Main);
}

private static bool IsDDLMRegistered(ProcessorArchitecture systemArchitecture,
    PackageVersion minVersion)
{
    // ...similar to IsFrameworkRegistered, but the packageFamilyName is more complicated...
    // ...and no predefined constant is currently available...
    // ...for more details, see
    // https://github.com/microsoft/WindowsAppSDK/blob/main/specs/Deployment/MSIXPackages.md.
}

As informações e o código acima abrangem o cenário básico de detecção. Para detectar se o runtime é provisionado para todos os usuários ou para fazer o acima de um Contêiner de Aplicativo e/ou fazê-lo de um processo empacotado mediumIL , é necessária lógica adicional.

Cenários de implantação

  • Instalando o Runtime do SDK do Aplicativo Windows em todo o sistema: a instalação em todo o sistema altera o computador para todos os usuários, incluindo novos usuários que são adicionados no futuro. Se o aplicativo estiver sendo executado com privilégios elevados e o usuário que está fazendo a instalação tiver privilégios de administrador, o instalador registrará os pacotes MSIX em todo o sistema chamando o ProvisionPackageForAllUsersAsync. Se o registro em todo o sistema não for bem-sucedido, a instalação será executada apenas para o usuário atual que está fazendo a instalação. Em um ambiente corporativo gerenciado, o administrador de TI deve ser capaz de provisionar para todos como de costume.

  • Arquiteturas redistribuídas pelo instalador SDK do Aplicativo Windows: o instalador SDK do Aplicativo Windows está disponível nas x86arquiteturas , x64e .Arm64 Cada versão do instalador inclui os pacotes MSIX apenas para a arquitetura específica para a qual ele é nomeado. Por exemplo, se você executar o x86 WindowsAppRuntimeInstall.exe em um dispositivo x64 ou Arm64, esse x86 instalador implantará nesse dispositivo apenas os pacotes para a arquitetura x86.

  • Todos os pacotes MSIX do SDK do Aplicativo Windows já estão instalados no computador: os pacotes MSIX são instalados em uma localização em todo o sistema com apenas uma cópia no disco. Se um aplicativo tentar instalar o SDK do Aplicativo Windows quando todas as dependências do pacote MSIX já estiverem instaladas no computador, a instalação não será executada.

  • Um ou mais dos pacotes MSIX do SDK do Aplicativo Windows não estão instalados no computador: ao implantar o SDK do Aplicativo Windows, sempre tente instalar todos os pacotes MSIX (estrutura, main, singleton, DDLM) para garantir que todas as dependências sejam instaladas e você evite interrupções na experiência do usuário final.

Requisitos de runtime para aplicativos empacotados com localização externa ou não empacotados

Os aplicativos empacotados com localização externa ou não empacotados têm requisitos de runtime extras para usar o runtime do SDK do Aplicativo Windows. Isso envolve referenciar e inicializar o pacote de estrutura do SDK do Aplicativo Windows em runtime. Além disso, a API de Dependências Dinâmicas pode ser usada para fazer referência a outros pacotes de estrutura fora do SDK do Aplicativo Windows.

Usar o runtime do SDK do Aplicativo Windows

Aplicativos empacotados com localização externa e não empacotados devem chamar a API Bootstrapper para usar o SDK do aplicativo Windows em tempo de execução. Isso é necessário antes que o aplicativo possa usar recursos do SDK do Aplicativo Windows, como WinUI, Ciclo de Vida do Aplicativo, MRT Core e DWriteCore. Um componente bootstrapper permite que aplicativos empacotados com localização externa e aplicativos não empacotados executem estas tarefas importantes:

  • Procurar e carregar o pacote de estrutura do SDK do Aplicativo Windows no gráfico de pacotes do aplicativo.
  • Inicializar o gerenciador de vida útil de dependência dinâmica (DDLM) para o pacote de estrutura do SDK do Aplicativo Windows. O objetivo do DDLM é impedir a manutenção do pacote de estrutura do SDK do Aplicativo Windows enquanto ele estiver em uso por um aplicativo empacotado com localização externa ou não empacotado.

A maneira mais simples de carregar do runtime do SDK do Aplicativo Windows para aplicativos empacotados com localização externa e não empacotados é definindo a propriedade <WindowsPackageType>None</WindowsPackageType> em seu arquivo de projeto (.csproj ou .vcxproj). Você também pode chamar a API bootstrapper diretamente no código de inicialização do seu aplicativo para obter mais controle sobre a inicialização. Para obter mais detalhes, consulte Usar o tempo de execução do SDK do aplicativo Windows para aplicativos empacotados com localização externa ou não empacotados e o Tutorial: usar a API bootstrapper em um aplicativo empacotado com localização externa ou não empacotado que usa o SDK do aplicativo Windows.

O suporte a dependências dinâmicas permite que aplicativos empacotados com localização externa e não empacotados mantenham seus mecanismos de implantação existentes, como MSI ou qualquer instalador, e possam aproveitar o SDK do aplicativo Windows em seus aplicativos. As dependências dinâmicas podem ser usadas por aplicativos empacotados, empacotados com localização externa e não empacotados; embora se destinem principalmente ao uso por aplicativos empacotados com localização externa e não empacotados.

Há um DDLM para cada versão e arquitetura do pacote de estrutura do SDK do Aplicativo Windows. Isso significa que, em um computador x64, você pode ter uma versão x86 e x64 do DDLM para oferecer suporte a aplicativos de ambas as arquiteturas.

Faça referência a outros pacotes de estrutura usando a API de dependências dinâmicas

Se você quiser usar recursos em outros pacotes de estrutura fora do SDK do Aplicativo Windows (por exemplo, DirectX), empacotados com localização externa e aplicativos não empacotados podem chamar a API de Dependências Dinâmicas. Além do componente bootstrapper, o SDK do Aplicativo Windows também fornece um conjunto mais amplo de funções C/C++ e classes WinRT que implementam a API de dependência dinâmica. Essa API foi projetada para ser usada para fazer referência a qualquer pacote de estrutura dinamicamente em tempo de execução.

Para obter mais informações, confira Usar os pacotes de estrutura MSIX dinamicamente por meio do seu aplicativo para desktop e do exemplo de dependências dinâmicas.

Implantar arquivos .winmd no computador de destino

Junto com seu aplicativo, recomendamos que você vá em frente e implante arquivos de Metadados (.winmd) do Windows. Os metadados podem ser usados por várias APIs e comportamentos em runtime, e sua ausência pode limitar ou interromper a funcionalidade. Por exemplo, os metadados podem ser usados para realizar marshal em objetos através dos limites dos apartamentos; e a necessidade de marechal pode ser uma função do desempenho do computador. Como não há uma maneira determinística de saber se há necessidade de metadados, você deve implantar .winmds, a menos que esteja extremamente preocupado com o tamanho.