如何修复包支持框架文件系统写入权限错误
本文介绍如何使用包支持框架 (PSF) 解决文件系统写入权限错误。
Windows 应用会将与特定应用程序相关的目录重定向到 C:\Program Files\WindowsApps
文件夹。 如果应用程序尝试写入 Windows 应用容器,将触发错误,且写入失败。 你可以对 Windows 应用包进行增强来解决此问题。
调查
首先,识别失败以及应用请求的目录路径。
捕获 Windows 应用失败
筛选结果是可选的,但更易于查看与应用程序相关的失败。 要筛选结果,请创建两个筛选规则。 第一个筛选器包含应用程序进程名称,第二个筛选器包含不成功的任何结果。
下载 SysInternals Process Monitor 并将其提取到 C:\PSF\ProcessMonitor 目录。
打开 Windows 资源管理器并导航到提取的 SysInternals ProcessMonitor 文件夹。
选择 SysInternals Process Monitor procmon.exe 文件以启动应用。
如果 UAC 提示,请选择“是”。
在“进程监视器筛选器”窗口中,从第一个字段的下拉菜单中选择“进程名称”。
验证“是”显示在下一个字段中。
在下一个字段中,输入应用的进程名称,例如 PSFSample.exe。
选择添加。
在“进程监视器筛选器”窗口中,从第一个字段的下拉菜单中选择“结果”。
在下一个字段中,从下拉菜单中选择“不是”。
在文本字段中,输入 SUCCESS。
依次选择“添加”、“确定” 。
启动 Windows 应用,触发错误,然后关闭 Windows 应用。
查看 Windows 应用失败日志
捕获 Windows 应用进程后,调查结果以确定失败是否与工作目录相关。
查看 SysInternals Process Monitor 失败结果。 如果结果包括“访问被拒绝”,且显示“所需的访问地:泛型写入”详细信息,则针对定位 C:\Program Files\WindowsApps\...\ 的应用,你发现了与工作目录相关的写入权限失败。
如果识别此错误,请对你的应用程序应用以下 PSF 更正。
解决方法
要解决 Windows 应用无法写入 Windows 应用容器的问题,请执行以下步骤:
- 将 Windows 应用的内容提取到本地暂存目录。
- 创建 config.json 并注入 PSF 修复文件到暂存 Windows 应用目录。
- 将应用程序启动器配置为指向 PSF 启动器,并将 PSF config.json 文件配置为重定向 PSF 启动器,以指定工作目录。
- 更新 Windows 应用 AppxManifest 文件。
- 重新打包 Windows 应用并进行签名。
下载并安装所需的工具
此流程需要以下工具:
- NuGet 客户端工具
- 包支持框架 (PSF)
- Windows 10 软件开发工具包 (Win 10 SDK),最新版本
- SysInternals Process Monitor
下载并安装 NuGet 和 PSF:
下载 NuGet 客户端工具的最新非预览版本,并将 nuget.exe 保存在 C:\PSF\nuget 中。
通过“管理 PowerShell”窗口运行以下命令,使用 Nuget 下载并安装包支持框架:
Set-Location "C:\PSF" .\nuget\nuget.exe install Microsoft.PackageSupportFramework
下载并安装 Windows 10 SDK:
- 下载 Win 10 SDK。
- 运行 winsdksetup.exe。
- 选择下一步。
- 仅选择以下三项功能:
- 适用于桌面应用的 Windows SDK 签名工具
- 适用于 UWP C++ 应用的 Windows SDK
- 用于 UWP 应用本地化的 Windwos SDK
- 选择“安装”,然后选择“确定”。
暂存 Windows 应用
暂存 Windows 应用会将应用的内容提取并解压缩到本地目录。 将 Windows 应用解压缩到暂存位置后,可以注入 PSF 修复文件以更正任何不需要的体验。
在“管理 PowerShell”窗口中,设置以下变量以定位特定应用文件和 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
通过运行以下 PowerShell cmdlet 将 Windows 应用解压缩到暂存文件夹:
## 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.json 文件,并提供有关失败的 Windows 应用启动器的信息。 如果多个 Windows 应用启动器遇到问题,你可以使用多个条目配置 config.json 文件。
创建 config.json 文件后,将 config.json 文件和支持的 PSF 修复文件移动到 Windows 应用包的根目录中。
打开 Visual Studio Code 或其他文本编辑器。
在 Windows 应用暂存目录 C:\PSF\Staging\PSFSampleApp 中创建名为 config.json 的新文件。
将以下代码复制到新建的 config.json 文件中。
{ "applications": [ { "id": "", "executable": "" } ], "processes": [ { "executable": "", "fixups": [ { "dll": "", "config": { "redirectedPaths": { "packageRelative": [ { "base": "", "patterns": [ "" ] } ] } } } ] } ] }
在 Windows 应用暂存文件夹中打开 AppxManifest.xml 文件。 以下示例显示 AppxManifest.xml 文件:
<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>
在 config.json 文件中进行以下更改:
将
applications.id
值设置为与 AppxManifest.xml 文件的Applications.Application.ID
字段中的值相同的值。设置
applications.executable
值以定位位于 AppxManifest.xml 文件的Applications.Application.Executable
字段中的应用程序的相对路径。设置
applications.workingdirectory
值以定位位于 AppxManifest.xml 文件的Applications.Application.Executable
字段中的相对文件夹路径。在 AppxManifest.xml 文件的
process.executable
字段中设置Applications.Application.Executable
值以定位文件名(不带路径和扩展名)。设置
processes.fixups.dll
值以定位体系结构特定的FileRedirectionFixup.dll
。 如果更正适用于 x64 体系结构,请将该值设置为FileRedirectionFixup64.dll
。 如果体系结构为 x86 或未知,请将该值设置为FileRedirectionFixup86.dll
。将
processes.fixups.config.redirectedPaths.packageRelative.base
值设置为 AppxManifest.xml 文件的Applications.Application.Executable
字段中的包相对文件夹路径。设置
processes.fixups.config.redirectedPaths.packageRelative.patterns
值以匹配应用程序创建的文件类型。 如果你使用.*\\.log
,PSF 将重定向processes.fixups.config.redirectedPaths.packageRelative.base
目录和子目录中的所有日志文件写入。
保存已更新的 config.json 文件。 以下示例显示了更新的 config.json 文件:
{ "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" ] } ] } } } ] } ] }
将以下文件从应用程序可执行体系结构的包支持框架复制到暂存 Windows 应用的根目录。 可以在 .\Microsoft.PackageSupportFramework.\<Version>\bin 中找到这些文件。
应用程序 (x64) 应用程序 (x86) PSFLauncher64.exe PSFLauncher32.exe PSFRuntime64.dll PSFRuntime32.dll PSFRunDll64.exe PSFRunDll32.exe FileRedirectionFixup64.dll FileRedirectionFixup64.dll
更新 AppxManifest
创建和更新 config.json 文件后,为 config.json 中包含的每个 Windows 应用启动器更新 Windows 应用的 AppxManifest.xml 文件。 AppxManifestApplications
现在必须定位与应用程序体系结构关联的 PSFLauncher.exe。
- 在暂存 MSIX 应用文件夹 C:\PSF\Staging\PSFSampleApp 中打开 AppxManifest.xml。
- 使用以下代码更新 AppxManifest.xml:
<Package ...> ... <Applications> <Application Id="PSFSample" Executable="PSFLauncher32.exe" EntryPoint="Windows.FullTrustApplication"> ... </Application> </Applications> </Package>
重新打包应用程序
应用所有更正后,将 Windows 应用重新打包到 MSIX 中,并使用代码签名证书对其进行签名。
打开“管理 PowerShell”窗口。
设置以下变量:
$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
通过运行以下 PowerShell cmdlet 重新打包暂存文件夹中的 Windows 应用:
Set-Location "${env:ProgramFiles(x86)}\Windows Kits\10\Bin\$Win10SDKVersion\$OSArchitecture" .\makeappx.exe pack /p "$AppPath" /d "$StagingFolder"
通过运行以下 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
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈