包支持框架 - 文件系统写入权限修复

调查

Windows应用会将与应用程序相关的特定目录重定向到 Windows容器文件夹。 如果应用程序尝试写入应用Windows,将触发错误,写入将失败。

使用包支持框架 (PSF) ,可以增强 Windows 应用包以解决此问题。 首先,必须识别失败以及应用请求的目录路径。

捕获Windows失败

筛选结果是一个可选步骤,可以更轻松地查看与应用程序相关的故障。 为此,我们将创建两个筛选器规则。 第一个包含筛选器用于应用程序进程名称,第二个包含任何未成功的结果。

  1. SysInternals 进程监视器 下载并提取到 C:\PSF\ProcessMonitor 目录。
  2. 打开Windows资源管理器并导航到提取的 SysInternals 进程监视器文件夹
  3. 双击 SysInternals 进程监视器 (procmon.exe) 文件,启动应用。
  4. 如果 UAC 提示,请选择" 是" 按钮。
  5. 在"进程监视器筛选器窗口"中,选择标有"体系结构"的第一个 下拉菜单
  6. 下拉菜单中选择 "进程名称"。
  7. 在下一个下拉菜单中,验证其值是否 设置为
  8. 在文本字段中,键入应用进程的进程名称 (示例:PSFSample.exe) 。 具有应用名称的进程监视器筛选器Windows示例
  9. 选择“添加”按钮。
  10. 在"进程监视器筛选器窗口"中,选择标记为"进程名称"的第一个 下拉菜单
  11. 下拉菜单 中选择"结果"。
  12. 在下一个下拉菜单中,选择它 ,然后从 下拉菜单中选择"不是"。
  13. 在文本字段中键入 :SUCCESS 进程监视器筛选器示例Windows结果
  14. 选择“添加”按钮。
  15. 选择“确定”按钮。
  16. 启动Windows应用,触发错误,并关闭Windows应用。

查看Windows失败日志

捕获应用Windows后,需要调查结果以确定失败是否与工作目录相关。

  1. 查看 SysInternals 进程监视器结果,搜索上表中概述的故障。
  2. 如果结果显示"找不到名称 " 结果,以及特定应用的详细信息"所需访问 :...", 该应用面向 "C:\Program Files\WindowsApps \ ..." \ 外部的目录 (如下图) 所示,然后你已成功识别与工作目录相关的故障,请使用 PSF 支持 - 文件系统访问一文获取有关如何将 PSF 更正应用于应用的指南。 显示 SysInternals 进程监视器中针对无法写入目录而见证的错误消息。

解决方案

Windows应用会将与应用程序相关的特定目录重定向到 Windows容器文件夹。 如果应用程序尝试写入应用Windows,将触发错误,写入将失败。

若要解决与应用程序Windows无法写入 Windows 应用容器相关的问题,必须执行以下四个步骤:

  1. 将Windows应用阶段到本地目录
  2. 创建Config.js并注入所需的 PSF 文件
  3. 更新 Windows AppxManifest 文件
  4. 重新打包并Windows应用

上述步骤指导将 Windows 应用的内容提取到本地分步目录,将 PSF 修复文件注入到分步 Windows 应用目录中,将应用程序 Launcher 配置为指向 PSF 启动器,然后配置 PSF config.json 文件,将 PSF 启动器重定向到指定工作目录的应用。

下载并安装所需的工具

此过程将指导你完成以下工具的检索和使用:

  • NuGet客户端工具
  • 包支持框架
  • Windows 10SDK (最新版本)
  • SysInternals 进程监视器

下面将提供有关下载和安装所需工具的分步指南。

  1. 下载 (客户端) 的最新NuGet预览版,nuget.exe文件夹 C:\PSF\nuget

  2. 通过从管理 PowerShell 窗口运行以下代码,使用 Nuget 下载包支持框架:

    Set-Location "C:\PSF"
    .\nuget\nuget.exe install Microsoft.PackageSupportFramework
    
  3. 下载并安装Windows 10 Software Development Toolkit (Win 10 SDK) 。

    1. 下载 Win 10 SDK
    2. 运行 winsdksetup.exe 步骤中下载的脚本。
    3. 选择“下一步”按钮。
    4. 仅选择要安装的以下三项功能:
      • 适用于桌面应用的 Windows SDK 签名工具
      • 适用于 UWP C++ 应用的 Windows SDK
      • 适用于 UWP 应用的 Windwos SDK 本地化
    5. 选择“安装”按钮。
    6. 选择“确定”按钮。

阶段Windows应用

通过暂Windows应用,我们将提取/解压缩 Windows 应用的内容到本地目录。 将 Windows 应用解压缩到暂存位置后,可以注入 PSF 修复文件来更正任何不需要的体验。

  1. 打开"管理 PowerShell"窗口。

  2. 设置以下针对特定应用文件的变量,Windows 10 SDK 版本:

    $AppPath          = "C:\PSF\SourceApp\PSFSampleApp.msix"         ## Path to the MSIX App Installer
    $StagingFolder    = "C:\PSF\Staging\PSFSampleApp"                ## Path to where the MSIX App will be staged
    $OSArchitecture   = "x$((gwmi Win32_Processor).AddressWidth)"    ## Operating System Architecture
    $Win10SDKVersion  = "10.0.19041.0"                               ## Latest version of the Win10 SDK
    
  3. 通过运行Windows PowerShell cmdlet 将应用解压缩到暂存文件夹:

    ## Sets the directory to the Windows 10 SDK
    Set-Location "${env:ProgramFiles(x86)}\Windows Kits\10\Bin\$Win10SDKVersion\$OSArchitecture"
    
    ## Unpackages the Windows App to the staging folder
    .\makeappx.exe unpack /p "$AppPath" /d "$StagingFolder"
    

创建并注入所需的 PSF 文件

若要对 Windows 应用应用config.js,必须创建config.js on 文件,并提供有关失败Windows应用Launcher的信息。 如果有多个Windows启动器遇到问题,config.js更新具有多个条目的 on 文件。

更新config.js on 文件后,config.js on 文件和支持 PSF 修复文件必须移动到 Windows 应用包的根目录。

  1. 打开Visual Studio Code (VS Code) 或其他任何文本编辑器。

  2. 通过选择文件顶部的"文件"菜单,VS Code下拉菜单中选择"新建文件",以创建新文件。

  3. 在 上config.js文件,选择"文件"菜单VS Code,然后从下拉菜单中选择"保存"。 在"另存为"窗口中,导航到 Windows 应用暂存目录 (C:\PSF\Staging\PSFSampleApp) ,将"文件名 "设置为 config.json 。 选择“保存”按钮。

  4. 将以下代码复制到新创建的config.js on 文件中。

    {
        "applications": [
            {
                "id": "",
                "executable": ""
            }
        ],
        "processes": [
            {
                "executable": "",
                "fixups": [
                {
                    "dll": "",
                    "config": {
                        "redirectedPaths": {
                            "packageRelative": [
                                {
                                    "base": "",
                                    "patterns": [
                                        ""
                                    ]
                                }
                            ]
                        }
                    }
                }
            ]
            }
        ]
    }
    
  5. 使用 VS Code 或其他文本编辑器打开位于 Windows 应用暂存文件夹 (C:\PSF\Staging\PSFSampleApp\AppxManifest.xml) app AppxManifest 暂存文件夹中的暂存文件。 Windows

    <Applications>
        <Application Id="PSFSAMPLE" Executable="VFS\ProgramFilesX64\PS Sample App\PSFSample.exe" EntryPoint="Windows.FullTrustApplication">
        <uap:VisualElements BackgroundColor="transparent" DisplayName="PSFSample" Square150x150Logo="Assets\StoreLogo.png" Square44x44Logo="Assets\StoreLogo.png" Description="PSFSample">
            <uap:DefaultTile Wide310x150Logo="Assets\StoreLogo.png" Square310x310Logo="Assets\StoreLogo.png" Square71x71Logo="Assets\StoreLogo.png" />
        </uap:VisualElements>
        </Application>
    </Applications>
    
  6. applications.idconfig.js 中的值 设置为与在 Applications.Application.ID 文件的AppxManifest.xml字段中找到的值相同。 图像:围绕 AppxManifest 文件中 ID 的位置。

  7. 在config.js中设置值,以面向位于Applications.Application.Exe文件的可剪切字段中的应用程序 applications.executableAppxManifest.xml路径。
    围绕 AppxManifest 文件中可执行文件的位置的图像。

  8. 在 上设置config.js中的值,以定位在Applications.Application.Exeapplications.workingdirectory 文件的可 剪切字段中找到的相对 AppxManifest.xml 路径。 图像:在 AppxManifest 文件中循环显示工作目录的位置。

  9. process.executableconfig.js on 中的值设置为 (文件中没有路径和扩展名) 在AppxManifest.xml文件的Applications.Application.Exe 剪切字段中找到。 在 AppxManifest 文件中循环进程可执行文件的位置的图像。

  10. processes.fixups.dll 上设置 config.js中的值,以面向特定于FileRedirectionFixup.dll。 如果更正适用于 x64 体系结构,则将 值设置为 FileRedirectionFixup64.dll。 如果体系结构为 x86 或未知,请设置要FileRedirectionFixup86.dll

  11. 将上一config.js中的值设置为包相对文件夹路径,Applications.Application.Exeprocesses.fixups.config.redirectedPaths.packageRelative.base 文件 可AppxManifest.xml路径。
    图像:在 AppxManifest 文件中循环显示工作目录的位置。

  12. processes.fixups.config.redirectedPaths.packageRelative.patternsconfig.js on 文件中设置值,以匹配应用程序创建的文件类型。 通过使用 ". \ .log",PSF* 将为 processes.fixups.config.redirectedPaths.packageRelative.base 路径中标识的目录中的所有日志文件以及子目录重定向写入。

  13. 保存已更新 config.js文件

    {
        "applications": [
            {
            "id": "PSFSample",
            "executable": "VFS/ProgramFilesX64/PS Sample App/PSFSample.exe"
            }
        ],
        "processes": [
            {
                "executable": "PSFSample",
                "fixups": [
                    {
                        "dll": "FileRedirectionFixup64.dll",
                        "config": {
                            "redirectedPaths": {
                                "packageRelative": [
                                    {
                                        "base": "VFS/ProgramFilesX64/PS Sample App/",
                                        "patterns": [
                                            ".*\\.log"
                                        ]
                                    }
                                ]
                            }
                        }
                    }
                ]
            }
        ]
    }
    
  14. 将以下四个文件从基于应用程序可执行体系结构的包支持框架复制到已Windows根。 以下文件位于 .\Microsoft.PackageSupportFramework 中。 \bin

    应用程序 (x64) X86 (的应用程序)
    PSFLauncher64.exe PSFLauncher32.exe
    PSFRuntime64.dll PSFRuntime32.dll
    PSFRunDll64.exe PSFRunDll32.exe
    FileRedirectionFixup64.dll FileRedirectionFixup64.dll

更新 Appxmanifest.xml

创建和更新文件 上的config.js 后,必须为 Launcher 上 包含的每个 Windows 应用config.js更新 Windows 应用的 AppxManifest.xmlAppxmanifest.xml 的应用程序现在必须针对与应用程序体系结构关联的 PSFLauncher.exe

  1. 打开文件资源管理器,然后导航到暂存的 .MSIX 应用程序文件夹 (C:\PSF\Staging\PSFSampleApp) 。

  2. 右键单击 " AppxManifest.xml",然后从 (下拉菜单中选择 "从 代码打开 " (可选),可以通过其他文本编辑器) 打开。

  3. 更新 AppxManifest.xml 文件,其中包含以下信息:

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

重新打包应用程序

已应用所有更正,现在可以将 Windows 应用重新打包成 .msix,并使用代码签名证书对其进行签名。

  1. 打开管理 PowerShell 窗口。

  2. 设置以下变量:

    $AppPath          = "C:\PSF\SourceApp\PSFSampleApp_Updated.msix" ## Path to the MSIX App Installer
    $CodeSigningCert  = "C:\PSF\Cert\CodeSigningCertificate.pfx"     ## Path to your code signing certificate
    $CodeSigningPass  = "<Password>"                                 ## Password used by the code signing certificate
    $StagingFolder    = "C:\PSF\Staging\PSFSampleApp"                ## Path to where the MSIX App will be staged
    $OSArchitecture   = "x$((gwmi Win32_Processor).AddressWidth)"    ## Operating System Architecture
    $Win10SDKVersion  = "10.0.19041.0"                               ## Latest version of the Win10 SDK
    
  3. 通过运行以下 PowerShell cmdlet 从暂存文件夹中重新打包 Windows 应用程序:

    Set-Location "${env:ProgramFiles(x86)}\Windows Kits\10\Bin\$Win10SDKVersion\$OSArchitecture"
    .\makeappx.exe pack /p "$AppPath" /d "$StagingFolder"
    
  4. 通过运行以下 PowerShell cmdlet 对 Windows 应用进行签名:

    Set-Location "${env:ProgramFiles(x86)}\Windows Kits\10\Bin\$Win10SDKVersion\$OSArchitecture"
    .\signtool.exe sign /v /fd sha256 /f $CodeSigningCert /p $CodeSigningPass $AppPath