Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
O Package Support Framework é um kit de código aberto que ajuda você a aplicar correções ao seu aplicativo de desktop existente (sem modificar o código) para que ele possa ser executado em um contêiner MSIX. O Package Support Framework ajuda seu aplicativo a seguir as práticas recomendadas do ambiente de tempo de execução moderno.
Este artigo fornece uma visão detalhada de cada componente do Package Support Framework e um guia passo a passo para usá-lo.
Entender o que está dentro de uma estrutura de suporte a pacotes
O Package Support Framework contém um executável, uma DLL do gerenciador de tempo de execução e um conjunto de correções de tempo de execução.
Aqui está o processo:
- Crie um arquivo de configuração que especifique as correções que você deseja aplicar ao seu aplicativo.
- Modifique seu pacote para apontar para o arquivo executável do iniciador PSF (Package Support Framework).
Quando os usuários iniciam seu aplicativo, o iniciador do Package Support Framework é o primeiro executável executado. Ele lê o arquivo de configuração e injeta as correções de tempo de execução e a DLL do gerenciador de tempo de execução no processo do aplicativo. O gerenciador de tempo de execução aplica a correção quando é necessário que o aplicativo seja executado dentro de um contêiner MSIX.
Etapa 1: Identificar problemas de compatibilidade de aplicativos empacotados
Primeiro, crie um pacote para seu aplicativo. Em seguida, instale-o, execute-o e observe seu comportamento. Você pode receber mensagens de erro que podem ajudá-lo a identificar um problema de compatibilidade. Você também pode usar o Process Monitor para identificar problemas. Problemas comuns estão relacionados a suposições do aplicativo em relação ao diretório de trabalho e permissões de caminho do programa.
Usando o Process Monitor para identificar um problema
O Process Monitor é um utilitário poderoso para observar as operações de arquivo e registro de um aplicativo e seus resultados. Isso pode ajudá-lo a entender os problemas de compatibilidade de aplicativos. Depois de abrir o Process Monitor, adicione um filtro (Filter > Filter...) para incluir apenas eventos do executável do aplicativo.
Será apresentada uma lista de eventos. Para muitos desses eventos, a palavra SUCESSO aparecerá na coluna Resultado .
Opcionalmente, você pode filtrar eventos para mostrar apenas falhas.
Se você suspeitar de uma falha de acesso ao sistema de arquivos, procure eventos com falha que estejam sob o caminho do arquivo System32/SysWOW64 ou do pacote. Os filtros também podem ajudar aqui. Comece na parte inferior desta lista e role para cima. As falhas que aparecem no final desta lista ocorreram mais recentemente. Preste mais atenção aos erros que contêm cadeias de caracteres como "acesso negado" e "caminho/nome não encontrado" e ignore coisas que não parecem suspeitas. O PSFSample tem duas questões. Você pode ver esses problemas na lista que aparece na imagem a seguir.
No primeiro problema que aparece nesta imagem, o aplicativo está falhando ao ler do arquivo "Config.txt" que está localizado no caminho "C:\Windows\SysWOW64". É improvável que o aplicativo esteja tentando fazer referência a esse caminho diretamente. Muito provavelmente, ele está tentando ler a partir desse arquivo usando um caminho relativo e, por padrão, "System32/SysWOW64" é o diretório de trabalho do aplicativo. Isso sugere que o aplicativo está esperando que seu diretório de trabalho atual seja definido para algum lugar no pacote. Olhando para dentro do appx, podemos ver que o arquivo existe no mesmo diretório que o executável.
O segundo problema aparece na imagem a seguir.
Nesse problema, a aplicação está falhando ao gravar um arquivo .log no seu caminho de pacote. Isso sugere que uma correção de redirecionamento de arquivo pode ajudar.
Etapa 2: Encontrar uma correção de tempo de execução
O PSF contém correções de tempo de execução que você pode usar agora, como a correção de redirecionamento de arquivo.
Correção de redirecionamento de arquivo
Você pode usar o File Redirection Fixup para redirecionar tentativas de gravar ou ler dados em um diretório que não está acessível a partir de um aplicativo executado em um contêiner MSIX.
Por exemplo, se seu aplicativo gravar em um arquivo de log que esteja no mesmo diretório que o executável de aplicativos, você poderá usar a Correção de Redirecionamento de Arquivo para criar esse arquivo de log em outro local, como o repositório de dados do aplicativo local.
Correções de tempo de execução (runtime) da comunidade
Certifique-se de revisar as contribuições da comunidade para nossa página do GitHub . É possível que outros desenvolvedores tenham resolvido um problema semelhante ao seu e compartilhado uma correção de tempo de execução.
Etapa 3: Aplicar uma correção de tempo de execução
Você pode aplicar uma correção de tempo de execução existente com algumas ferramentas simples do SDK do Windows e seguindo estas etapas.
- Criar uma pasta de estrutura de pacote
- Obter os ficheiros do Package Support Framework
- Adicione-os ao seu pacote
- Modificar o manifesto do pacote
- Criar um arquivo de configuração
Vamos passar por cada tarefa.
Criar a pasta de layout do pacote
Se você já tiver um arquivo .msix (ou .appx), poderá descompactar seu conteúdo em uma pasta de layout que servirá como área de preparo para seu pacote. Você pode fazer isso a partir de um prompt de comando usando a ferramenta MakeAppx, com base no seu caminho de instalação do SDK, é aqui que você encontrará a ferramenta makeappx.exe no seu PC com Windows 10: x86: C:\Program Files (x86)\Windows Kits\10\bin\x86\makeappx.exe x64: C:\Program Files (x86)\Windows Kits\10\bin\x64\makeappx.exe
makeappx unpack /p PSFSamplePackage_1.0.60.0_AnyCPU_Debug.msix /d PackageContents
Isto vai dar-te algo que se parece com o seguinte.
Se você não tiver um arquivo .msix (ou .appx) para começar, poderá criar a pasta do pacote e os arquivos do zero.
Obter os ficheiros do Package Support Framework
Você pode obter o pacote Nuget PSF usando a ferramenta de linha de comando Nuget autônoma ou por meio do Visual Studio.
Obter o pacote usando a ferramenta de linha de comando
Instale a ferramenta de linha de comando Nuget a partir deste local: https://www.nuget.org/downloads. Em seguida, na linha de comando do Nuget, execute este comando:
nuget install Microsoft.PackageSupportFramework
Como alternativa, você pode renomear a extensão do pacote para .zip e descompactá-la. Todos os arquivos que você precisa estarão na pasta /bin.
Obter o pacote usando o Visual Studio
No Visual Studio, clique com o botão direito do mouse no nó da solução ou do projeto e escolha um dos comandos Gerenciar Pacotes Nuget. Pesquise por Microsoft.PackageSupportFramework ou PSF para encontrar o pacote no Nuget.org. Em seguida, instale-o.
Adicione os arquivos do Package Support Framework ao seu pacote
Adicione as DLLs PSF de 32 bits e 64 bits necessárias e os arquivos executáveis ao diretório do pacote. Use a tabela a seguir como guia. Você também desejará incluir todas as correções de tempo de execução necessárias. Em nosso exemplo, precisamos da correção do tempo de execução do redirecionamento de arquivo.
| O executável do aplicativo é x64 | O executável do aplicativo é x86 |
|---|---|
| PSFLauncher64.exe | PSFLauncher32.exe |
| PSFRuntime64.dll | PSFRuntime32.dll |
| PSFRunDll64.exe | PSFRunDll32.exe |
O conteúdo do seu pacote agora deve ter esta aparência.
Modificar o manifesto do pacote
Abra o manifesto do pacote num editor de texto e defina o atributo do elemento ExecutableApplication para o nome do ficheiro executável do PSF Launcher. Se você conhece a arquitetura do seu aplicativo de destino, selecione a versão apropriada, PSFLauncher32.exe ou PSFLauncher64.exe. Caso contrário, PSFLauncher32.exe funcionará em todos os casos. Eis um exemplo.
<Package ...>
...
<Applications>
<Application Id="PSFSample"
Executable="PSFLauncher32.exe"
EntryPoint="Windows.FullTrustApplication">
...
</Application>
</Applications>
</Package>
Criar um arquivo de configuração
Crie um nome config.jsonde arquivo e salve-o na pasta raiz do seu pacote. Modifique a ID do aplicativo declarada do arquivo config.json para apontar para o executável que você acabou de substituir. Usando o conhecimento que você adquiriu usando o Process Monitor, você também pode definir o diretório de trabalho, bem como usar a correção de redirecionamento de arquivo para redirecionar leituras/gravações para arquivos .log no diretório "PSFSampleApp" relativo ao pacote.
{
"applications": [
{
"id": "PSFSample",
"executable": "PSFSampleApp/PSFSample.exe",
"workingDirectory": "PSFSampleApp/"
}
],
"processes": [
{
"executable": "PSFSample",
"fixups": [
{
"dll": "FileRedirectionFixup.dll",
"config": {
"redirectedPaths": {
"packageRelative": [
{
"base": "PSFSampleApp/",
"patterns": [
".*\\.log"
]
}
]
}
}
}
]
}
]
}
Segue-se um guia para o esquema config.json:
| Matriz | chave | Valor |
|---|---|---|
| Aplicações | ID | Use o valor do atributo Id do elemento Application no manifesto do pacote. |
| Aplicações | executável | O caminho relativo ao pacote para o executável que você deseja iniciar. Na maioria dos casos, você pode obter esse valor do arquivo de manifesto do pacote antes de modificá-lo. É o valor do Executable atributo do Application elemento. |
| Aplicações | diretório de trabalho | (Opcional) Um caminho relativo ao pacote para usar como o diretório de trabalho do aplicativo que é iniciado. Se você não definir esse valor, o sistema operacional usará o System32 diretório como o diretório de trabalho do aplicativo. |
| processos | executável | Na maioria dos casos, este será o nome do executable configurado acima, com o caminho e a extensão de arquivo removidos. |
| correções | dll | Caminho relativo ao pacote para carregar a correção, .msix/.appx. |
| correções | Configurações | (Opcional) Controla como a dll de correção se comporta. O formato exato desse valor varia de correção por correção, pois cada correção pode interpretar esse "blob" como quiser. |
O applications, processese fixups as chaves são matrizes. Isso significa que você pode usar o arquivo config.json para especificar mais de um aplicativo, processo e corrigir DLL.
Empacotar e testar o aplicativo
Em seguida, crie um pacote.
makeappx pack /d PackageContents /p PSFSamplePackageFixup.msix
Em seguida, assine-o.
signtool sign /a /v /fd sha256 /f ExportedSigningCertificate.pfx PSFSamplePackageFixup.msix
Para obter mais informações, consulte como criar um certificado de assinatura de pacote e como assinar um pacote usando signtool
Usando o PowerShell, instale o pacote.
Observação
Lembre-se de desinstalar o pacote primeiro.
powershell Add-AppPackage .\PSFSamplePackageFixup.msix
Execute o aplicativo e observe o comportamento com a correção de tempo de execução aplicada. Repita as etapas de diagnóstico e embalagem conforme necessário.
Verifique se o Package Support Framework está em execução
Você pode verificar se sua correção de tempo de execução está em execução. Uma maneira de fazer isso é abrir o Gerenciador de Tarefas e clicar em Mais detalhes. Encontre o aplicativo ao qual a estrutura de suporte do pacote foi aplicada e expanda os detalhes do aplicativo para obter mais detalhes. Você deve ser capaz de ver que o Package Support Framework está em execução.
Usar a correção de traço
Uma técnica alternativa para diagnosticar problemas de compatibilidade de aplicativos empacotados é usar o Trace Fixup. Essa DLL está incluída no PSF e fornece uma exibição de diagnóstico detalhada do comportamento do aplicativo, semelhante ao Process Monitor. Ele é especialmente projetado para revelar problemas de compatibilidade de aplicativos. Para usar o Trace Fixup, adicione a DLL ao pacote, adicione o seguinte fragmento ao seu config.jsone, em seguida, empacote e instale seu aplicativo.
{
"dll": "TraceFixup.dll",
"config": {
"traceLevels": {
"filesystem": "allFailures"
}
}
}
Por padrão, a Correção de Rastreamento filtra falhas que podem ser consideradas "esperadas". Por exemplo, os aplicativos podem tentar excluir incondicionalmente um arquivo sem verificar se ele já existe, ignorando o resultado. Isso tem a consequência infeliz de que algumas falhas inesperadas podem ser filtradas, portanto, no exemplo acima, optamos por receber todas as falhas das funções do sistema de arquivos. Fazemos isso porque sabemos de antes que a tentativa de ler o arquivo Config.txt falha com a mensagem "arquivo não encontrado". Esta é uma falha que é frequentemente observada e geralmente não assumida como inesperada. Na prática, é provavelmente melhor começar filtrando apenas para falhas inesperadas e, em seguida, voltar para todas as falhas se houver um problema que ainda não pode ser identificado.
Por padrão, a saída do Trace Fixup é enviada para o depurador anexado. Para este exemplo, não vamos anexar um depurador e, em vez disso, usaremos o programa DebugView de SysInternals para exibir sua saída. Depois de executar o aplicativo, podemos ver as mesmas falhas de antes, o que nos apontaria para as mesmas correções de tempo de execução.
Depurar, estender ou criar uma solução em tempo de execução
Você pode usar o Visual Studio para depurar uma correção de tempo de execução, estender uma correção de tempo de execução ou criar uma do zero. Você precisará fazer essas coisas para ser bem-sucedido.
- Adicionar um projeto de empacotamento
- Adicionar projeto para a correção de tempo de execução
- Adicionar um projeto que inicie o executável do Lançador PSF
- Configurar o projeto de empacotamento
Quando terminar, a sua solução será algo assim.
Vamos examinar cada projeto neste exemplo.
| Projeto | Propósito |
|---|---|
| Pacote de Aplicação de Desktop | Este projeto é baseado no projeto Windows Application Packaging e gera o pacote MSIX. |
| Correção de runtime | Este é um projeto C++ Dynamic-Linked Library que contém uma ou mais funções de substituição que atuam como correção durante a execução. |
| PSFLauncher | Este é um Projeto Vazio C++. Este projeto é um local para coletar os arquivos distribuíveis de tempo de execução do Package Support Framework. Ele gera um arquivo executável. Esse executável é a primeira coisa que é executada quando você inicia a solução. |
| WinFormsDesktopApplication | Este projeto contém o código-fonte de um aplicativo de desktop. |
Para examinar um exemplo completo que contém todos esses tipos de projetos, consulte PSFSample.
Vamos percorrer as etapas para criar e configurar cada um desses projetos em sua solução.
Criar uma solução de pacote
Se tu ainda não tiveres uma solução para a tua aplicação de desktop, cria uma nova Solução em Branco no Visual Studio.
Você também pode querer adicionar quaisquer projetos de aplicativo que você tem.
Adicionar um projeto de empacotamento
Se você ainda não tiver um projeto de empacotamento de aplicativos do Windows, crie um e adicione-o à sua solução.
Para obter mais informações sobre o projeto Windows Application Packaging, consulte Empacotar seu aplicativo usando o Visual Studio.
No Gerenciador de Soluções, clique com o botão direito do mouse no projeto de empacotamento, selecione Editar e adicione isso à parte inferior do arquivo de projeto:
<Target Name="PSFRemoveSourceProject" AfterTargets="ExpandProjectReferences" BeforeTargets="_ConvertItems">
<ItemGroup>
<FilteredNonWapProjProjectOutput Include="@(_FilteredNonWapProjProjectOutput)">
<SourceProject Condition="'%(_FilteredNonWapProjProjectOutput.SourceProject)'=='<your runtime fix project name goes here>'" />
</FilteredNonWapProjProjectOutput>
<_FilteredNonWapProjProjectOutput Remove="@(_FilteredNonWapProjProjectOutput)" />
<_FilteredNonWapProjProjectOutput Include="@(FilteredNonWapProjProjectOutput)" />
</ItemGroup>
</Target>
Adicionar projeto para a correção de tempo de execução
Adicione um projeto C++Dynamic-Link Library (DLL) à solução.
Clique com o botão direito do mouse no projeto e escolha Propriedades.
Nas páginas de propriedades, localize o campo Padrão da linguagem C++ e, na lista suspensa ao lado desse campo, selecione a opção ISO C++17 Standard (/std:c++17).
Clique com o botão direito do mouse nesse projeto e, no menu de contexto, escolha a opção Gerenciar pacotes Nuget . Verifique se a opção Origem do pacote está definida como Todos ou nuget.org.
Clique no ícone de configurações ao lado desse campo.
Procure o pacote Nuget PSF* e instale-o para este projeto.
Se você quiser depurar ou estender uma correção de tempo de execução existente, adicione os arquivos de correção de tempo de execução que você obteve usando as diretrizes descritas na seção Localizar uma correção de tempo de execução deste guia.
Se você pretende criar uma nova correção, não adicione nada a este projeto ainda. Vamos ajudá-lo a adicionar os arquivos certos a este projeto mais adiante neste guia. Por enquanto, continuaremos a configurar a sua solução.
Adicionar um projeto que inicie o executável do Lançador PSF
Adicione um projeto C++ Empty Project à solução.
Adicione o pacote Nuget PSF a este projeto usando as mesmas orientações descritas na seção anterior.
Abra as páginas de propriedades do projeto e, na página Configurações gerais , defina a propriedade Nome do Destino como PSFLauncher32 ou PSFLauncher64 dependendo da arquitetura do seu aplicativo.
Adicione uma referência de projeto ao projeto de correção de tempo de execução em sua solução.
Clique com o botão direito do mouse na referência e, na janela Propriedades , aplique esses valores.
| Propriedade | Valor |
|---|---|
| Copiar local | Verdade |
| Copiar conjuntos de satélites locais | Verdade |
| Saída de montagem de referência | Verdade |
| Dependências da biblioteca de links | Falso |
| Entradas de dependência da biblioteca de links | Falso |
Configurar o projeto de empacotamento
No projeto de empacotamento, clique com o botão direito do mouse na pasta Aplicativos e escolha Adicionar Referência.
Escolha o projeto PSF Launcher e seu projeto de aplicativo de desktop e, em seguida, escolha o botão OK .
Observação
Se você não tiver o código-fonte do seu aplicativo, basta escolher o projeto PSF Launcher. Mostraremos como fazer referência ao seu executável quando você criar um arquivo de configuração.
No nó Aplicativos , clique com o botão direito do mouse no aplicativo Iniciador PSF e escolha Definir como Ponto de Entrada.
Adicione um arquivo nomeado config.json ao seu projeto de empacotamento e, em seguida, copie e cole o seguinte texto json no arquivo. Defina a propriedade Package Action como Content.
{
"applications": [
{
"id": "",
"executable": "",
"workingDirectory": ""
}
],
"processes": [
{
"executable": "",
"fixups": [
{
"dll": "",
"config": {
}
}
]
}
]
}
Forneça um valor para cada chave. Use esta tabela como um guia.
| Matriz | chave | Valor |
|---|---|---|
| Aplicações | ID | Use o valor do atributo Id do elemento Application no manifesto do pacote. |
| Aplicações | executável | O caminho relativo ao pacote para o executável que você deseja iniciar. Na maioria dos casos, você pode obter esse valor do arquivo de manifesto do pacote antes de modificá-lo. É o valor do Executable atributo do Application elemento. |
| Aplicações | diretório de trabalho | (Opcional) Um caminho relativo ao pacote para usar como o diretório de trabalho do aplicativo que é iniciado. Se você não definir esse valor, o sistema operacional usará o System32 diretório como o diretório de trabalho do aplicativo. |
| processos | executável | Na maioria dos casos, este será o nome do executable configurado acima, com o caminho e a extensão de arquivo removidos. |
| correções | dll | Caminho relativo do pacote para a DLL de correção a ser carregada. |
| correções | Configurações | (Opcional) Controla como a DLL de correção se comporta. O formato exato desse valor varia de correção por correção, pois cada correção pode interpretar esse "blob" como quiser. |
Quando terminar, o seu config.json ficheiro terá o seguinte aspeto.
{
"applications": [
{
"id": "DesktopApplication",
"executable": "DesktopApplication/WinFormsDesktopApplication.exe",
"workingDirectory": "WinFormsDesktopApplication"
}
],
"processes": [
{
"executable": ".*App.*",
"fixups": [ { "dll": "RuntimeFix.dll" } ]
}
]
}
Observação
O applications, processese fixups as chaves são matrizes. Isso significa que você pode usar o arquivo config.json para especificar mais de um aplicativo, processo e corrigir DLL.
Depurar uma correção em tempo de execução
No Visual Studio, pressione F5 para iniciar o depurador. A primeira coisa que inicia é o aplicativo PSF Launcher, que, por sua vez, inicia seu aplicativo de desktop de destino. Para depurar o aplicativo da área de trabalho de destino, você terá que anexar manualmente ao processo do aplicativo da área de trabalho escolhendo Depurar-Anexar> ao Processo e, em seguida, selecionando o processo do aplicativo. Para permitir a depuração de um aplicativo .NET com uma DLL de correção de tempo de execução nativa, selecione os tipos de código gerenciado e nativo (depuração de modo misto).
Depois de configurar isso, você pode definir pontos de interrupção ao lado de linhas de código no código do aplicativo da área de trabalho e no projeto de correção de tempo de execução. Se você não tiver o código-fonte para seu aplicativo, poderá definir pontos de interrupção somente ao lado de linhas de código em seu projeto de correção de tempo de execução.
Como a depuração F5 executa o aplicativo implantando arquivos soltos a partir do caminho da pasta de layout do pacote, em vez de instalar a partir de um pacote .msix/.appx, a pasta de layout normalmente não tem as mesmas restrições de segurança que uma pasta de pacote instalada. Como resultado, talvez não seja possível reproduzir erros de negação de acesso ao caminho do pacote antes de aplicar uma correção na execução.
Para resolver esse problema, use a implantação de pacote .msix / .appx em vez da implantação de arquivo solto F5. Para criar um arquivo de pacote .msix / .appx, use o utilitário MakeAppx do SDK do Windows, conforme descrito acima. Ou, no Visual Studio, clique com o botão direito do mouse no nó do projeto de aplicativo e selecione Loja -> Criar pacotes de aplicativos.
Outro problema com o Visual Studio é que ele não tem suporte embutido para anexar a quaisquer processos filho lançados pelo depurador. Isso dificulta a depuração da lógica no processo de inicialização do aplicativo de destino, que deve ser ligado manualmente pelo Visual Studio após a execução.
Para resolver este problema, use um depurador que ofereça suporte ao acoplamento de processos filho. Observe que geralmente não é possível anexar um depurador just-in-time (JIT) ao aplicativo de destino. Isso ocorre porque a maioria das técnicas JIT envolve iniciar o depurador no lugar do aplicativo de destino, por meio da chave do Registro ImageFileExecutionOptions. Isto impede o mecanismo de desvio usado por PSFLauncher.exe para injetar FixupRuntime.dll na aplicação alvo. WinDbg, incluído nas Ferramentas de Depuração para Windows e obtido do SDK do Windows, suporta anexação de processo filho. Agora, ele também oferece suporte à inicialização e depuração diretas de um aplicativo UWP.
Para depurar a inicialização do aplicativo de destino como um processo filho, inicie WinDbg.
windbg.exe -plmPackage PSFSampleWithFixup_1.0.59.0_x86__7s220nvg1hg3m -plmApp PSFSample
No prompt WinDbg, habilite a depuração de processos filho e configure os pontos de paragem adequados.
.childdbg 1
g
(executar até que o aplicativo de destino seja iniciado e invada o depurador)
sxe ld fixup.dll
g
(execute até que a DLL de correção seja carregada)
bp ...
Observação
PLMDebug também pode ser usado para anexar um depurador a um aplicativo após a inicialização, e também está incluído nas Ferramentas de Depuração para Windows. No entanto, é mais complexo de usar do que o suporte direto agora fornecido pelo WinDbg.
Apoio
Tem dúvidas? Pergunte-nos no espaço de conversação do Package Support Framework no site da comunidade de tecnologia MSIX.