Partilhar via


Integrar aplicativos não empacotados com o Windows Share

Este artigo explica como integrar aplicativos não empacotados com o recurso Windows Share. O recurso Compartilhar permite que os usuários compartilhem conteúdo de um aplicativo do Windows para outro. Um aplicativo não empacotado deve ser fornecido com a identidade do pacote para que possa ser registrado como um Destino de compartilhamento. Uma vez registrado, o aplicativo pode receber e processar arquivos compartilhados.

Como integrar um aplicativo não empacotado como um Destino de compartilhamento:

  • Fornecer ao aplicativo a identidade do pacote
  • Implementar o contrato do Share

Fornecer aplicativos não empacotados com identidade de pacote

Um aplicativo pode obter a identidade do pacote de duas maneiras:

  • Criar um novo pacote de instalação MSIX (método preferido) OU
  • Torne os aplicativos empacotados com localização externa compatíveis com o instalador atual. Isso só é recomendado para aplicativos que têm um instalador existente e que não podem alternar para a instalação MSIX.

Criar um novo pacote de instalação do MSIX

É recomendável empacotar o aplicativo com MSIX usando o modelo Projeto Aplicativo do Windows de Empacotamento no Visual Studio. Isso inclui todos os binários no pacote MSIX e fornecerá uma experiência de instalação limpa e confiável.

O que observar antes de empacotar aplicativos da área de trabalho: Prepare-se para empacotar um aplicativo da área de trabalho (MSIX)

Siga as etapas em Configurar seu aplicativo de área de trabalho para empacotamento MSIX no Visual Studio para gerar um pacote para o projeto do aplicativo existente.

Observação

Ao criar o projeto de empacotamento, selecione Windows 10, versão 2004 (10.0; Build 19041) ou posterior como a Versão mínima.

Quando isso for concluído, você criará o pacote seguindo Empacotar um aplicativo de área de trabalho ou UWP no Visual Studio.

Tornar empacotamento com localização externa compatível com o instalador atual.

A segunda maneira de dar a identidade do pacote do aplicativo é adicionar um pacote com localização externa ao aplicativo e registrá-lo no instalador existente. O pacote com localização externa é um pacote MSIX vazio que contém o .appxmanifest com identidade, registro de destino de compartilhamento e ativos visuais. Os binários do aplicativo ainda são gerenciados pelo instalador existente do aplicativo. Ao registrar o pacote, você precisa fornecer o local de instalação do aplicativo na API. É importante manter a identidade no manifesto do pacote MSIX e no manifesto do aplicativo Win32 em sincronia com o certificado que foi usado para assinar o aplicativo.

Etapas para conceder identidade de pacote a um aplicativo não empacotado

A documentação sobre como criar um pacote com localização externa está disponível aqui, incluindo informações sobre modelos a serem usados: Conceder identidade de pacote empacotando com localização externa.

O aplicativo de exemplo completo está disponível no GitHub: SparsePackages (Empacotado com Localização Externa).

Registrar-se como um Destino de compartilhamento

Depois que o aplicativo tiver a identidade do pacote, a próxima etapa é implementar o Contrato de compartilhamento. O Contrato de compartilhamento permite que seu aplicativo receba dados de outro aplicativo.

Você pode seguir as mesmas etapas na seção Registrar como um Destino de Compartilhamento da documentação para aplicativos empacotados para integrar à Share Sheet.

Passo a passo do aplicativo PhotoStore de exemplo

Neste passo a passo sobre identidade de pacote, registro e ativação de compartilhamento para aplicativos Win32 não empacotados, você aprenderá como conceder identidade de pacote a um aplicativo Win32 não empacotado criando um pacote com local externo. Depois que o aplicativo tiver a identidade de pacote, ele poderá registrar e manipular a ativação como um Destino de compartilhamento. Você executará as seguintes etapas usando o exemplo PhotoStoreDemo:

  • Gere o arquivo AppxManifest.xml.
  • Criar um pacote
  • Assinar o pacote
  • Registro do pacote
  • Tratar a ativação do aplicativo

Comece criando o AppxManifest.xmlarquivo, que inclui propriedades necessárias como <AllowExternalContent>, identidade e recursos e extensão de destino de compartilhamento. Verifique se os valores Publisher, PackageName & ApplicationId do AppxManifest.xml arquivo correspondem aos valores do arquivo PhotoStoreDemo.exe.manifest. O valor Publisher também deve corresponder ao valor do certificado usado para assinar o pacote. Adicione ativos visuais conforme necessário e referenciado em AppxManifest.xml. No Visual Studio, você pode usar o nó Ativos Visuais ao editar package.manifest no projeto Empacotamento de aplicativo para gerar os ativos visuais necessários.

Este é um trecho de exemplo AppxManifest.xml com conteúdo externo permitido:

<Identity Name="PhotoStoreDemo" ProcessorArchitecture="neutral" Publisher="CN=YourPubNameHere" Version="1.0.0.0" />
  <Properties>
    <DisplayName>PhotoStoreDemo</DisplayName>
    <PublisherDisplayName>Sparse Package</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.19041.0" />
  </Dependencies>
  <Capabilities>
    <rescap:Capability Name="runFullTrust" />
    <rescap:Capability Name="unvirtualizedResources"/>
  </Capabilities>
  <Applications>
    <Application Id="PhotoStoreDemo" Executable="PhotoStoreDemo.exe" uap10:TrustLevel="mediumIL" uap10:RuntimeBehavior="win32App">
      <uap:VisualElements AppListEntry="none" DisplayName="PhotoStoreDemo" Description="PhotoStoreDemo" BackgroundColor="transparent" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png">
        <uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" Square310x310Logo="Assets\LargeTile.png" Square71x71Logo="Assets\SmallTile.png"></uap:DefaultTile>
        <uap:SplashScreen Image="Assets\SplashScreen.png" />
      </uap:VisualElements>
      <Extensions>
        <uap:Extension Category="windows.shareTarget">
          <uap:ShareTarget Description="Send to PhotoStoreDemo">
            <uap:SupportedFileTypes>
              <uap:FileType>.jpg</uap:FileType>
              <uap:FileType>.png</uap:FileType>
              <uap:FileType>.gif</uap:FileType>
            </uap:SupportedFileTypes>
            <uap:DataFormat>StorageItems</uap:DataFormat>
            <uap:DataFormat>Bitmap</uap:DataFormat>
          </uap:ShareTarget>
        </uap:Extension>
        ...

Este é um arquivo Application.exe.manifest de exemplo:

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

Em seguida, para criar o pacote com localização externa, use a ferramenta MakeAppx.exe com o /nv comando para criar um pacote contendo o arquivo AppxManifest.xml.

Exemplo:

MakeAppx.exe pack /d <Path to directory with AppxManifest.xml> /p <Output Path>\mypackage.msix /nv

Observação

Um pacote com localização externa contém um manifesto do pacote, mas nenhum outro conteúdo nem binários de aplicativo. O manifesto de um pacote com localização externa pode referenciar arquivos fora do pacote em uma localização externa predeterminada.

Assine seu pacote com um certificado confiável usando SignTool.exe.​

Exemplo:

SignTool.exe sign /fd SHA256 /a /f <path to cert>  /p <cert key> <Path to Package>​

O certificado usado para assinar o pacote deve ser instalado em um local confiável na máquina.

Na primeira execução do aplicativo, registre o pacote com o Windows. Quando um aplicativo tem seu próprio instalador, ele também deve conter o MSIX assinado como a carga útil e deve colocá-lo em um local especificado (por exemplo, o local de instalação do aplicativo). Esse local deve ser conhecido pelo aplicativo de runtime porque o aplicativo precisará do caminho absoluto do MSIX para registrá-lo. Coloque os ativos e resources.pri no local de instalação do aplicativo também.

O código a seguir é um exemplo de execução não empacotada do método Main do aplicativo:

[STAThread]
public static void Main(string[] cmdArgs)
{
    //if app isn't running with identity, register its package with external identity
    if (!ExecutionMode.IsRunningWithIdentity())
    {
        //TODO - update the value of externalLocation to match the output location of your VS Build binaries and the value of 
        //externalPkgPath to match the path to your signed package with external identity (.msix). 
        //Note that these values cannot be relative paths and must be complete paths
        string externalLocation = Environment.CurrentDirectory;
        string externalPkgPath = externalLocation + @"\PhotoStoreDemo.package.msix";

        //Attempt registration
        bool bPackageRegistered = false;
        //bPackageRegistered = registerPackageWithExternalLocation(externalLocation, externalPkgPath);
        if (bPackageRegistered)
        {
            //Registration succeeded, restart the app to run with identity
            System.Diagnostics.Process.Start(Application.ResourceAssembly.Location, arguments: cmdArgs?.ToString());
        }
        else //Registration failed, run without identity
        {
            Debug.WriteLine("Package Registration failed, running WITHOUT Identity");
            SingleInstanceManager wrapper = new SingleInstanceManager();
            wrapper.Run(cmdArgs);
        }
    }
    ...

Este exemplo mostra como registrar o MSIX na primeira execução do aplicativo:

[STAThread]
public static void Main(string[] cmdArgs)
{
    //If app isn't running with identity, register its package with external identity
    if (!ExecutionMode.IsRunningWithIdentity())
    {
        //TODO - update the value of externalLocation to match the output location of your VS Build binaries and the value of 
        //externalPkgPath to match the path to your signed package with external identity (.msix). 
        //Note that these values cannot be relative paths and must be complete paths
        string externalLocation = Environment.CurrentDirectory;
        string externalPkgPath = externalLocation + @"\PhotoStoreDemo.package.msix";

        //Attempt registration
        if (registerPackageWithExternalLocation(externalLocation, externalPkgPath))
        {
            //Registration succeeded, restart the app to run with identity
            System.Diagnostics.Process.Start(Application.ResourceAssembly.Location, arguments: cmdArgs?.ToString());
        }
        else //Registration failed, run without identity
        {
            Debug.WriteLine("Package Registration failed, running WITHOUT Identity");
            SingleInstanceManager wrapper = new SingleInstanceManager();
            wrapper.Run(cmdArgs);
        }
    }
    ...

Por fim, gerencie a ativação do aplicativo:

[STAThread]
public static void Main(string[] cmdArgs)
{
    //if app isn't running with identity, register its sparse package
    if (!ExecutionMode.IsRunningWithIdentity())
    {
        ...
    }
    else //App is registered and running with identity, handle launch and activation
    {
        //Handle Sparse Package based activation e.g Share target activation or clicking on a Tile
        // Launching the .exe directly will have activationArgs == null
        var activationArgs = AppInstance.GetActivatedEventArgs();
        if (activationArgs != null)
        {
            switch (activationArgs.Kind)
            {
                case ActivationKind.Launch:
                    HandleLaunch(activationArgs as LaunchActivatedEventArgs);
                    break;
                case ActivationKind.ToastNotification:
                    HandleToastNotification(activationArgs as ToastNotificationActivatedEventArgs);
                    break;
                case ActivationKind.ShareTarget: // Handle the activation as a share target
                    HandleShareAsync(activationArgs as ShareTargetActivatedEventArgs);
                    break;
                default:
                    HandleLaunch(null);
                    break;
            }

        }
        //This is a direct exe based launch e.g. double click app .exe or desktop shortcut pointing to .exe
        else
        {
            SingleInstanceManager singleInstanceManager = new SingleInstanceManager();
            singleInstanceManager.Run(cmdArgs);
        }
    }

Demonstração do Windows Share com identidade de pacote

O vídeo a seguir demonstra como um aplicativo não empacotado pode ser um destino de compartilhamento depois de receber a identidade do pacote e se registrar como um destino de compartilhamento:

Confira também