如何修正套件支援架構檔案系統寫入許可權錯誤
本文說明如何使用套件支援架構 (PSF) 來解決檔案系統寫入許可權錯誤。
Windows 應用程式會將特定應用程式相關目錄重新導向至 C:\Program Files\WindowsApps
資料夾。 如果應用程式嘗試寫入 Windows 應用程式容器,就會觸發錯誤,且寫入失敗。 您可以對 Windows 應用程式套件進行增強功能,以解決此問題。
調查
首先,識別失敗,以及應用程式所要求的目錄路徑。
擷取 Windows 應用程式失敗
篩選結果是選擇性的,但可讓您更輕鬆地查看應用程式相關失敗。 若要篩選結果,您可以建立兩個篩選規則。 第一個篩選包含應用程式進程名稱,而第二個篩選包含任何未成功的結果。
將 SysInternals 行程監視器下載並解壓縮至 C:\PSF\ProcessMonitor 目錄。
開啟 Windows 檔案總管,並流覽至擷取的 SysInternals ProcessMonitor 資料夾。
選取 [SysInternals 行程監視器 ] procmon.exe 檔案來啟動應用程式。
如果 UAC 出現提示,請選取 [ 是]。
在 [ 行程監視器篩選] 視窗中,從第一個字段的下拉功能表中選取 [行程名稱 ]。
確認是否 出現在 下一個字段中。
在下一個字段中,輸入應用程式的進程名稱,例如 PSFSample.exe。
選取 [新增]。
在 [ 行程監視器篩選] 視窗中,從第一個字段的下拉功能表中選取 [結果 ]。
在下一個字段中,選取 不是 從下拉功能表中選取。
在文字欄位中,輸入 SUCCESS。
選取 [加入],然後選取 [確定]。
啟動 Windows 應用程式、觸發錯誤,然後關閉 Windows 應用程式。
檢閱 Windows 應用程式失敗記錄
擷取 Windows 應用程式進程之後,請調查結果,以判斷失敗是否與工作目錄有關。
檢閱 SysInternals 行程監視器失敗結果。 如果結果包含拒絕存取,且具有 Desired Access:Generic Write 詳細數據,則針對以 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 行程監視器
若要下載並安裝 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 簽署工具
- Windows SDK for UWP C++ Apps
- Windwos SDK for UWP Apps 當地語系化
- 選取 [ 安裝],然後選取 [ 確定]。
暫存 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 應用程式預備目錄中建立名為 config.json 的新檔案 C :\PSF\Staging\PSFSampleApp。
將下列程式代碼複製到新建立 的 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
值設定為與Applications.Application.ID
AppxManifest.xml 檔案欄位中的值相同。將
applications.executable
值設定為以位於Applications.Application.Executable
AppxManifest.xml 檔案欄位中的應用程式相對路徑為目標。將
applications.workingdirectory
值設定為以AppxManifest.xml檔案欄位中的相對資料夾路徑Applications.Application.Executable
為目標。在
process.executable
AppxManifest.xml檔案的欄位中,將值設定為以檔名為目標,而不使用路徑和擴展名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檔案。 Applications
AppxManifest.xml現在必須以與應用程式架構相關聯的PSFLauncher.exe為目標。
- 在暫存的 MSIX 應用程式資料夾中開啟AppxManifest.xml C:\PSF\Staging\PSFSampleApp。
- 使用下列程式代碼更新 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