如何修正套件支援架構檔案系統寫入許可權錯誤

本文說明如何使用套件支援架構 (PSF) 來解決檔案系統寫入許可權錯誤。

Windows 應用程式會將特定應用程式相關目錄重新導向至 C:\Program Files\WindowsApps 資料夾。 如果應用程式嘗試寫入 Windows 應用程式容器,就會觸發錯誤,且寫入失敗。 您可以對 Windows 應用程式套件進行增強功能,以解決此問題。

調查

首先,識別失敗,以及應用程式所要求的目錄路徑。

擷取 Windows 應用程式失敗

篩選結果是選擇性的,但可讓您更輕鬆地查看應用程式相關失敗。 若要篩選結果,您可以建立兩個篩選規則。 第一個篩選包含應用程式進程名稱,而第二個篩選包含任何未成功的結果。

  1. 將 SysInternals 行程監視器下載並解壓縮C:\PSF\ProcessMonitor 目錄。

  2. 開啟 Windows 檔案總管,並流覽至擷取的 SysInternals ProcessMonitor 資料夾。

  3. 選取 SysInternals Process Monitor procmon.exe 檔案以啟動應用程式。

  4. 如果 UAC 出現提示,請選取 [ ]。

  5. 在 [ 行程監視器篩選] 視窗中,從第一個字段的下拉功能表中選取 [行程名稱 ]。

  6. 確認是否 出現在 下一個字段中。

  7. 在下一個字段中,輸入應用程式的進程名稱,例如 PSFSample.exe

    Example of the Process Monitor Filter window with app name.

  8. 選取新增

  9. 在 [ 行程監視器篩選] 視窗中,從第一個字段的下拉功能表中選取 [結果 ]。

  10. 在下一個字段中,選取 不是 從下拉功能表中選取。

  11. 在文字欄位中,輸入 SUCCESS

    Example of the Process Monitor Filter window with Result.

  12. 選取 [加入],然後選取 [確定]

  13. 啟動 Windows 應用程式、觸發錯誤,然後關閉 Windows 應用程式。

檢閱 Windows 應用程式失敗記錄

擷取 Windows 應用程式進程之後,請調查結果,以判斷失敗是否與工作目錄有關。

檢閱 SysInternals 行程監視器失敗結果。 如果結果包含拒絕存取,且具有 Desired Access:Generic Write 詳細數據,則針對以 C:\Program Files\WindowsApps\...\ 為目標的應用程式,您發現與工作目錄相關的寫入許可權失敗。

Displays the error message witnessed in the SysInternals Process Monitor for failure to write to directory.

如果您識別此錯誤,請將下列 PSF 更正套用至您的應用程式。

解決方法

若要解決 Windows 應用程式無法寫入 Windows 應用程式容器的問題,請遵循下列步驟:

  1. 將 Windows 應用程式的內容解壓縮到本機 預備目錄
  2. 建立 config.json,並將 PSF 修正檔案 插入暫存的 Windows 應用程式目錄中。
  3. 將應用程式啟動器設定為指向 PSF 啟動器,並將 PSF config.json 檔案設定為重新導向 PSF 啟動器,並指定工作目錄。
  4. 更新 Windows 應用程式 AppxManifest 檔案
  5. 重新封裝並簽署 Windows 應用程式

下載並安裝必要的工具

此程式需要下列工具:

  • NuGet 用戶端工具
  • 套件支援架構 (PSF)
  • Windows 10 軟體開發工具組 (Win 10 SDK), 最新版本
  • SysInternals 行程監視器

若要下載並安裝 NuGet 和 PSF:

  1. 下載 NuGet 用戶端工具的最新非預覽版本,並將 nuget.exe 儲存C:\PSF\nuget 中。

  2. 從系統管理 PowerShell 視窗執行下列命令,以使用 NuGet 下載並安裝套件支援架構:

    Set-Location "C:\PSF"
    .\nuget\nuget.exe install Microsoft.PackageSupportFramework
    

若要下載並安裝 Windows 10 SDK:

  1. 下載 Win 10 SDK
  2. 執行 winsdksetup.exe
  3. 選取 [下一步] 。
  4. 只選取下列三個功能:
    • 適用於傳統型應用程式的 Windows SDK 簽署工具
    • 適用於UWP C++ 應用程式的 Windows SDK
    • Windwos SDK for UWP Apps 當地語系化
  5. 選取 [ 安裝],然後選取 [ 確定]。

暫存 Windows 應用程式

暫存 Windows 應用程式會將應用程式的內容解壓縮並解壓縮到本機目錄。 將 Windows 應用程式解壓縮到預備位置之後,您可以插入 PSF 修正檔案,以更正任何不必要的體驗。

  1. 在系統管理 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
    
  2. 執行下列 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 應用程式套件的根目錄。

  1. 開啟 Visual Studio Code 或其他文字編輯器。

  2. 在 Windows 應用程式預備目錄中建立名為 config.json 的新檔案 C :\PSF\Staging\PSFSampleApp

  3. 將下列程式代碼複製到新建立 的 config.json 檔案。

    {
        "applications": [
            {
                "id": "",
                "executable": ""
            }
        ],
        "processes": [
            {
                "executable": "",
                "fixups": [
                {
                    "dll": "",
                    "config": {
                        "redirectedPaths": {
                            "packageRelative": [
                                {
                                    "base": "",
                                    "patterns": [
                                        ""
                                    ]
                                }
                            ]
                        }
                    }
                }
            ]
            }
        ]
    }
    
  4. 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>
    
  5. 在 config.json 檔案中進行下列變更:

    • applications.id值設定為與 AppxManifest.xml 檔案欄位中的值相同Applications.Application.ID

      Image showing the location of the ID within the AppxManifest file.

    • applications.executable值設定為以位於 AppxManifest.xml 檔案欄位中之應用程式的Applications.Application.Executable相對路徑為目標。

      Image showing the location of the executable within the *AppxManifest.xml* file.

    • applications.workingdirectory值設定為以 AppxManifest.xml 檔案欄位中的相對資料夾路徑Applications.Application.Executable為目標。

      Image showing the location of the working directory within the AppxManifest file.

    • process.executable AppxManifest.xml 檔案的欄位中,將值設定為以檔名為目標,不含路徑和擴展名Applications.Application.Executable

      Image showing the location of the process executable within the AppxManifest file.

    • processes.fixups.dll 值設定為以架構特定的 FileRedirectionFixup.dll為目標。 如果更正適用於 x64 架構,請將值設定為 FileRedirectionFixup64.dll。 如果架構為 x86 或未知,請將值設定為 FileRedirectionFixup86.dll

    • processes.fixups.config.redirectedPaths.packageRelative.base值設定為 AppxManifest.xml 檔案欄位中的套件相對資料夾路徑Applications.Application.Executable

      Image showing the location of the working directory within the AppxManifest file.

    • processes.fixups.config.redirectedPaths.packageRelative.patterns設定值以符合應用程式建立的檔案類型。 如果您使用 .*\\.log,PSF 會重新導向目錄和子目錄中寫入的所有記錄檔 processes.fixups.config.redirectedPaths.packageRelative.base

  6. 儲存更新 後的 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"
                                        ]
                                    }
                                ]
                            }
                        }
                    }
                ]
            }
        ]
    }
    
  7. 將下列檔案從應用程式可執行檔案架構的套件支援架構複製到分段 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 檔案。 AppxManifest.xmlApplications 現在必須以與應用程式架構相關聯的 PSFLauncher.exe 為目標

  1. 在暫存的 MSIX 應用程式資料夾中,開啟 AppxManifest.xml,C:\PSF\Staging\PSFSampleApp
  2. 使用下列程式代碼更新 AppxManifest.xml
    <Package ...>
    ...
    <Applications>
        <Application Id="PSFSample"
                    Executable="PSFLauncher32.exe"
                    EntryPoint="Windows.FullTrustApplication">
        ...
        </Application>
    </Applications>
    </Package>
    

重新封裝應用程式

套用所有更正之後,請將 Windows 應用程式重新封裝到 MSIX,並使用程式代碼簽署憑證簽署它。

  1. 開啟 管理員 istrative 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