パッケージ サポート フレームワーク ファイル システム書き込みアクセス許可エラーを修正する方法

この記事では、パッケージ サポート フレームワーク (PSF) を使用して、ファイル システム書き込みアクセス許可エラーを解決する方法について説明します。

Windows アプリは、特定のアプリケーション関連のディレクトリをフォルダーに C:\Program Files\WindowsApps リダイレクトします。 アプリケーションが Windows アプリ コンテナーに書き込もうとすると、エラーがトリガーされ、書き込みが失敗します。 この問題を解決するために、Windows アプリ パッケージの機能強化を行うことができます。

調査

まず、エラーと、アプリが要求しているディレクトリ パスを特定します。

Windows アプリのエラーをキャプチャする

結果のフィルター処理は省略可能ですが、アプリケーション関連のエラーを簡単に確認できます。 結果をフィルター処理するには、2 つのフィルター 規則を作成します。 最初のフィルターにはアプリケーション プロセス名が含まれており、2 番目のフィルターには成功しなかった結果が含まれます。

  1. SysInternals プロセス モニターをダウンロードし、C:\PSF\ProcessMonitor ディレクトリに抽出します。

  2. Windows エクスプローラーを開き、抽出した SysInternals ProcessMonitor フォルダーに移動します。

  3. SysInternals プロセス モニター procmon.exe ファイルを選択して、アプリを起動します。

  4. UAC でメッセージが表示されたら、[ はい] を選択します。

  5. [ プロセス モニター フィルター ] ウィンドウで、最初のフィールドのドロップダウン メニューから [ プロセス名 ] を選択します。

  6. が次のフィールドに表示されることを確認します。

  7. 次のフィールドに、アプリのプロセス名を入力します (例: PSFSample.exe)。

    アプリ名を含む [プロセス モニター フィルター] ウィンドウの例。

  8. [追加] を選択します。

  9. [ プロセス モニター フィルター ] ウィンドウで、最初のフィールドのドロップダウン メニューから [ 結果 ] を選択します。

  10. 次のフィールドで、 がドロップダウン メニューから 選択されていません

  11. テキスト フィールドに「SUCCESS」と入力 します

    [結果] を含む [プロセス モニター フィルター] ウィンドウの例。

  12. **[追加]****[OK]** の順に選択します。

  13. Windows アプリを起動し、エラーをトリガーして、Windows アプリを閉じます。

Windows アプリのエラー ログを確認する

Windows アプリ プロセスをキャプチャした後、結果を調査して、エラーが作業ディレクトリに関連しているかどうかを判断します。

SysInternals プロセス モニターのエラー結果を確認します。 C:\Program Files\WindowsApps\...\を対象とするアプリに対して[アクセス拒否]、[Desired Access: Generic Write detail]\(必要なアクセス: 汎用書き込み詳細\) が結果に含まれている場合は、作業ディレクトリに関連する書き込みアクセス許可エラーが特定されました。

SysInternals プロセス モニターで、ディレクトリへの書き込みに失敗した場合に監視されるエラー メッセージを表示します。

このエラーが特定された場合は、次の PSF 修正をアプリに適用します。

解決方法

Windows アプリが Windows アプリ コンテナーへの書き込みに失敗する問題を解決するには、次の手順に従います。

  1. Windows アプリのコンテンツを ローカルのステージング ディレクトリに抽出します。
  2. config.json を作成し、PSF fixup ファイル をステージングされた Windows アプリ ディレクトリに挿入します。
  3. PSF ランチャーを指すアプリケーション起動ツールを構成し、PSF ランチャーをリダイレクトするように PSF config.json ファイルを構成し、作業ディレクトリを指定します。
  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. 次の 3 つの機能のみを選択します。
    • デスクトップ アプリ用 Windows SDK 署名ツール
    • UWP C++ アプリ用 Windows SDK
    • UWP アプリのローカライズ用 Windows SDK
  5. [ インストール] を選択し、[ OK] を選択します

Windows アプリをステージングする

Windows アプリをステージングすると、アプリの内容が抽出され、ローカル ディレクトリにパッケージ化解除されます。 Windows アプリがステージングの場所に展開されたら、PSF fixup ファイルを挿入して不要なエクスペリエンスを修正できます。

  1. 管理 PowerShell ウィンドウで、特定のアプリ ファイルと SDK バージョンを対象Windows 10次の変数を設定します。

    $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 コマンドレットを実行して、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 アプリを修正するには、失敗した Windows アプリ起動ツールに関する情報を含む config.json ファイルを作成します。 複数の Windows アプリ起動ツールで問題が発生している場合は、複数のエントリで config.json ファイルを構成できます。

config.json ファイルを作成したら、config.json とサポートされている PSF fixup ファイルを Windows アプリ パッケージのルートに移動します。

  1. Visual Studio Code または別のテキスト エディターを開きます。

  2. Windows アプリのステージング ディレクトリ C:\PSF\Staging\PSFSampleAppconfig.json という名前の新しいファイルを作成します。

  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.idAppxManifest.xml ファイルの フィールドとApplications.Application.ID同じ値に設定します。

      AppxManifest ファイル内の ID の場所を示す画像。

    • applications.executableAppxManifest.xml ファイルのフィールドにあるアプリケーションへの相対パスをApplications.Application.Executableターゲットにする値を設定します。

      *AppxManifest.xml* ファイル内の実行可能ファイルの場所を示す画像。

    • applications.workingdirectoryAppxManifest.xmlファイルのフィールド内の相対フォルダー パスをApplications.Application.Executableターゲットにする値設定します。

      AppxManifest ファイル内の作業ディレクトリの場所を示す画像。

    • process.executableAppxManifest.xmlファイルのフィールドで、パスと拡張子を指定せずにファイル名Applications.Application.Executableターゲットにするように値を設定します。

      AppxManifest ファイル内のプロセス実行可能ファイルの場所を示す画像。

    • 値を processes.fixups.dll 設定して、アーキテクチャ固有 FileRedirectionFixup.dllの をターゲットにします。 修正が x64 アーキテクチャの場合は、値を に FileRedirectionFixup64.dll設定します。 アーキテクチャが x86 の場合、または不明な場合は、値を に FileRedirectionFixup86.dll設定します。

    • 値を、processes.fixups.config.redirectedPaths.packageRelative.baseAppxManifest.xml ファイルのフィールドのApplications.Application.Executableパッケージ相対フォルダー パスに設定します。

      AppxManifest ファイル内の作業ディレクトリの場所を示す画像。

    • アプリケーションが作成する 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 アプリ フォルダー C:\PSF\Staging\PSFSampleApp でAppxManifest.xmlを開きます。
  2. のコードを使用して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 コマンドレットを実行して、ステージング フォルダーから Windows アプリを再パックします。

    Set-Location "${env:ProgramFiles(x86)}\Windows Kits\10\Bin\$Win10SDKVersion\$OSArchitecture"
    .\makeappx.exe pack /p "$AppPath" /d "$StagingFolder"
    
  4. 次の PowerShell コマンドレットを実行して、Windows アプリに署名します。

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