はじめに サポート フレームワークの使用

パッケージ サポート フレームワーク は、MSIX コンテナーで実行できるよう、(コードを変更せずに) 既存のデスクトップ アプリケーションに修正プログラムを適用するのに役立つオープン ソース キットです。 パッケージ サポート フレームワークは、アプリケーションで最新のランタイム環境のベスト プラクティスに従うのに役立ちます。

この記事では、パッケージ サポート フレームワークの各コンポーネントを実際に確認し、それを使用するステップ バイ ステップ ガイドを示します。

パッケージ サポート フレームワーク内の情報を理解する

パッケージ サポート フレームワークには、実行可能ファイル、ランタイム マネージャー DLL、およびランタイム修正プログラムのセットが含まれます。

パッケージ サポート フレームワーク

プロセスを次に示します。

  1. アプリケーションに適用する修正プログラムを指定する構成ファイルを作成します。
  2. パッケージ サポート フレームワーク (PSF) ランチャー実行可能ファイルを指すパッケージを変更します。

ユーザーがアプリケーションを起動すると、パッケージ サポート フレームワーク ランチャーが最初に実行される実行可能ファイルになります。 ランチャーによって構成ファイルが読み取られ、ランタイム修正プログラムとランタイム マネージャー DLL がアプリケーション プロセスに挿入されます。 ランタイム マネージャーは、MSIX、コンテナー内で実行するアプリケーションで必要になったときに修正プログラムを適用します。

パッケージ サポート フレームワークによる DLL の挿入

手順 1: パッケージ化されたアプリケーションの互換性の問題を特定する

まず、アプリケーションのパッケージを作成します。 次に、インストールして実行し、その動作を確認します。 互換性に関する問題の特定に役立つエラー メッセージが表示されることがあります。 プロセス モニターを使用して問題を識別することもできます。 一般的な問題は、作業ディレクトリとプログラム パスのアクセス許可に関するアプリケーションの前提条件に関連しています。

プロセス モニターを使用して問題を特定する

プロセス モニター は、アプリのファイルとレジストリの操作とその結果を監視する強力なユーティリティです。 これは、アプリケーションの互換性の問題を理解するのに役立ちます。 プロセス モニターを開いて、アプリケーション実行可能ファイルからのイベントのみを含>フィルター (Filter > Filter...) を追加します。

ProcMon アプリ フィルター

イベントの一覧が表示されます。 これらのイベントの多くでは 、SUCCESS という単語が [結果] 列 に表示 されます。

ProcMon イベント

必要に応じて、イベントをフィルター処理してエラーのみを表示できます。

ProcMon Exclude Success

ファイル システム アクセスエラーが疑われる場合は、System32/SysWOW64 またはパッケージ ファイル パスの下にある失敗したイベントを検索します。 フィルターは、ここでも役立ちます。 この一覧の下部から開始し、上にスクロールします。 この一覧の下部に表示されるエラーは、最近発生しました。 "アクセス拒否" や "path/name not found" などの文字列を含むエラーに最も注意し、疑わしいとは思わないものを無視します。 PSFSample には 2つの問題があります。 これらの問題は、次の図に示す一覧で確認できます。

ProcMon Config.txt

このイメージに表示される最初の問題では、アプリケーションは "C:\Windows\SysWOW64" パスにある "Config.txt" ファイルからの読み取りに失敗しています。 アプリケーションがパスを直接参照しようとしている可能性は低い。 ほとんどの場合、相対パスを使用してそのファイルから読み取ろうとしています。既定では、"System32/SysWOW64" はアプリケーションの作業ディレクトリです。 これは、アプリケーションが現在の作業ディレクトリをパッケージ内のどこかに設定する必要を示しています。 appx の内部を見て、ファイルが実行可能ファイルと同じディレクトリに存在しているのを確認できます。

アプリConfig.txt

次の図に 2 番目の問題が表示されます。

ProcMon Logfile

この問題では、アプリケーションがパッケージ パスに .log ファイルを書き込めない。 これは、ファイル リダイレクトの修正が役立つ可能性を示唆しています。

手順 2: ランタイム修正プログラムを見つける

PSF には、ファイル リダイレクトの修正など、今すぐ使用できるランタイム修正が含まれている。

ファイル リダイレクトの修正

ファイル リダイレクト修正を使用すると、MSIX コンテナーで実行されているアプリケーションからアクセスできないディレクトリ内のデータの書き込みまたは読み取りをリダイレクトできます。

たとえば、アプリケーションがアプリケーション実行可能ファイルと同じディレクトリにあるログ ファイルに書き込む場合は、ファイル リダイレクト修正を使用して、ローカル アプリ データ ストアなどの別の場所にログ ファイルを作成できます。

コミュニティからのランタイム修正

このページでは、コミュニティの投稿を必GitHubしてください。 他の開発者が、自分と同様の問題を解決し、ランタイム修正を共有している可能性があります。

手順 3: ランタイム修正プログラムを適用する

既存のランタイム修正プログラムは、Windows SDK の簡単なツールを使用して適用できます。次の手順に従います。

  • パッケージ レイアウト フォルダーを作成する
  • パッケージ サポート フレームワーク ファイルを取得する
  • パッケージに追加する
  • パッケージ マニフェストの変更
  • 構成ファイルを作成する

各タスクについて説明します。

パッケージ レイアウト フォルダーを作成する

.msix (または .appx) ファイルが既にある場合は、パッケージのステージング領域として機能するレイアウト フォルダーにコンテンツをアンパックできます。 これは、SDK のインストール パスに基づいて MakeAppx ツールを使用してコマンド プロンプトから行うことができます。ここで、Windows 10 PC に makeappx.exe ツールが表示されます: x86: C:\Program Files (x86)\Windows Kits\10\bin\x86\makeappx.exe x64: C:\Program Files (x86)\Windows Kits\10\bin\x64\makeappx.exe

makeappx unpack /p PSFSamplePackage_1.0.60.0_AnyCPU_Debug.msix /d PackageContents

これにより、次のようになります。

パッケージ レイアウト

最初に .msix (または .appx) ファイルが存在しない場合は、パッケージ フォルダーとファイルを最初から作成できます。

パッケージ サポート フレームワーク ファイルを取得する

PSF Nuget パッケージを取得するには、スタンドアロンの Nuget コマンド ライン ツールを使用するか、次のコマンド を使用Visual Studio。

コマンド ライン ツールを使用してパッケージを取得する

Nuget コマンド ライン ツールを次の場所からインストールします https://www.nuget.org/downloads 。 次に、Nuget コマンド ラインから次のコマンドを実行します。

nuget install Microsoft.PackageSupportFramework

または、パッケージ拡張機能の名前をに変更して.zip解凍することもできます。 必要なすべてのファイルは、/bin フォルダーの下にあります。

次のコマンドを使用してパッケージを取得Visual Studio

このVisual Studioソリューションまたはプロジェクト ノードを右クリックし、 [Nuget パッケージの管理] コマンドのいずれかを選択します。 Microsoft.PackageSupportFramework または PSF を検索して、パッケージを Nuget.org。次に、インストールします。

パッケージ サポート フレームワーク ファイルをパッケージに追加する

必要な 32 ビットおよび 64 ビットの PSF DLL と実行可能ファイルをパッケージ ディレクトリに追加します。 次の表をガイドとして使用してください。 必要なランタイム修正も含める必要があります。 この例では、ファイル リダイレクト ランタイムの修正が必要です。

アプリケーション実行可能ファイルは x64 アプリケーション実行可能ファイルは x86
PSFLauncher64.exe PSFLauncher32.exe
PSFRuntime64.dll PSFRuntime32.dll
PSFRunDll64.exe PSFRunDll32.exe

これで、パッケージのコンテンツは次のように表示されます。

パッケージ バイナリ

パッケージ マニフェストの変更

テキスト エディターでパッケージ マニフェストを開き、 要素の 属性を実行可能ファイルの PSF ファイルの名前 Executable Application 起動ツールします。 ターゲット アプリケーションのアーキテクチャがわかっている場合は、適切なバージョンを選択し、PSFLauncher32.exeまたはPSFLauncher64.exe。 そうしない場合、PSFLauncher32.exe場合でも機能します。 次に例を示します。

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

構成ファイルを作成する

ファイル名 を作成 config.json し、そのファイルをパッケージのルート フォルダーに保存します。 置き換えた実行可能ファイルconfig.jsを指す、ファイルの宣言されたアプリ ID を変更します。 プロセス モニターを使用して得た知識を使用して、作業ディレクトリを設定し、ファイル リダイレクトの修正を使用して、パッケージ相対の "PSFSampleApp" ディレクトリにある .log ファイルに読み取り/書き込みをリダイレクトすることもできます。

{
    "applications": [
        {
            "id": "PSFSample",
            "executable": "PSFSampleApp/PSFSample.exe",
            "workingDirectory": "PSFSampleApp/"
        }
    ],
    "processes": [
        {
            "executable": "PSFSample",
            "fixups": [
                {
                    "dll": "FileRedirectionFixup.dll",
                    "config": {
                        "redirectedPaths": {
                            "packageRelative": [
                                {
                                    "base": "PSFSampleApp/",
                                    "patterns": [
                                        ".*\\.log"
                                    ]
                                }
                            ]
                        }
                    }
                }
            ]
        }
    ]
}

スキーマに関するドキュメントのconfig.jsを次に示します。

Array key
applications id パッケージ マニフェスト内の Id 要素の 属性 Application の値を使用します。
applications executable 開始する実行可能ファイルへのパッケージ相対パス。 ほとんどの場合、変更する前にパッケージ マニフェスト ファイルからこの値を取得できます。 これは、 要素の 属性 Executable の値 Application です。
applications workingDirectory (省略可能)開始するアプリケーションの作業ディレクトリとして使用するパッケージ相対パス。 この値を設定しない場合、オペレーティング システムはアプリケーションの作業 System32 ディレクトリとして ディレクトリを使用します。
プロセス executable ほとんどの場合、パスとファイル拡張子が削除された上で構成された の executable 名前になります。
修正プログラム dll 修正プログラムへのパッケージ相対パス。読み込む .msix/.appx。
修正プログラム config (省略可能)修正プログラム dll の動作を制御します。 この値の正確な形式は、修正ごとに異なります。各修正プログラムは、この "BLOB" を必要なとおりに解釈できます。

applications、、 processes および キー fixups は配列です。 つまり、config.json ファイルを使用して、複数のアプリケーション、プロセス、および修正 DLL を指定できます。

アプリをパッケージ化してテストする

次に、パッケージを作成します。

makeappx pack /d PackageContents /p PSFSamplePackageFixup.msix

次に、署名します。

signtool sign /a /v /fd sha256 /f ExportedSigningCertificate.pfx PSFSamplePackageFixup.msix

詳細については、パッケージ署名 証明書を作成する方法 と、signtool を使用してパッケージに署名 する方法に関するページを参照してください。

PowerShell を使用して、パッケージをインストールします。

注意

最初にパッケージをアンインストールしてください。

powershell Add-AppPackage .\PSFSamplePackageFixup.msix

アプリケーションを実行し、ランタイム修正が適用された動作を確認します。 必要に応じて、診断とパッケージ化の手順を繰り返します。

パッケージ サポート フレームワークが実行されているかどうかを確認する

ランタイム修正プログラムが実行されているかどうかを確認できます。 これを行う方法は、アプリケーションを 開タスク マネージャー詳細 ] をクリックします。 パッケージ サポート フレームワークが適用されたアプリを見つけ、アプリの詳細を展開して詳細を表示します。 パッケージ サポート フレームワークが実行されているのを確認できます。

トレース修正の使用

パッケージ化されたアプリケーションの互換性の問題を診断する別の手法は、トレースの修正を使用する方法です。 この DLL は PSF に含まれており、プロセス モニターと同様に、アプリの動作の詳細な診断ビューを提供します。 これは、アプリケーションの互換性の問題を明らかにするために特別に設計されています。 トレース修正を使用するには、DLL をパッケージに追加し、次のフラグメントを config.json に追加してから、アプリケーションをパッケージ化してインストールします。

{
    "dll": "TraceFixup.dll",
    "config": {
        "traceLevels": {
            "filesystem": "allFailures"
        }
    }
}

既定では、トレースの修正では、"予期される" と見なされる可能性があるエラーがフィルター処理されます。 たとえば、アプリケーションは、結果を無視して、ファイルが既に存在するかどうかを確認せずに、無条件にファイルを削除しようとする場合があります。 これにより、予期しないエラーがフィルター処理される可能性があるという残念な結果が生じるので、上記の例では、ファイルシステム関数からすべてのエラーを受信することを選択します。 これは、Config.txt ファイルからの読み取りが失敗し、"ファイルが見つかりません" というメッセージが表示される前からわかっているためです。 これは頻繁に観察される障害であり、通常は予期しないと見なされません。 実際には、予期しないエラーにのみフィルター処理を開始し、まだ特定できない問題がある場合は、すべてのエラーに戻すのが最善の方法です。

既定では、トレース修正からの出力は、アタッチされたデバッガーに送信されます。 この例では、デバッガーをアタッチするのではなく、SysInternals の DebugView プログラムを使用して出力を表示します。 アプリを実行すると、以前と同じエラーが表示され、同じランタイム修正が示されます。

TraceShim ファイルが見つかりません

TraceShim アクセスが拒否されました

ランタイム修正のデバッグ、拡張、または作成

Visual Studioを使用して、ランタイム修正のデバッグ、ランタイム修正の拡張、またはゼロからの作成を行います。 成功するには、これらのことを行う必要があります。

  • パッケージ プロジェクトを追加する
  • ランタイム修正用のプロジェクトを追加する
  • PSF ファイルを起動するプロジェクトを起動ツールする
  • パッケージ プロジェクトを構成する

完了すると、ソリューションは次のように表示されます。

完成したソリューション

この例では、各プロジェクトを見てみしましょう。

Project 目的
DesktopApplicationPackage このプロジェクトは、アプリケーション パッケージ プロジェクトWindows基づいており、MSIX パッケージが出力されます。
Runtimefix これは、ランタイム修正としてDynamic-Linked 1 つ以上の置換関数を含む C++ ライブラリ プロジェクトです。
PSFLauncher これは C++ の空のProject。 このプロジェクトは、パッケージ サポート フレームワークのランタイムの配布可能ファイルを収集する場所です。 実行可能ファイルが出力されます。 その実行可能ファイルは、ソリューションを起動するときに最初に実行されます。
WinFormsDesktopApplication このプロジェクトには、デスクトップ アプリケーションのソース コードが含まれている。

これらのすべての種類のプロジェクトを含む完全なサンプルを確認するには 、「PSFSample 」を参照してください

ソリューション内でこれらの各プロジェクトを作成して構成する手順について説明します。

パッケージ ソリューションを作成する

デスクトップ アプリケーション用のソリューションをまだお持ちない場合は、新しい空のソリューションを Visual Studio。

空のソリューション

また、アプリケーション プロジェクトを追加する必要がある場合があります。

パッケージ プロジェクトを追加する

アプリケーション パッケージのアプリケーション パッケージをまだWindows場合 Project作成し、ソリューションに追加します。

パッケージ プロジェクト テンプレート

アプリケーション パッケージ プロジェクトの詳細Windowsを使用したアプリケーションのパッケージ化に関するページVisual Studio。

ソリューション エクスプローラー プロジェクトを右クリックし、 [編集] を選択して、プロジェクト ファイルの一番下に追加します。

<Target Name="PSFRemoveSourceProject" AfterTargets="ExpandProjectReferences" BeforeTargets="_ConvertItems">
<ItemGroup>
  <FilteredNonWapProjProjectOutput Include="@(_FilteredNonWapProjProjectOutput)">
  <SourceProject Condition="'%(_FilteredNonWapProjProjectOutput.SourceProject)'=='<your runtime fix project name goes here>'" />
  </FilteredNonWapProjProjectOutput>
  <_FilteredNonWapProjProjectOutput Remove="@(_FilteredNonWapProjProjectOutput)" />
  <_FilteredNonWapProjProjectOutput Include="@(FilteredNonWapProjProjectOutput)" />
</ItemGroup>
</Target>

ランタイム修正用のプロジェクトを追加する

C++ ダイナミック リンク ライブラリ (DLL) プロジェクトをソリューション に追加します。

ランタイム修正ライブラリ

そのプロジェクトを右クリックし、 [プロパティ] を 選択します

プロパティ ページで 、C++ 言語 標準フィールドを探し、そのフィールドの横にあるドロップダウン リストで 、ISO C++17 標準 (/std:c++17) オプションを選択します。

ISO 17 オプション

そのプロジェクトを右クリックし、コンテキスト メニューの [Nuget パッケージの管理] オプションを選択 します。 [パッケージ ソース ] オプションが [ すべて] または [パッケージ]に設定 nuget.org。

そのフィールドの横にある設定アイコンをクリックします。

PSF* Nuget パッケージを検索し、このプロジェクト用にインストールします。

nuget パッケージ

既存のランタイム修正プログラムをデバッグまたは拡張する場合は、このガイドの「ランタイム修正プログラムの検索」セクションで説明されているガイダンスを使用して取得したランタイム修正ファイルを追加します。

新しい修正プログラムを作成する場合は、このプロジェクトにはまだ何も追加しないでください。 このガイドの後半で、このプロジェクトに適切なファイルを追加する方法について説明します。 ここで、ソリューションの設定を続行します。

PSF ファイルを起動するプロジェクトを起動ツールする

ソリューションに C++の空Project プロジェクトを追加します。

空のプロジェクト

前の セクションで説明 したのと同じガイダンスを使用して、PSF Nuget パッケージをこのプロジェクトに追加します。

プロジェクトのプロパティ ページを開き、 [全般設定] ページで、アプリケーションのアーキテクチャに応じて、 [ターゲット名] プロパティを または PSFLauncher32 PSFLauncher64 に設定します。

PSF 起動ツール リファレンス

ソリューションのランタイム修正プロジェクトへのプロジェクト参照を追加します。

ランタイム修正リファレンス

参照を右クリックし、[プロパティ] ウィンドウで これらの値を適用します。

プロパティ
ローカルコピー
ローカル サテライト アセンブリにコピー
参照アセンブリの出力
ライブラリ依存関係のリンク 誤り
リンク ライブラリの依存関係の入力 誤り

パッケージ プロジェクトを構成する

パッケージ プロジェクトで、[アプリケーション] フォルダーを右クリックして [参照の追加] を選びます。

プロジェクト参照の追加

PSF 起動ツールプロジェクトとデスクトップ アプリケーション プロジェクトを選択し 、[OK] ボタンを選択 します。

デスクトップ プロジェクト

注意

アプリケーションのソース コードを持ってない場合は、PSF プロジェクトを選択起動ツールしてください。 構成ファイルを作成するときに実行可能ファイルを参照する方法について説明します。

[アプリケーション ] ノードで、PSF アプリケーションを右クリック起動ツールして、[エントリ ポイントに設定]を選択します

エントリ ポイントの設定

という名前のファイルをパッケージ プロジェクトに追加し、次の json テキストをコピー config.json してファイルに貼り付けます。 [パッケージ アクション ] プロパティを [ コンテンツ] に 設定します

{
    "applications": [
        {
            "id": "",
            "executable": "",
            "workingDirectory": ""
        }
    ],
    "processes": [
        {
            "executable": "",
            "fixups": [
                {
                    "dll": "",
                    "config": {
                    }
                }
            ]
        }
    ]
}

各キーの値を指定します。 次の表を参考にしてください。

Array key
applications id パッケージ マニフェスト内の Id 要素の 属性 Application の値を使用します。
applications executable 開始する実行可能ファイルへのパッケージ相対パス。 ほとんどの場合、変更する前にパッケージ マニフェスト ファイルからこの値を取得できます。 これは、 要素の 属性 Executable の値 Application です。
applications workingDirectory (省略可能)開始するアプリケーションの作業ディレクトリとして使用するパッケージ相対パス。 この値を設定しない場合、オペレーティング システムはアプリケーションの作業 System32 ディレクトリとして ディレクトリを使用します。
プロセス executable ほとんどの場合、パスとファイル拡張子が削除された上で構成された の executable 名前になります。
修正プログラム dll 読み込む修正プログラム DLL へのパッケージ相対パス。
修正プログラム config (省略可能)修正 DLL の動作を制御します。 この値の正確な形式は、修正ごとに異なります。各修正プログラムは、この "BLOB" を必要なとおりに解釈できます。

完了すると、ファイル config.json は次のように表示されます。

{
  "applications": [
    {
      "id": "DesktopApplication",
      "executable": "DesktopApplication/WinFormsDesktopApplication.exe",
      "workingDirectory": "WinFormsDesktopApplication"
    }
  ],
  "processes": [
    {
      "executable": ".*App.*",
      "fixups": [ { "dll": "RuntimeFix.dll" } ]
    }
  ]
}

注意

applications、、 processes および キー fixups は配列です。 つまり、config.json ファイルを使用して、複数のアプリケーション、プロセス、および修正 DLL を指定できます。

ランタイム修正をデバッグする

このVisual Studio F5 キーを押してデバッガーを起動します。 最初に始めるのは、PSF 起動ツールアプリケーションです。次に、ターゲット デスクトップ アプリケーションが起動されます。 ターゲット デスクトップ アプリケーションをデバッグするには、[デバッグ] ->[プロセスにアタッチ] を選択 し、アプリケーション プロセスを選択して、デスクトップ アプリケーション プロセスに手動でアタッチする必要があります。 ネイティブ ランタイム修正 DLL を使用した .NET アプリケーションのデバッグを許可するには、マネージド コードの種類とネイティブ コードの種類 (混合モードのデバッグ) を選択します。

これを設定したら、デスクトップ アプリケーション コードとランタイム修正プロジェクトのコード行の横にブレーク ポイントを設定できます。 アプリケーションのソース コードを使用しない場合は、ランタイム修正プロジェクトのコード行の横にのみブレーク ポイントを設定できます。

F5 デバッグでは、.msix/.appx パッケージからインストールするのではなく、パッケージ レイアウト フォルダー パスから Loose ファイルをデプロイすることでアプリケーションが実行されます。そのため、レイアウト フォルダーには、通常、インストールされているパッケージ フォルダーと同じセキュリティ制限はありません。 その結果、ランタイム修正を適用する前に、パッケージ パスのアクセス拒否エラーを再現できない可能性があります。

この問題に対処するには、F5 Loose ファイルの展開ではなく、.msix / .appx パッケージの展開を使用します。 .msix / .appx パッケージ ファイルを作成するには、前述のように、Windows SDK のMakeAppxユーティリティを使用します。 または、アプリケーション プロジェクト ノードVisual Studio右クリックし、[ストア] -> [アプリ パッケージの作成] を 選択します

この問題のVisual Studio、デバッガーによって起動された子プロセスにアタッチするサポートが組み込けられていないという問題です。 これにより、ターゲット アプリケーションのスタートアップ パスでロジックをデバッグするのが難しくなります。これは、起動後にアプリケーションによって手動Visual Studio必要があります。

この問題に対処するには、子プロセスのアタッチをサポートするデバッガーを使用します。 通常、Just-In-Time (JIT) デバッガーをターゲット アプリケーションにアタッチできません。 これは、ほとんどの JIT 手法では、ImageFileExecutionOptions レジストリ キーを使用して、ターゲット アプリの代わりのデバッガーを起動する必要があるためです。 これにより、ターゲット アプリにデータを挿入PSFLauncher.exeにFixupRuntime.dllが使用される迂回メカニズムが使用されます。 のデバッグ ツールに含まれており、Windows SDK から取得したWinDbgは、子プロセスのアタッチWindowsをサポートします。 また、UWP アプリ の直接起動とデバッグもサポートされています

ターゲット アプリケーションの起動を子プロセスとしてデバッグするには、 を開始します WinDbg

windbg.exe -plmPackage PSFSampleWithFixup_1.0.59.0_x86__7s220nvg1hg3m -plmApp PSFSample

プロンプトで WinDbg 子デバッグを有効にし、適切なブレークポイントを設定します。

.childdbg 1
g

(ターゲット アプリケーションが起動してデバッガーに割り込むまで実行)

sxe ld fixup.dll
g

(修正プログラム DLL が読み込まれるまで実行)

bp ...

注意

また、起動時にデバッガーをアプリにアタッチするためにも使用できます。また、 のデバッグ ツールにも含Windows。 ただし、WinDbg によって提供される直接サポートよりも、使用が複雑になります。

サポート

ご質問があるでしょうか。 MSIX 技術コミュニティ サイトの Package Support Framework 会話空間でお問い合わせください。