在 Visual Studio 中应用包支持框架Apply Package Support Framework in Visual Studio

包支持框架(PSF)是一个开源项目,可用于将修补程序应用于现有的桌面应用程序。The Package Support Framework (PSF) is an open source project that enables you to apply fixes to your existing desktop application. PSF 使应用程序能够在不修改代码的情况下以 .MSIX 封装格式运行。The PSF enables an application to run in an MSIX packaged format without modifying code. 包支持框架可帮助应用程序遵循新式运行时环境的最佳做法。The Package Support Framework helps your application follow the best practices of the modern runtime environment.

在以下部分中,我们将探讨如何创建新的 Visual Studio 项目,如何在解决方案中包含包支持框架,以及如何创建运行时修复。In the following sections, we will explore how to create a new Visual Studio project, include Package Support Framework to the solution, and create runtime fixes.

步骤1:在 Visual Studio 中创建包解决方案Step 1: Create a package solution in Visual Studio

在 Visual Studio 中,创建一个新的Visual Studio 解决方案 "空白解决方案"In Visual Studio, create a new Visual Studio Solutions, Blank Solution. 将所有应用程序项目包括到新创建的空白解决方案Include any application projects to the newly created Blank Solution.

步骤2:添加打包项目Step 2: Add a packaging project

如果还没有Windows 应用程序打包项目,请创建一个项目并将其添加到解决方案中。If you don't already have a Windows Application Packaging Project, create one and add it to your solution. 创建新的Visual c # > Windows 通用 > Windows 应用程序打包项目,并将其添加到新创建的解决方案中。Create a new Visual C# -> Windows Universal -> Windows Application Packaging Project and add it to your newly created solution.

有关 Windows 应用程序打包项目的详细信息,请参阅使用 Visual Studio 打包你的应用程序For more information on Windows Application Packaging project, see Package your application by using Visual Studio.

解决方案资源管理器中,右键单击打包项目,选择 "编辑",然后将其添加到项目文件的底部: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)'=='<Runtime fix project name>'" />
  </FilteredNonWapProjProjectOutput>
  <_FilteredNonWapProjProjectOutput Remove="@(_FilteredNonWapProjProjectOutput)" />
  <_FilteredNonWapProjProjectOutput Include="@(FilteredNonWapProjProjectOutput)" />
</ItemGroup>
</Target>

步骤3:为运行时修复添加项目Step 3: Add project for the runtime fix

向解决方案添加新的Visual C++ > Windows 桌面 > 动态链接库(DLL) 项目。Add a new Visual C++ -> Windows Desktop -> Dynamic-Link Library (DLL) project to the solution.

接下来,右键单击该项目,然后选择 "属性"。Next, right-click the that project, and then choose Properties.

在 "属性" 页中,找到 "配置属性-> c/c + +-> 语言 > c + + 语言标准" 字段。In the property page, locate the Configuration Properties -> C/C++ -> Language -> C++ Language Standard field. 然后从下拉菜单中选择 "ISO c + + 17 标准(/std: c + + 17)"。Then select ISO C++17 Standard (/std:c++17) from the drop-down menu.

右键单击该项目,然后在上下文菜单中,选择 "管理 Nuget 包" 选项。Right-click on the project, and then in the context menu, choose the Manage Nuget Packages option. 确保 "包源" 选项设置为 "全部" 或 " nuget.org"。Ensure that the Package source option is set to All or nuget.org.

单击 "设置" 图标旁边的字段。Click the settings icon next that field.

在 Nuget 包中搜索PSF,然后安装此项目的PackageSupportFrameworkSearch the Nuget packages for PSF, then install the Microsoft.PackageSupportFramework for this project.

NuGet 包

步骤4:添加启动 PSF 启动器可执行文件的项目Step 4: Add a project that starts the PSF Launcher executable

向解决方案中添加新的Visual C++ > 常规 > 空项目Add a new Visual C++ -> General -> Empty Project to the solution.

请执行以下步骤:Do the following steps:

  1. 右键单击该项目,然后在上下文菜单中,选择 "管理 Nuget 包" 选项。Right-click that project, and then in the context menu, choose the Manage Nuget Packages option. 确保 "包源" 选项设置为 "全部" 或 " nuget.org"。Ensure that the Package source option is set to All or nuget.org.
  2. 单击 "设置" 图标旁边的字段。Click the settings icon next that field.
  3. 在 Nuget 包中搜索 PSF,然后安装此项目的 PackageSupportFramework。Search the Nuget packages for PSF, then install the Microsoft.PackageSupportFramework for this project.

打开项目的 "属性" 页,并在 "常规设置" 页中,将 "目标名称" 属性设置为 PSFLauncher32 或, PSFLauncher64 具体取决于应用程序的体系结构。Open the properties 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.

将项目引用添加到解决方案中的运行时修复项目。Add a project reference to the runtime fix project in your solution.

右键单击该引用,然后在 "属性" 窗口中应用这些值。Right-click the reference, and then in the Properties window, apply these values.

propertiesProperty ValueValue
复制本地Copy local TrueTrue
复制本地附属程序集Copy Local Satellite Assemblies TrueTrue
引用程序集输出Reference Assembly Output TrueTrue
链接库依赖项Link Library Dependencies FalseFalse
链接库依赖项输入Link Library Dependency Inputs FalseFalse

步骤5:配置打包项目Step 5: Configure the packaging project

若要配置打包项目,请执行以下步骤:To configure the packaging project do the following steps:

  1. 在打包项目中,右键单击 "应用程序" 文件夹,然后从下拉菜单中选择 "添加引用"。In the packaging project, right-click the Applications folder, and then choose Add Reference from the dropdown menu.
  2. 选择 PSF 启动器项目和桌面应用程序项目,然后选择 "确定" 按钮。Choose the PSF Launcher project and your desktop application project, and then choose the OK button.
  3. 选择PSF 启动器桌面应用程序项目,然后单击 "确定" 按钮。Select both the PSF Launcher and the Desktop Application project, then click the Ok button. 如果应用程序源代码不可用,则仅选择 PSF 启动器项目。If the application source code is not available, select only the PSF Launcher project.
  4. 在 "应用程序" 节点中,右键单击 PSF 启动器应用程序,然后选择 "设置为入口点"。In the Applications node, right-click the PSF Launcher application, and then choose Set as Entry Point.

向打包项目添加一个名为的文件 config.json ,然后将以下 json 文本复制并粘贴到该文件中。Add a file named config.json to your packaging project, then, copy and paste the following json text into the file. 将 "包操作" 属性设置为 "内容"。Set the Package Action property to Content.

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

为每个键提供一个值。Provide a value for each key. 使用此表作为指南。Use this table as a guide.

ArrayArray key ValueValue
applicationsapplications idid 使用 Id Application 包清单中元素的属性的值。Use the value of the Id attribute of the Application element in the package manifest.
applicationsapplications 可执行文件executable 要启动的可执行文件的包相对路径。The package-relative path to the executable that you want to start. 在大多数情况下,你可以在修改之前从包清单文件中获取此值。In most cases, you can get this value from your package manifest file before you modify it. 它是元素的属性的值 Executable ApplicationIt's the value of the Executable attribute of the Application element.
applicationsapplications workingDirectoryworkingDirectory 可有可无要用作启动的应用程序的工作目录的包相对路径。(Optional) A package-relative path to use as the working directory of the application that starts. 如果未设置此值,操作系统将使用 System32 目录作为应用程序的工作目录。If you don't set this value, the operating system uses the System32 directory as the application's working directory.
进程processes 可执行文件executable 在大多数情况下,这将是上面配置的名称, executable 其中包含已删除的路径和文件扩展名。In most cases, this will be the name of the executable configured above with the path and file extension removed.
修正fixups dlldll 要加载的链接地址 DLL 的包相对路径。Package-relative path to the fixup DLL to load.
修正fixups configconfig 可有可无控制修正 DLL 的行为方式。(Optional) Controls how the fixup DLL behaves. 此值的准确格式因修正链接而异,因为每个修正都可以根据需要解释此 "blob"。The exact format of this value varies on a fixup-by-fixup basis as each fixup can interpret this "blob" as it wants.

完成后, config.json 文件将如下所示。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" } ]
    }
  ]
}

备注

applicationsprocessesfixups 键是数组。The applications, processes, and fixups keys are arrays. 这意味着,你可以使用配置 json 文件来指定多个应用程序、进程和修复 DLL。That means that you can use the config.json file to specify more than one application, process, and fixup DLL.

调试运行时修补程序Debug a runtime fix

在 Visual Studio 中,按 F5 启动调试器。In Visual Studio, press F5 to start the debugger. 第一件事是 PSF 启动器应用程序,该应用程序随后会启动目标桌面应用程序。The first thing that starts is the PSF Launcher application, which in turn, starts your target desktop application. 若要调试目标桌面应用程序,必须通过选择 "调试"->"附加到进程",然后选择应用程序进程,手动附加到桌面应用程序进程。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. 若要允许使用本机运行时修复 DLL 调试 .NET 应用程序,请选择 "托管和本机代码类型(混合模式调试)"。To permit the debugging of a .NET application with a native runtime fix DLL, select managed and native code types (mixed mode debugging).

可以在桌面应用程序代码和运行时修复项目中的代码行旁边设置断点。You can set break points next to lines of code in the desktop application code and the runtime fix project. 如果你的应用程序没有源代码,则只能在运行时修复项目中的代码行旁边设置断点。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.