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.xml
arquivo, 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
- Visão geral da implantação do SDK do Aplicativo do Windows
- Criar seu primeiro projeto da WinUI 3
- Migrar da UWP para o SDK do Aplicativo Windows
- Vantagens e desvantagens de empacotar um aplicativo - Visão geral da implantação
- Identidade, registro e ativação de aplicativos Win32 não empacotados
- Implementação do Contrato de compartilhamento para o aplicativo WinAppSDK
- Implementação do Contrato de compartilhamento para aplicativos empacotados com localização externa
Windows developer