Introdução à estrutura de suporte do pacoteGet Started with Package Support Framework

O Package support Framework é um Open Source kit que ajuda a aplicar correções ao seu aplicativo de área de trabalho existente (sem modificar o código) para que ele possa ser executado em um contêiner MSIX.The Package Support Framework is an open source kit that helps you apply fixes to your existing desktop application (without modifying the code) so that it can run in an MSIX container. O Package Support Framework ajuda seu aplicativo a seguir as melhores práticas do ambiente moderno do runtime.The Package Support Framework helps your application follow the best practices of the modern runtime environment.

Este artigo fornece uma visão aprofundada de cada componente da estrutura de suporte do pacote e guia passo a passo para usá-lo.This article provides an indepth look at each component of Package Support Framework and step by step guide to using it.

Entender o que está dentro de uma estrutura de suporte de pacoteUnderstand what is inside a Package Support Framework

O Package Support Framework contém um executável, uma DLL do gerenciador de runtime e um conjunto de correções em runtime.The Package Support Framework contains an executable, a runtime manager DLL, and a set of runtime fixes.

PSF (estrutura de suporte do pacote)

Este é o processo:Here is the process:

  1. Crie um arquivo de configuração que especifique as correções que você deseja aplicar ao seu aplicativo.Create a configuration file that specifies the fixes that you want to apply to your application.
  2. Modifique seu pacote para apontar para o arquivo executável do iniciador da estrutura de suporte do pacote (PSF).Modify your package to point to the Package Support Framework (PSF) launcher executable file.

Quando os usuários iniciam seu aplicativo, o iniciador da estrutura de suporte do pacote é o primeiro executável que é executado.When users starts your application, the Package Support Framework launcher is the first executable that runs. Ele lê o arquivo de configuração e injeta as correções em runtime e a DLL do gerenciador de runtime no processo do aplicativo.It reads your configuration file and injects the runtime fixes and the runtime manager DLL into the application process. O gerenciador de runtime aplica a correção quando ela é necessária para que o aplicativo seja executado em um contêiner MSIX.The runtime manager applies the fix when it's needed by the application to run inside of an MSIX container.

Injeção de DLL do Package Support Framework

Etapa 1: identificar problemas de compatibilidade de aplicativos empacotadosStep 1: Identify packaged application compatibility issues

Primeiro, crie um pacote para seu aplicativo.First, create a package for your application. Em seguida, instale-o, execute-o e observe seu comportamento.Then, install it, run it, and observe its behavior. Você poderá receber mensagens de erro que podem ajudá-lo a identificar um problema de compatibilidade.You might receive error messages that can help you identify a compatibility issue. Use também o Monitor do Processo para identificar problemas.You can also use Process Monitor to identify issues. Problemas comuns relacionados a pressuposições de aplicativo em relação às permissões de diretório de trabalho e caminho do programa.Common issues relate to application assumptions regarding the working directory and program path permissions.

Usando o Process Monitor para identificar um problemaUsing Process Monitor to identify an issue

O Process Monitor é um utilitário poderoso para observar as operações de registro e arquivo de um aplicativo e seus resultados.Process Monitor is a powerful utility for observing an app's file and registry operations, and their results. Isso pode ajudá-lo a entender os problemas de compatibilidade de aplicativos.This can help you to understand application compatibility issues. Depois de abrir o Process Monitor, adicione um filtro (filtro > filtro...) para incluir somente os eventos do executável do aplicativo.After opening Process Monitor, add a filter (Filter > Filter…) to include only events from the application executable.

Filtro de aplicativo ProcMon

Uma lista de eventos será exibida.A list of events will appear. Para muitos desses eventos, a palavra Success será exibida na coluna Result .For many of these events, the word SUCCESS will appear in the Result column.

Eventos de ProcMon

Opcionalmente, você pode filtrar eventos para mostrar apenas as falhas.Optionally, you can filter events to only show only failures.

ProcMon excluir êxito

Se você suspeitar de uma falha de acesso ao sistema de arquivos, Procure eventos com falha que estejam sob o caminho de arquivo system32/SysWOW64 ou pacote.If you suspect a filesystem access failure, search for failed events that are under either the System32/SysWOW64 or the package file path. Os filtros também podem ajudar aqui.Filters can also help here, too. Inicie na parte inferior desta lista e role para cima.Start at the bottom of this list and scroll upwards. As falhas que aparecem na parte inferior desta lista ocorreram mais recentemente.Failures that appear at the bottom of this list have occurred most recently. Preste mais atenção aos erros que contêm cadeias de caracteres como "acesso negado" e "caminho/nome não encontrado" e ignore as coisas que não parecem suspeitas.Pay most attention to errors that contain strings such as "access denied," and "path/name not found", and ignore things that don't look suspicious. O PSFSample tem dois problemas.The PSFSample has two issues. Você pode ver esses problemas na lista que aparece na imagem a seguir.You can see those issues in the list that appears in the following image.

Config.txt ProcMon

No primeiro problema que aparece nessa imagem, o aplicativo está falhando ao ler do arquivo "Config.txt" que está localizado no caminho "C:\Windows\SysWOW64".In the first issue that appears in this image, the application is failing to read from the "Config.txt" file that is located in the "C:\Windows\SysWOW64" path. É improvável que o aplicativo esteja tentando referenciar esse caminho diretamente.It's unlikely that the application is trying to reference that path directly. 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.Most likely, it's trying to read from that file by using a relative path, and by default, "System32/SysWOW64" is the application's working directory. Isso sugere que o aplicativo está esperando que seu diretório de trabalho atual seja definido como algum lugar no pacote.This suggests that the application is expecting its current working directory to be set to somewhere in the package. Olhando dentro do Appx, podemos ver que o arquivo existe no mesmo diretório que o executável.Looking inside of the appx, we can see that the file exists in the same directory as the executable.

Config.txt do aplicativo

O segundo problema aparece na imagem a seguir.The second issue appears in the following image.

Arquivo de log ProcMon

Nesse problema, o aplicativo está falhando em gravar um arquivo. log em seu caminho de pacote.In this issue, the application is failing to write a .log file to its package path. Isso sugere que uma correção de redirecionamento de arquivo pode ajudar.This would suggest that a file redirection fixup might help.

Etapa 2: encontrar uma correção de tempo de execuçãoStep 2: Find a runtime fix

O PSF contém correções de tempo de execução que você pode usar no momento, como a correção de redirecionamento de arquivo.The PSF contains runtime fixes that you can use right now, such as the file redirection fixup.

Correção de redirecionamento de arquivoFile Redirection Fixup

Você pode usar a correção de redirecionamento de arquivo para redirecionar tentativas de gravação ou leitura de dados em um diretório que não está acessível a partir de um aplicativo que é executado em um contêiner MSIX.You can use the File Redirection Fixup to redirect attempts to write or read data in a directory that isn't accessible from an application that runs in an MSIX container.

Por exemplo, se seu aplicativo gravar em um arquivo de log que está no mesmo diretório que o executável de seus aplicativos, você poderá usar a correção de redirecionamento de arquivo para criar esse arquivo de log em outro local, como o armazenamento de dados do aplicativo local.For example, if your application writes to a log file that is in the same directory as your applications executable, then you can use the File Redirection Fixup to create that log file in another location, such as the local app data store.

Correções de tempo de execução da ComunidadeRuntime fixes from the community

Certifique-se de examinar as contribuições da Comunidade em nossa página do GitHub .Make sure to review the community contributions to our GitHub page. É possível que outros desenvolvedores tenham resolvido um problema semelhante ao seu e tenham compartilhado uma correção de tempo de execução.It's possible that other developers have resolved an issue similar to yours and have shared a runtime fix.

Etapa 3: aplicar uma correção de tempo de execuçãoStep 3: Apply a runtime fix

Você pode aplicar uma correção de tempo de execução existente com algumas ferramentas simples do SDK do Windows e seguindo estas etapas.You can apply an existing runtime fix with a few simple tools from the Windows SDK, and by following these steps.

  • Criar uma pasta de layout de pacoteCreate a package layout folder
  • Obter os arquivos da estrutura de suporte do pacoteGet the Package Support Framework files
  • Adicioná-los ao seu pacoteAdd them to your package
  • Modificar o manifesto do pacoteModify the package manifest
  • Criar um arquivo de configuraçãoCreate a configuration file

Vamos examinar cada tarefa.Let's go through each task.

Criar a pasta de layout do pacoteCreate the package layout folder

Se você já tiver um arquivo. msix (ou. AppX), poderá desempacotar seu conteúdo em uma pasta de layout que servirá como a área de preparo para seu pacote.If you have a .msix (or .appx) file already, you can unpack its contents into a layout folder that will serve as the staging area for your package. Você pode fazer isso em um prompt de comando usando a ferramenta MakeAppx, com base no caminho de instalação do SDK, é aqui que você encontrará a ferramenta de makeappx.exe em seu PC com Windows 10: x86: C:\Arquivos de programas (x86) \Windows Kits\10\bin\x86\makeappx.exe x64: C:\Arquivos de programas (x86) \Windows Kits\10\bin\x64\makeappx.exeYou can do this from a command prompt using MakeAppx tool, based on your installation path of the SDK, this is where you will find the makeappx.exe tool on your Windows 10 PC: 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

Isso fornecerá algo parecido com o seguinte.This will give you something that looks like the following.

Layout do pacote

Se você não tiver um arquivo. msix (ou. AppX) para começar, poderá criar a pasta e os arquivos do pacote do zero.If you don't have a .msix (or .appx) file to start with, you can create the package folder and files from scratch.

Obter os arquivos da estrutura de suporte do pacoteGet the Package Support Framework files

Você pode obter o pacote NuGet do PSF usando a ferramenta de linha de comando do NuGet autônomo ou por meio do Visual Studio.You can get the PSF Nuget package by using the standalone Nuget command line tool or via Visual Studio.

Obter o pacote usando a ferramenta de linha de comandoGet the package by using the command line tool

Instale a ferramenta de linha de comando do NuGet deste local: https://www.nuget.org/downloads .Install the Nuget command line tool from this location: https://www.nuget.org/downloads. Em seguida, na linha de comando do NuGet, execute este comando:Then, from the Nuget command line, run this command:

nuget install Microsoft.PackageSupportFramework

Como alternativa, você pode renomear a extensão do pacote para. zip e descompactá-la.Alternatively, you can rename the package extension to .zip and unzip it. Todos os arquivos de que você precisa estarão na pasta/bin.All the files you need will be under the /bin folder.

Obter o pacote usando o Visual StudioGet the package by using Visual Studio

No Visual Studio, clique com o botão direito do mouse no nó da sua solução ou do projeto e escolha um dos comandos gerenciar pacotes NuGet.In Visual Studio, right-click your solution or project node and pick one of the Manage Nuget Packages commands. Procure Microsoft. PackageSupportFramework ou PSF para localizar o pacote em NuGet.org. Em seguida, instale-o.Search for Microsoft.PackageSupportFramework or PSF to find the package on Nuget.org. Then, install it.

Adicionar os arquivos da estrutura de suporte do pacote ao seu pacoteAdd the Package Support Framework files to your package

Adicione as DLLs de PSF e arquivos executáveis de 32 bits e de 64 bits necessários ao diretório do pacote.Add the required 32-bit and 64-bit PSF DLLs and executable files to the package directory. Use a tabela a seguir como guia.Use the following table as a guide. Você também desejará incluir correções de tempo de execução necessárias.You'll also want to include any runtime fixes that you need. Em nosso exemplo, precisamos da correção de tempo de execução de redirecionamento de arquivo.In our example, we need the file redirection runtime fix.

O executável do aplicativo é x64Application executable is x64 O executável do aplicativo é x86Application executable is x86
PSFLauncher64.exePSFLauncher64.exe PSFLauncher32.exePSFLauncher32.exe
PSFRuntime64.dllPSFRuntime64.dll PSFRuntime32.dllPSFRuntime32.dll
PSFRunDll64.exePSFRunDll64.exe PSFRunDll32.exePSFRunDll32.exe

O conteúdo do pacote agora deve ser semelhante a este.Your package content should now look something like this.

Binários de pacote

Modificar o manifesto do pacoteModify the package manifest

Abra o manifesto do pacote em um editor de texto e defina o Executable atributo do Application elemento como o nome do arquivo executável do iniciador PSF.Open your package manifest in a text editor, and then set the Executable attribute of the Application element to the name of the PSF Launcher executable file. Se você souber a arquitetura do seu aplicativo de destino, selecione a versão apropriada, PSFLauncher32.exe ou PSFLauncher64.exe.If you know the architecture of your target application, select the appropriate version, PSFLauncher32.exe or PSFLauncher64.exe. Se não, PSFLauncher32.exe funcionará em todos os casos.If not, PSFLauncher32.exe will work in all cases. Veja um exemplo.Here's an example.

<Package ...>
  ...
  <Applications>
    <Application Id="PSFSample"
                 Executable="PSFLauncher32.exe"
                 EntryPoint="Windows.FullTrustApplication">
      ...
    </Application>
  </Applications>
</Package>

Criar um arquivo de configuraçãoCreate a configuration file

Crie um nome de arquivo config.json e salve esse arquivo na pasta raiz do seu pacote.Create a file name config.json, and save that file to the root folder of your package. Modifique a ID de aplicativo declarada do config.jsno arquivo para apontar para o executável que você acabou de substituir.Modify the declared app ID of the config.json file to point to the executable that you just replaced. Usando o conhecimento obtido 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.Using the knowledge that you gained from using Process Monitor, you can also set the working directory as well as use the file redirection fixup to redirect reads/writes to .log files under the package-relative "PSFSampleApp" directory.

{
    "applications": [
        {
            "id": "PSFSample",
            "executable": "PSFSampleApp/PSFSample.exe",
            "workingDirectory": "PSFSampleApp/"
        }
    ],
    "processes": [
        {
            "executable": "PSFSample",
            "fixups": [
                {
                    "dll": "FileRedirectionFixup.dll",
                    "config": {
                        "redirectedPaths": {
                            "packageRelative": [
                                {
                                    "base": "PSFSampleApp/",
                                    "patterns": [
                                        ".*\\.log"
                                    ]
                                }
                            ]
                        }
                    }
                }
            ]
        }
    ]
}

Veja a seguir um guia para o config.jsno esquema:Following is a guide for the config.json schema:

ArrayArray chavekey ValorValue
de dimensionamento da Webapplications idid Use o valor do Id atributo do Application elemento no manifesto do pacote.Use the value of the Id attribute of the Application element in the package manifest.
de dimensionamento da Webapplications executávelexecutable O caminho relativo do pacote para o executável que você deseja iniciar.The package-relative path to the executable that you want to start. Na maioria dos casos, você pode obter esse valor do arquivo de manifesto do pacote antes de modificá-lo.In most cases, you can get this value from your package manifest file before you modify it. É o valor do Executable atributo do Application elemento.It's the value of the Executable attribute of the Application element.
de dimensionamento da Webapplications workingDirectoryworkingDirectory Adicional Um caminho relativo de pacote a ser usado como o diretório de trabalho do aplicativo que é iniciado.(Optional) A package-relative path to use as the working directory of the application that starts. Se você não definir esse valor, o sistema operacional usará o System32 diretório como o diretório de trabalho do aplicativo.If you don't set this value, the operating system uses the System32 directory as the application's working directory.
processosprocesses executávelexecutable Na maioria dos casos, esse será o nome do executable configurado acima com o caminho e a extensão de arquivo removidos.In most cases, this will be the name of the executable configured above with the path and file extension removed.
ajustesfixups dlldll Caminho relativo ao pacote para a correção,. msix/. Appx a ser carregado.Package-relative path to the fixup, .msix/.appx to load.
ajustesfixups configconfig Adicional Controla como a DLL de correção se comporta.(Optional) Controls how the fixup dll behaves. O formato exato desse valor varia de acordo com a correção, pois cada correção pode interpretar esse "blob" como desejado.The exact format of this value varies on a fixup-by-fixup basis as each fixup can interpret this "blob" as it wants.

As applications processes chaves, e fixups são matrizes.The applications, processes, and fixups keys are arrays. Isso significa que você pode usar a config.jsno arquivo para especificar mais de um aplicativo, processo e DLL de correção.That means that you can use the config.json file to specify more than one application, process, and fixup DLL.

Empacotar e testar o aplicativoPackage and test the app

Em seguida, crie um pacote.Next, create a package.

makeappx pack /d PackageContents /p PSFSamplePackageFixup.msix

Em seguida, assine-o.Then, sign it.

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 SigntoolFor more information, see how to create a package signing certificate and how to sign a package using signtool

Usando o PowerShell, instale o pacote.Using PowerShell, install the package.

Observação

Lembre-se de desinstalar o pacote primeiro.Remember to uninstall the package first.

powershell Add-AppPackage .\PSFSamplePackageFixup.msix

Execute o aplicativo e observe o comportamento com a correção de tempo de execução aplicada.Run the application and observe the behavior with runtime fix applied. Repita as etapas de diagnóstico e empacotamento conforme necessário.Repeat the diagnostic and packaging steps as necessary.

Verificar se a estrutura de suporte do pacote está em execuçãoCheck whether the Package Support Framework is running

Você pode verificar se a correção de tempo de execução está em execução.You can check whether your runtime fix is running. Uma maneira de fazer isso é abrir o Gerenciador de tarefas e clicar em mais detalhes.A way to do this is to open Task Manager and click More details. Localize o aplicativo ao qual a estrutura de suporte do pacote foi aplicada e expanda os detalhes do aplicativo para veiw mais detalhes.Find the app that the package support framework was applied to and expand the app detail to veiw more details. Você deve ser capaz de exibir se a estrutura de suporte do pacote está em execução.You should be able to view that the Package Support Framework is running.

Usar a correção de rastreamentoUse the Trace Fixup

Uma técnica alternativa para diagnosticar problemas de compatibilidade de aplicativos empacotados é usar a correção de rastreamento.An alternative technique to diagnosing packaged application compatibility issues is to use the 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.This DLL is included with the PSF and provides a detailed diagnostic view of the app's behavior, similar to Process Monitor. Ele é especialmente projetado para revelar problemas de compatibilidade de aplicativos.It is specially designed to reveal application compatibility issues. Para usar a correção de rastreamento, adicione a DLL ao pacote, adicione o fragmento a seguir ao seu config.jsativado e, em seguida, empacote e instale o aplicativo.To use the Trace Fixup, add the DLL to the package, add the following fragment to your config.json, and then package and install your application.

{
    "dll": "TraceFixup.dll",
    "config": {
        "traceLevels": {
            "filesystem": "allFailures"
        }
    }
}

Por padrão, a correção de rastreamento filtra falhas que podem ser consideradas "esperadas".By default, the Trace Fixup filters out failures that might be considered "expected". Por exemplo, os aplicativos podem tentar excluir um arquivo incondicionalmente sem verificar se ele já existe, ignorando o resultado.For example, applications might try to unconditionally delete a file without checking to see if it already exists, ignoring the result. Isso tem a conseqüência de que algumas falhas inesperadas podem ser filtradas, portanto, no exemplo acima, optamos por receber todas as falhas das funções FileSystem.This has the unfortunate consequence that some unexpected failures might get filtered out, so in the above example, we opt to receive all failures from filesystem functions. Fazemos isso porque sabemos antes que a tentativa de ler a partir do arquivo de Config.txt falha com a mensagem "arquivo não encontrado".We do this because we know from before that the attempt to read from the Config.txt file fails with the message "file not found". Essa é uma falha que é frequentemente observada e, geralmente, não é presumida como inesperada.This is a failure that is frequently observed and not generally assumed to be unexpected. Na prática, é provável que seja melhor começar a filtragem apenas para falhas inesperadas e, em seguida, voltar a todas as falhas se houver um problema que ainda não possa ser identificado.In practice it's likely best to start out filtering only to unexpected failures, and then falling back to all failures if there's an issue that still can't be identified.

Por padrão, a saída da correção de rastreamento é enviada para o depurador anexado.By default, the output from the Trace Fixup gets sent to the attached debugger. Para este exemplo, não vamos anexar um depurador e, em vez disso, usaremos o programa DebugView da Sysinternals para exibir sua saída.For this example, we aren't going to attach a debugger, and will instead use the DebugView program from SysInternals to view its output. Depois de executar o aplicativo, podemos ver as mesmas falhas que antes, o que nos indicaria nas mesmas correções de tempo de execução.After running the app, we can see the same failures as before, which would point us towards the same runtime fixes.

Arquivo TraceShim não encontrado

Acesso negado ao TraceShim

Depurar, estender ou criar uma correção de tempo de execuçãoDebug, extend, or create a runtime fix

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.You can use Visual Studio to debug a runtime fix, extend a runtime fix, or create one from scratch. Você precisará fazer essas coisas para ter êxito.You'll need to do these things to be successful.

  • Adicionar um projeto de empacotamentoAdd a packaging project
  • Adicionar projeto para a correção de tempo de execuçãoAdd project for the runtime fix
  • Adicionar um projeto que inicia o executável do iniciador PSFAdd a project that starts the PSF Launcher executable
  • Configurar o projeto de empacotamentoConfigure the packaging project

Quando terminar, sua solução terá uma aparência semelhante a esta.When you're done, your solution will look something like this.

Solução concluída

Vamos examinar cada projeto neste exemplo.Let's look at each project in this example.

ProjectProject FinalidadePurpose
DesktopApplicationPackageDesktopApplicationPackage Este projeto é baseado no projeto de empacotamento de aplicativos do Windows e gera o pacote MSIX.This project is based on the Windows Application Packaging project and it outputs the MSIX package.
RuntimefixRuntimefix Este é um projeto de biblioteca de vínculo dinâmico C++ que contém uma ou mais funções de substituição que servem como correção de tempo de execução.This is a C++ Dynamic-Linked Library project that contains one or more replacement functions that serve as the runtime fix.
PSFLauncherPSFLauncher Este é um projeto vazio do C++.This is C++ Empty Project. Este projeto é um local para coletar os arquivos distribuíveis de tempo de execução da estrutura de suporte do pacote.This project is a place to collect the runtime distributable files of the Package Support Framework. Ele gera um arquivo executável.It outputs an executable file. Esse executável é a primeira coisa que é executada quando você inicia a solução.That executable is the first thing that runs when you start the solution.
WinFormsDesktopApplicationWinFormsDesktopApplication Este projeto contém o código-fonte de um aplicativo de área de trabalho.This project contains the source code of a desktop application.

Para examinar um exemplo completo que contém todos esses tipos de projetos, consulte PSFSample.To look at a complete sample that contains all of these types of projects, see PSFSample.

Vamos percorrer as etapas para criar e configurar cada um desses projetos em sua solução.Let's walk through the steps to create and configure each of these projects in your solution.

Criar uma solução de pacoteCreate a package solution

Se você ainda não tiver uma solução para seu aplicativo de área de trabalho, crie uma nova solução em branco no Visual Studio.If you don't already have a solution for your desktop application, create a new Blank Solution in Visual Studio.

Solução em branco

Talvez você também queira adicionar qualquer projeto de aplicativo que você tenha.You may also want to add any application projects you have.

Adicionar um projeto de empacotamentoAdd a packaging project

Se você ainda não tiver um projeto de empacotamento de aplicativos do Windows, crie um e adicione-o à sua solução.If you don't already have a Windows Application Packaging Project, create one and add it to your solution.

Modelo de projeto de pacote

Para obter mais informações sobre o projeto de empacotamento de aplicativos do Windows, consulte empacotar seu aplicativo usando o Visual Studio.For more information on Windows Application Packaging project, see Package your application by using Visual Studio.

Em Gerenciador de soluções, clique com o botão direito do mouse no projeto de empacotamento, selecione Editare, em seguida, adicione-o à parte inferior do arquivo de projeto:In Solution Explorer, right-click the packaging project, select Edit, and then add this to the bottom of the project file:

<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çãoAdd project for the runtime fix

Adicione um projeto de dll (biblioteca de vínculo dinâmico) do C++ à solução.Add a C++ Dynamic-Link Library (DLL) project to the solution.

Biblioteca de correção de tempo de execução

Clique com o botão direito do mouse no projeto e escolha Propriedades.Right-click the that project, and then choose Properties.

Nas páginas de propriedades, encontre o campo padrão da linguagem C++ e, em seguida, na lista suspensa ao lado desse campo, selecione a opção ISO C++ 17 Standard (/std: C++ 17) .In the property pages, find the C++ Language Standard field, and then in the drop-down list next to that field, select the ISO C++17 Standard (/std:c++17) option.

Opção ISO 17

Clique com o botão direito do mouse no projeto e, no menu de contexto, escolha a opção gerenciar pacotes NuGet .Right-click that project, and then in the context menu, choose the Manage Nuget Packages option. Verifique se a opção origem do pacote está definida como All ou NuGet.org.Ensure that the Package source option is set to All or nuget.org.

Clique no ícone de configurações próximo ao campo.Click the settings icon next that field.

Procure o pacote NuGet PSF* e instale-o para este projeto.Search for the PSF* Nuget package, and then install it for this project.

pacote nuget

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 obtidos usando as diretrizes descritas na seção encontrar uma correção de tempo de execução deste guia.If you want to debug or extend an existing runtime fix, add the runtime fix files that you obtained by using the guidance described in the Find a runtime fix section of this guide.

Se você pretende criar uma correção totalmente nova, não adicione nada a esse projeto ainda.If you intend to create a brand new fix, don't add anything to this project just yet. Ajudaremos você a adicionar os arquivos corretos a esse projeto posteriormente neste guia.We'll help you add the right files to this project later in this guide. Por enquanto, continuaremos Configurando sua solução.For now, we'll continue setting up your solution.

Adicionar um projeto que inicia o executável do iniciador PSFAdd a project that starts the PSF Launcher executable

Adicione um projeto de projeto vazio do C++ à solução.Add a C++ Empty Project project to the solution.

Projeto vazio

Adicione o pacote NuGet do PSF a este projeto usando as mesmas diretrizes descritas na seção anterior.Add the PSF Nuget package to this project by using the same guidance described in the previous section.

Abra as páginas de propriedades do projeto e, na página configurações gerais , defina a propriedade nome de destino como PSFLauncher32 ou PSFLauncher64 dependendo da arquitetura do seu aplicativo.Open the property pages for the project, and in the General settings page, set the Target Name property to PSFLauncher32 or PSFLauncher64 depending on the architecture of your application.

Referência do iniciador PSF

Adicione uma referência de projeto ao projeto de correção de tempo de execução em sua solução.Add a project reference to the runtime fix project in your solution.

referência de correção de tempo de execução

Clique com o botão direito do mouse na referência e, em seguida, na janela Propriedades , aplique esses valores.Right-click the reference, and then in the Properties window, apply these values.

PropriedadeProperty ValorValue
Copiar localCopy local VerdadeiroTrue
Assemblies Satélite do Local da CópiaCopy Local Satellite Assemblies VerdadeiroTrue
Saída do Assembly de ReferênciaReference Assembly Output VerdadeiroTrue
Dependências da Biblioteca de LinksLink Library Dependencies FalsoFalse
Entradas de dependência da biblioteca de linksLink Library Dependency Inputs FalsoFalse

Configurar o projeto de empacotamentoConfigure the packaging project

No projeto de empacotamento, clique com botão direito na pasta Aplicativos e escolha Adicionar referência.In the packaging project, right-click the Applications folder, and then choose Add Reference.

Adicionar Referência de Projeto

Escolha o projeto do iniciador PSF e o projeto de aplicativo da área de trabalho e escolha o botão OK .Choose the PSF Launcher project and your desktop application project, and then choose the OK button.

Projeto de área de trabalho

Observação

Se você não tiver o código-fonte para seu aplicativo, basta escolher o projeto iniciador PSF.If you don't have the source code to your application, just choose the PSF Launcher project. Mostraremos como fazer referência ao seu executável ao criar um arquivo de configuração.We'll show you how to reference your executable when you create a configuration file.

No nó aplicativos , clique com o botão direito do mouse no aplicativo iniciador PSF e escolha definir como ponto de entrada.In the Applications node, right-click the PSF Launcher application, and then choose Set as Entry Point.

Definir ponto de entrada

Adicione um arquivo chamado config.json ao seu projeto de empacotamento e copie e cole o texto JSON a seguir no arquivo.Add a file named config.json to your packaging project, then, copy and paste the following json text into the file. Defina a propriedade ação do pacote como conteúdo.Set the Package Action property to Content.

{
    "applications": [
        {
            "id": "",
            "executable": "",
            "workingDirectory": ""
        }
    ],
    "processes": [
        {
            "executable": "",
            "fixups": [
                {
                    "dll": "",
                    "config": {
                    }
                }
            ]
        }
    ]
}

Forneça um valor para cada chave.Provide a value for each key. Use essa tabela como um guia.Use this table as a guide.

ArrayArray chavekey ValorValue
de dimensionamento da Webapplications idid Use o valor do Id atributo do Application elemento no manifesto do pacote.Use the value of the Id attribute of the Application element in the package manifest.
de dimensionamento da Webapplications executávelexecutable O caminho relativo do pacote para o executável que você deseja iniciar.The package-relative path to the executable that you want to start. Na maioria dos casos, você pode obter esse valor do arquivo de manifesto do pacote antes de modificá-lo.In most cases, you can get this value from your package manifest file before you modify it. É o valor do Executable atributo do Application elemento.It's the value of the Executable attribute of the Application element.
de dimensionamento da Webapplications workingDirectoryworkingDirectory Adicional Um caminho relativo de pacote a ser usado como o diretório de trabalho do aplicativo que é iniciado.(Optional) A package-relative path to use as the working directory of the application that starts. Se você não definir esse valor, o sistema operacional usará o System32 diretório como o diretório de trabalho do aplicativo.If you don't set this value, the operating system uses the System32 directory as the application's working directory.
processosprocesses executávelexecutable Na maioria dos casos, esse será o nome do executable configurado acima com o caminho e a extensão de arquivo removidos.In most cases, this will be the name of the executable configured above with the path and file extension removed.
ajustesfixups dlldll Caminho relativo do pacote para o DLL de correção a ser carregado.Package-relative path to the fixup DLL to load.
ajustesfixups configconfig Adicional Controla como a DLL de correção se comporta.(Optional) Controls how the fixup DLL behaves. O formato exato desse valor varia de acordo com a correção, pois cada correção pode interpretar esse "blob" como desejado.The exact format of this value varies on a fixup-by-fixup basis as each fixup can interpret this "blob" as it wants.

Quando terminar, o config.json arquivo terá uma aparência semelhante a esta.When you're done, your config.json file will look something like this.

{
  "applications": [
    {
      "id": "DesktopApplication",
      "executable": "DesktopApplication/WinFormsDesktopApplication.exe",
      "workingDirectory": "WinFormsDesktopApplication"
    }
  ],
  "processes": [
    {
      "executable": ".*App.*",
      "fixups": [ { "dll": "RuntimeFix.dll" } ]
    }
  ]
}

Observação

As applications processes chaves, e fixups são matrizes.The applications, processes, and fixups keys are arrays. Isso significa que você pode usar a config.jsno arquivo para especificar mais de um aplicativo, processo e DLL de correção.That means that you can use the config.json file to specify more than one application, process, and fixup DLL.

Depurar uma correção de tempo de execuçãoDebug a runtime fix

No Visual Studio, pressione F5 para iniciar o depurador.In Visual Studio, press F5 to start the debugger. A primeira coisa que inicia é o aplicativo iniciador PSF, que, por sua vez, inicia o aplicativo de área de trabalho de destino.The first thing that starts is the PSF Launcher application, which in turn, starts your target desktop application. Para depurar o aplicativo de área de trabalho de destino, você precisará anexar manualmente ao processo de aplicativo da área de trabalho escolhendo debug->anexar ao processoe, em seguida, selecionando o processo do aplicativo.To debug the target desktop application, you'll have to manually attach to the desktop application process by choosing Debug->Attach to Process, and then selecting the application process. Para permitir a depuração de um aplicativo .NET com uma DLL de correção de tempo de execução nativa, selecione tipos de código gerenciados e nativos (depuração de modo misto).To permit the debugging of a .NET application with a native runtime fix DLL, select managed and native code types (mixed mode debugging).

Depois de configurar isso, você pode definir pontos de interrupção ao lado das linhas de código no código do aplicativo da área de trabalho e no projeto de correção de tempo de execução.Once you've set this up, you can set break points next to lines of code in the desktop application code and the runtime fix project. Se você não tiver o código-fonte para seu aplicativo, poderá definir pontos de interrupção somente ao lado das linhas de código em seu projeto de correção de tempo de execução.If you don't have the source code to your application, you'll be able to set break points only next to lines of code in your runtime fix project.

Como a depuração F5 executa o aplicativo implantando arquivos soltos do caminho da pasta de layout do pacote, em vez de instalar 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.Because F5 debugging runs the application by deploying loose files from the package layout folder path, rather than installing from a .msix/.appx package, the layout folder typically does not have the same security restrictions as an installed package folder. Como resultado, talvez não seja possível reproduzir os erros de negação de acesso ao caminho do pacote antes de aplicar uma correção de tempo de execução.As a result, it may not be possible to reproduce package path access denial errors prior to applying a runtime fix.

Para resolver esse problema, use a implantação de pacote. msix/. Appx em vez de F5 implantação de arquivo flexível.To address this issue, use .msix / .appx package deployment rather than F5 loose file deployment. Para criar um arquivo de pacote. msix/. Appx, use o utilitário MakeAppx do SDK do Windows, conforme descrito acima.To create a .msix / .appx package file, use the MakeAppx utility from the Windows SDK, as described above. Ou, no Visual Studio, clique com o botão direito do mouse no nó do projeto de aplicativo e selecione Store-> criar pacotes de aplicativos.Or, from within Visual Studio, right-click your application project node and select Store -> Create App Packages.

Outro problema com o Visual Studio é que ele não tem suporte interno para anexar a processos filho iniciados pelo depurador.Another issue with Visual Studio is that it does not have built-in support for attaching to any child processes launched by the debugger. Isso dificulta a depuração da lógica no caminho de inicialização do aplicativo de destino, que deve ser anexado manualmente pelo Visual Studio após a inicialização.This makes it difficult to debug logic in the startup path of the target application, which must be manually attached by Visual Studio after launch.

Para resolver esse problema, use um depurador que dá suporte à anexação de processo filho.To address this issue, use a debugger that supports child process attach. Observe que geralmente não é possível anexar um depurador JIT (just-in-time) ao aplicativo de destino.Note that it is generally not possible to attach a just-in-time (JIT) debugger to the target application. Isso ocorre porque a maioria das técnicas de JIT envolve a inicialização do depurador no lugar do aplicativo de destino, por meio da chave do registro ImageFileExecutionOptions.This is because most JIT techniques involve launching the debugger in place of the target app, via the ImageFileExecutionOptions registry key. Isso anula o mecanismo de desvio usado pelo PSFLauncher.exe para injetar FixupRuntime.dll no aplicativo de destino.This defeats the detouring mechanism used by PSFLauncher.exe to inject FixupRuntime.dll into the target app. O WinDbg, incluído nas ferramentas de depuração para Windows, e obtido do SDK do Windows, dá suporte à anexação do processo filho.WinDbg, included in the Debugging Tools for Windows, and obtained from the Windows SDK, supports child process attach. Agora, ele também dá suporte à inicialização e à depuração direta de um aplicativo UWP.It also now supports directly launching and debugging a UWP app.

Para depurar a inicialização do aplicativo de destino como um processo filho, inicie WinDbg .To debug target application startup as a child process, start WinDbg.

windbg.exe -plmPackage PSFSampleWithFixup_1.0.59.0_x86__7s220nvg1hg3m -plmApp PSFSample

No WinDbg prompt, habilite a depuração de filho e defina os pontos de interrupção apropriados.At the WinDbg prompt, enable child debugging and set appropriate breakpoints.

.childdbg 1
g

(execute até que o aplicativo de destino inicie e quebre no depurador)(execute until target application starts and breaks into the debugger)

sxe ld fixup.dll
g

(execute até que a DLL de correção seja carregada)(execute until the fixup DLL is loaded)

bp ...

Observação

O o plmdebug também pode ser usado para anexar um depurador a um aplicativo na inicialização e também está incluído nas ferramentas de depuração para Windows.PLMDebug can be also used to attach a debugger to an app upon launch, and is also included in the Debugging Tools for Windows. No entanto, é mais complexo usar do que o suporte direto agora fornecido pelo WinDbg.However, it is more complex to use than the direct support now provided by WinDbg.

SuporteSupport

Tem dúvidas?Have questions? Pergunte-nos sobre o pacote de suporte de estrutura de conversa do Framework no site da Comunidade do MSIX Tech.Ask us on the Package Support Framework conversation space on the MSIX tech community site.