.NET と Win32 のアプリとゲームは、アドレス指定可能な市場全体を拡大するために、多くの場合、異なる言語にローカライズされます。 アプリのローカライズの価値提案の詳細については、「グローバリゼーションとローカライズの
従来の Win32 アプリケーションをローカライズする方法は多数ありますが、Windows 8 では、アプリケーションの種類をまたいでプログラミング言語間で機能し、単純なローカライズ以上の機能を提供する、新しいリソース管理システム が導入されました。 このシステムは、このトピックでは "MRT" と呼ばれます。 歴史的には、それはかつて「現代のリソース技術」を表していましたが、「現代」という用語は使われなくなりました。 リソース マネージャーは、MRM (Modern Resource Manager) または PRI (パッケージ リソース インデックス) とも呼ばれます。
MSIX ベースまたは .appx ベースの展開 (Microsoft Store など) と組み合わせることで、MRT は特定のユーザー/デバイスに最も適用可能なリソースを自動的に提供し、アプリケーションのダウンロードとインストールのサイズを最小限に抑えることができます。 このサイズの削減は、ローカライズされたコンテンツが大量に含まれるアプリケーション、例えば AAAゲームでは、およそ数 ギガバイト の規模で大きくなる可能性があります。 MRT のその他の利点としては、Windows シェルと Microsoft Store のローカライズされた登録情報、ユーザーの優先言語が使用可能なリソースと一致しない場合の自動フォールバック ロジックなどがあります。
このドキュメントでは、MRT のアーキテクチャの概要について説明し、従来の Win32 アプリケーションを最小限のコード変更で MRT に移行するための移植ガイドを提供します。 MRT への移行が完了すると、追加の利点 (スケール ファクターやシステム テーマでリソースをセグメント化する機能など) が開発者に提供されるようになります。 MRT ベースのローカライズは、デスクトップ ブリッジによって処理される UWP アプリケーションと Win32 アプリケーションの両方で機能します ("Centennial" とも呼ばれる)。
多くの状況では、実行時にリソースを解決し、ダウンロード サイズを最小限に抑えるために MRT と統合しながら、既存のローカライズ形式とソース コードを引き続き使用できます。これは、すべてまたはまったくないアプローチではありません。 次の表は、各ステージの作業と推定コスト/利益をまとめたものです。 この表には、高解像度またはハイ コントラストのアプリケーション アイコンの提供など、ローカライズ以外のタスクは含まれません。 タイル、アイコンなどに複数のアセットを提供する方法の詳細については、「言語、スケール、ハイ コントラスト、およびその他の修飾子に合わせてリソースを調整する」を参照してください。
| 仕事 | メリット | 推定コスト |
|---|---|---|
| パッケージ マニフェストをローカライズする | ローカライズされたコンテンツを Windows シェルと Microsoft Store に表示するために必要な最小限の作業 | 小さい |
| MRT を使用してリソースを識別および検索する | ダウンロードとインストールのサイズを最小限に抑えるための前提条件。自動言語フォールバック | ミディアム |
| リソース パックをビルドする | ダウンロードとインストールのサイズを最小限に抑える最後の手順 | 小さい |
| MRT リソース形式と API への移行 | ファイル サイズが大幅に小さい (既存のリソース テクノロジに応じて) | 大きい |
イントロダクション
ほとんどの単純なアプリケーションには、アプリケーションのコードから切り離された
したがって、リソース管理テクノロジの主な目的は、実行時に、論理リソース名またはシンボリック
例
次に示すのは、2 つのボタン (openButton と saveButton) にテキスト ラベルが付いたアプリケーションと、ロゴ (logoImage) に使用される PNG ファイルを含むアプリケーションの簡単な例です。 テキスト ラベルは英語とドイツ語にローカライズされ、ロゴは通常のデスクトップ ディスプレイ (100% スケール ファクター) と高解像度電話 (300% スケール ファクター) 用に最適化されています。 この図は、モデルの概念的な概要を示しています。実装に正確にマップされるわけではありません。
図では、アプリケーション コードは 3 つの論理リソース名を参照しています。 実行時に、GetResource 擬似関数は MRT を使用してリソース テーブル (PRI ファイルと呼ばれます) でそれらのリソース名を検索し、アンビエント条件 (ユーザーの言語とディスプレイのスケールファクター) に基づいて最も適切な候補を見つけます。 ラベルの場合、文字列は直接使用されます。 ロゴ イメージの場合、文字列はファイル名として解釈され、ファイルはディスクから読み取られます。
ユーザーが英語またはドイツ語以外の言語を話す場合、または表示倍率が 100% または 300%以外の場合、MRT は一連のフォールバック ルールに基づいて "最も近い" 一致する候補を選択します (詳細な背景については、「リソース管理システムの」を参照してください)。
MRT では、複数の修飾子に合わせて調整されたリソースがサポートされていることに注意してください。たとえば、ロゴイメージにローカライズする必要がある埋め込みテキストが含まれている場合、ロゴには EN/Scale-100、DE/Scale-100、EN/Scale-300、DE/Scale-300 の 4 つの候補があります。
このドキュメントのセクション
以降のセクションでは、MRT をアプリケーションと統合するために必要な高度なタスクについて説明します。
フェーズ 0: アプリケーション パッケージをビルドする
このセクションでは、既存のデスクトップ アプリケーションをアプリケーション パッケージとしてビルドする方法について説明します。 この段階では MRT 機能は使用されません。
フェーズ 1: アプリケーション マニフェストをローカライズする
このセクションでは、従来のリソース形式と API を使用してリソースをパッケージ化および検索しながら、アプリケーションのマニフェストをローカライズする方法 (Windows シェルに正しく表示されるようにする) 方法について説明します。
フェーズ 2: MRT を使用してリソースを識別して見つける
このセクションでは、既存のリソース形式と API を使用してリソースを読み込んで使用しながら、MRT を使用してリソースを検索するようにアプリケーション コード (および場合によってはリソース レイアウト) を変更する方法について説明します。
フェーズ 3: リソース パックをビルドする
このセクションでは、アプリのダウンロード (およびインストール) サイズを最小限に抑え、リソースを個別の リソース パックに分離するために必要な最終的な変更について説明します。
このドキュメントでは取り上げません
上記のフェーズ 0 から 3 を完了すると、Microsoft Store に送信できるアプリケーション "バンドル" が作成され、必要のないリソース (たとえば、ユーザーが話さない言語) を省略することで、ユーザーのダウンロードとインストールのサイズが最小限に抑えられます。 アプリケーションのサイズと機能をさらに改善するために、最後の 1 つの手順を実行します。
フェーズ 4: MRT リソース形式と API に移行する
このフェーズは、このドキュメントの範囲外です。これには、リソース (特に文字列) を MUI DLL や .NET リソース アセンブリなどのレガシ形式から PRI ファイルに移動する必要があります。 これにより、ダウンロードおよびインストール サイズの領域がさらに節約される可能性があります。 また、スケール ファクター、アクセシビリティ設定などに基づいて、イメージ ファイルのダウンロードとインストールを最小限に抑えるなどの他の MRT 機能を使用することもできます。
フェーズ 0: アプリケーション パッケージをビルドする
アプリケーションのリソースに変更を加える前に、まず、現在のパッケージ化とインストールのテクノロジを標準の UWP パッケージ化および展開テクノロジに置き換える必要があります。 これを行うには、次の 3 つの方法があります。
- 複雑なインストーラーを備えた大規模なデスクトップ アプリケーションがある場合、または多数の OS 拡張機能ポイントを利用している場合は、Desktop App Converter ツールを使用して、既存のアプリ インストーラー (MSI など) から UWP ファイル のレイアウトとマニフェスト情報を生成できます。
- 比較的少数のファイルを含む小規模なデスクトップ アプリケーションまたは単純なインストーラーがあり、拡張性フックがない場合は、ファイル レイアウトとマニフェスト情報を手動で作成できます。
- ソースからリビルドしていて、アプリを純粋な UWP アプリケーションに更新する場合は、Visual Studio で新しいプロジェクトを作成し、IDE に依存して作業の多くを行うことができます。
デスクトップ アプリ コンバーターを使用する場合は、「デスクトップ アプリ コンバーター を使用してデスクトップ アプリケーションをパッケージ化する」を参照してください。 デスクトップ コンバーターのサンプルの完全なセットは、デスクトップ ブリッジから UWP へのサンプル GitHub リポジトリ
注
デスクトップ アプリ コンバーターは非推奨になりました。 新しく改良された MSIX パッケージ ツール を使用して、デスクトップ アプリをパッケージ化してください。
パッケージを手動で作成する場合は、すべてのアプリケーションのファイル (実行可能ファイルとコンテンツを含むが、ソース コードは含まない) とパッケージ マニフェスト ファイル (.appxmanifest) を含むディレクトリ構造を作成する必要があります。 例は Hello, World GitHub サンプル
<?xml version="1.0" encoding="utf-8" ?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap mp rescap">
<Identity Name="Contoso.Demo"
Publisher="CN=Contoso.Demo"
Version="1.0.0.0" />
<Properties>
<DisplayName>Contoso App</DisplayName>
<PublisherDisplayName>Contoso, Inc</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.14393.0"
MaxVersionTested="10.0.14393.0" />
</Dependencies>
<Resources>
<Resource Language="en-US" />
</Resources>
<Applications>
<Application Id="ContosoDemo" Executable="ContosoDemo.exe"
EntryPoint="Windows.FullTrustApplication">
<uap:VisualElements DisplayName="Contoso Demo" BackgroundColor="#777777"
Square150x150Logo="Assets\Square150x150Logo.png"
Square44x44Logo="Assets\Square44x44Logo.png"
Description="Contoso Demo">
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<rescap:Capability Name="runFullTrust" />
</Capabilities>
</Package>
パッケージ マニフェスト ファイルとパッケージ レイアウトの詳細については、「アプリ パッケージ マニフェスト」を参照してください。
最後に、Visual Studio を使用して新しいプロジェクトを作成し、既存のコードを移行する場合は、「Hello, world」 アプリの作成
フェーズ 1: マニフェストをローカライズする
手順 1.1: マニフェスト内の文字列とアセットを更新する
フェーズ 0 では、アプリケーションの基本的なパッケージ マニフェスト (.appxmanifest) ファイルを (コンバーターに指定された値、MSI から抽出された値、またはマニフェストに手動で入力した値に基づいて) 作成しましたが、ローカライズされた情報は含まれません。また、高解像度のスタート タイルアセットなどの追加機能もサポートしません。
アプリケーションの名前と説明が正しくローカライズされるようにするには、一連のリソース ファイル内にいくつかのリソースを定義し、それらを参照するようにパッケージ マニフェストを更新する必要があります。
既定のリソース ファイルの作成
最初の手順では、既定の言語 (たとえば、米国英語) で既定のリソース ファイルを作成します。 これは、テキスト エディターを使用して手動で行うか、Visual Studio のリソース デザイナーを使用して行うことができます。
リソースを手動で作成する場合:
-
resources.reswという名前の XML ファイルを作成し、プロジェクトのStrings\en-usサブフォルダーに配置します。 既定の言語が米国英語でない場合は、適切な BCP-47 コードを使用します。 - XML ファイルに次のコンテンツを追加します。ここで、強調表示されたテキスト は、既定の言語でアプリに適したテキストに置き換えられます。
注
これらの文字列の一部の長さに制限があります。 詳細については、VisualElements のを参照してください。
<?xml version="1.0" encoding="utf-8"?>
<root>
<data name="ApplicationDescription">
<value>Contoso Demo app with localized resources (English)</value>
</data>
<data name="ApplicationDisplayName">
<value>Contoso Demo Sample (English)</value>
</data>
<data name="PackageDisplayName">
<value>Contoso Demo Package (English)</value>
</data>
<data name="PublisherDisplayName">
<value>Contoso Samples, USA</value>
</data>
<data name="TileShortName">
<value>Contoso (EN)</value>
</data>
</root>
Visual Studio でデザイナーを使用する場合:
-
Strings\en-usフォルダー (または必要に応じて他の言語) をプロジェクトに作成し、既定の名前の を使用して、resources.reswをプロジェクトのルート フォルダーに追加します。 リソース ディクショナリ ではなく、リソース ファイル (.resw)選択してください。リソース ディクショナリは XAML アプリケーションで使用されるファイルです。 - デザイナーを使用して、次の文字列を入力します (同じ
Namesを使用しますが、Valuesをアプリケーションに適したテキストに置き換えます)。
注
Visual Studio デザイナーから開始する場合は、常に F7キーを押して XML を直接編集できます。 ただし、最小限の XML ファイルから始めると、追加のメタデータが多数不足しているため、デザイナー ファイル 認識されません。これを修正するには、デザイナーによって生成されたファイルから手で編集した XML ファイルに定型 XSD 情報をコピーします。
リソースを参照するようにマニフェストを更新する
.resw ファイルで値を定義したら、次の手順では、リソース文字列を参照するようにマニフェストを更新します。 ここでも、XML ファイルを直接編集することも、Visual Studio マニフェスト デザイナーに依存することもできます。
XML を直接編集する場合は、.resw ファイル内の名前と完全に一致する必要があります。 これらの名前は、Names ファイルで作成した .resw と一致する必要があります。プレフィックスには、ms-resource: スキームと Resources/ 名前空間が付いています。
注
マニフェストの多くの要素は、このスニペットから省略されています。何も削除しないでください。
<?xml version="1.0" encoding="utf-8"?>
<Package>
<Properties>
<DisplayName>ms-resource:Resources/PackageDisplayName</DisplayName>
<PublisherDisplayName>ms-resource:Resources/PublisherDisplayName</PublisherDisplayName>
</Properties>
<Applications>
<Application>
<uap:VisualElements DisplayName="ms-resource:Resources/ApplicationDisplayName"
Description="ms-resource:Resources/ApplicationDescription">
<uap:DefaultTile ShortName="ms-resource:Resources/TileShortName">
<uap:ShowNameOnTiles>
<uap:ShowOn Tile="square150x150Logo" />
</uap:ShowNameOnTiles>
</uap:DefaultTile>
</uap:VisualElements>
</Application>
</Applications>
</Package>
Visual Studio マニフェスト デザイナーを使用している場合は、.appxmanifest ファイルを開き、[*アプリケーション] タブと [パッケージ] タブで、強調表示されている 値 値を変更します。
手順 1.2: PRI ファイルをビルドし、MSIX パッケージを作成し、動作していることを確認する
これで、.pri ファイルをビルドし、アプリケーションをデプロイして、(既定の言語で) 正しい情報が [スタート] メニューに表示されていることを確認できるようになりました。
Visual Studio でビルドする場合は、Ctrl+Shift+B キーを押してプロジェクトをビルドし、プロジェクトを右クリックし、コンテキスト メニューから [Deploy] を選択します。
手動でビルドする場合は、次の手順に従って、MakePRI ツール用の構成ファイルを作成し、.pri ファイル自体を生成します (詳細については、手動アプリ パッケージ化を参照してください)。
[スタート] メニューの Visual Studio 2019 または Visual Studio 2022 フォルダーから開発者コマンド プロンプトを開きます。
プロジェクト ルート ディレクトリ (.appxmanifest ファイルと Strings フォルダーを含むディレクトリ) に切り替えます。
次のコマンドを入力し、"contoso_demo.xml" をプロジェクトに適した名前に置き換え、"en-US" をアプリの既定の言語に置き換えます (または、該当する場合は en-US します)。 XML ファイルは、アプリケーションの一部ではないため (プロジェクト ディレクトリに されていない) 親ディレクトリに作成されることに注意してください (必要な他のディレクトリを選択できますが、今後のコマンドで置き換えてください)。
makepri createconfig /cf ..\contoso_demo.xml /dq en-US /pv 10.0 /omakepri createconfig /?を入力すると、各パラメーターの動作を確認できますが、まとめると次のようになります。-
/cf構成ファイル名 (このコマンドの出力) を設定します -
/dqは、既定の修飾子を設定します。この場合、言語がen-USです。 -
/pvはプラットフォーム バージョンを設定します(この場合は Windows 10) -
/o、出力ファイルが存在する場合は上書きするように設定します
-
構成ファイルを作成したら、
MakePRIをもう一度実行して、実際にディスクでリソースを検索し、PRI ファイルにパッケージ化します。 "contoso_demop.xml" を前の手順で使用した XML ファイル名に置き換え、入力と出力の両方に親ディレクトリを指定してください。makepri new /pr . /cf ..\contoso_demo.xml /of ..\resources.pri /mf AppX /omakepri new /?を入力すると、各パラメーターの動作を確認できますが、簡単に説明します。-
/prプロジェクト ルート (この場合は現在のディレクトリ) を設定します -
/cf、前の手順で作成した構成ファイル名を設定します - 出力ファイルを設定
/of -
/mfマッピング ファイルを作成します (そのため、後の手順でパッケージ内のファイルを除外できます) -
/o、出力ファイルが存在する場合は上書きするように設定します
-
これで、既定の言語リソース (例: en-US) を含む
.priファイルが作成されました。 正常に動作したことを確認するには、次のコマンドを実行します。makepri dump /if ..\resources.pri /of ..\resources /omakepri dump /?を入力すると、各パラメーターの動作を確認できますが、簡単に説明します。-
/if入力ファイル名を設定します -
/of出力ファイル名を設定します (.xmlは自動的に追加されます) -
/o、出力ファイルが存在する場合は上書きするように設定します
-
最後に、テキスト エディターで
..\resources.xmlを開き、<NamedResource>の値 (ApplicationDescriptionやPublisherDisplayNameなど) と、選択した既定の言語の<Candidate>値が一覧表示されていることを確認できます (ファイルの先頭には他のコンテンツがあります。現時点では無視してください)。
マッピング ファイル ..\resources.map.txt を開いて、プロジェクトに必要なファイル (プロジェクトのディレクトリに含まれていない PRI ファイルを含む) が含まれていることを確認できます。 重要な点として、マッピング ファイルにはresources.resw ファイルへの参照が含まれていません。なぜなら、そのファイルの内容は既に PRI ファイルに埋め込まれているからです。 ただし、画像のファイル名などの他のリソースが含まれます。
パッケージのビルドと署名
PRI ファイルがビルドされたので、パッケージをビルドして署名できます。
アプリ パッケージを作成するには、
contoso_demo.appxを作成する .msix/.appx ファイルの名前に置き換えて、ファイルに別のディレクトリを選択するように次のコマンドを実行します (このサンプルでは親ディレクトリを使用します。このサンプルでは親ディレクトリを使用しますが、プロジェクト ディレクトリ しないでください)。makeappx pack /m AppXManifest.xml /f ..\resources.map.txt /p ..\contoso_demo.appx /omakeappx pack /?を入力すると、各パラメーターの動作を確認できますが、簡単に説明します。-
/m使用するマニフェスト ファイルを設定します -
/f使用するマッピング ファイルを設定します (前の手順で作成) - 出力パッケージ名を設定
/p -
/o、出力ファイルが存在する場合は上書きするように設定します
-
パッケージが作成されたら、署名する必要があります。 署名証明書を取得する最も簡単な方法は、Visual Studio で空のユニバーサル Windows プロジェクトを作成し、作成した
.pfxファイルをコピーすることですが、「MakeCertを作成する方法」の説明に従って、Pvk2Pfxユーティリティと ユーティリティを使用して手動で作成できます。Von Bedeutung
署名証明書を手動で作成する場合は、ソース プロジェクトやパッケージ ソースとは異なるディレクトリにファイルを配置してください。そうしないと、秘密キーを含むパッケージの一部として含まれる可能性があります。
パッケージに署名するには、次のコマンドを使用します。
の 要素で指定された は、証明書の と一致する必要があることに注意してください (これは、ユーザーに表示するローカライズされた表示名である 要素 ではありません)。 通常どおり、 contoso_demo...ファイル名をプロジェクトに適した名前に置き換え、(非常に重要な).pfxファイルが現在のディレクトリにないことを確認します (それ以外の場合は、秘密署名キーを含むパッケージの一部として作成されています)。signtool sign /fd SHA256 /a /f ..\contoso_demo_key.pfx ..\contoso_demo.appxsigntool sign /?を入力すると、各パラメーターの動作を確認できますが、簡単に説明します。-
/fdファイル ダイジェスト アルゴリズムを設定します (SHA256 は .appx の既定値です) -
/aは最適な証明書を自動的に選択します -
/f署名証明書を含む入力ファイルを指定します
-
最後に、.appx ファイルをダブルクリックしてインストールできます。または、コマンド ラインを使用する場合は、PowerShell プロンプトを開き、パッケージを含むディレクトリに変更し、次のように入力します (contoso_demo.appx をパッケージ名に置き換えます)。
add-appxpackage contoso_demo.appx
証明書が信頼されていないというエラーを受け取った場合は、その証明書がマシンストアに追加されていることを確認してください(として、のユーザーストアではなく)。 コンピューター ストアに証明書を追加するには、コマンド ラインまたは Windows エクスプローラーを使用します。
コマンド ラインを使用するには:
管理者として Visual Studio 2019 または Visual Studio 2022 コマンド プロンプトを実行します。
.cerファイルを含むディレクトリに切り替えます (ソース ディレクトリまたはプロジェクト ディレクトリの外部にあることを忘れないでください)。次のコマンドを入力し、
contoso_demo.cerをファイル名に置き換えます。certutil -addstore TrustedPeople contoso_demo.cercertutil -addstore /?を実行して各パラメーターの動作を確認できますが、簡単に説明します。- 証明書ストアに証明書を追加
-addstore -
TrustedPeopleは、証明書が配置されているストアを示します
- 証明書ストアに証明書を追加
Windows エクスプローラーを使用するには:
-
.pfxファイルを含むフォルダーに移動します -
.pfxファイルをダブルクリックすると、証明書のインポート ウィザードが表示されます - [
Local Machine] を選択し、[Next] をクリックします - ユーザー アカウント制御の管理者昇格プロンプトが表示されたら受け入れ、[
Next] をクリックします。 - 秘密キー用のパスワードを入力し、[
Next]をクリックしてください。 -
Place all certificates in the following storeを選択する - [
] をクリックし、 フォルダーを選択します ([信頼された発行元] ) - [
Next] をクリックしてから、[Finish] をクリックしてください。
Trusted People ストアに証明書を追加した後、パッケージをもう一度インストールしてみてください。
これで、アプリがスタート メニューの [すべてのアプリ] リストに表示され、.resw / .pri ファイルの正しい情報が表示されます。 空白の文字列または ms-resource:... 文字列が表示された場合は、問題が発生しています。編集内容を再確認し、正しいことを確認してください。 スタート メニューでアプリを右クリックすると、アプリをタイルとしてピン留めし、そこに正しい情報が表示されていることを確認できます。
手順 1.3: サポートされている言語をさらに追加する
パッケージ マニフェストに対する変更が行われ、最初の resources.resw ファイルが作成されたら、言語を追加するのは簡単です。
ローカライズされたその他のリソースを作成する
最初に、追加のローカライズされたリソース値を作成します。
Strings フォルダー内に、適切な BCP-47 コード (Strings\de-DEなど) を使用して、サポートする言語ごとに追加のフォルダーを作成します。 これらの各フォルダー内に、翻訳されたリソース値を含む resources.resw ファイル (XML エディターまたは Visual Studio デザイナーを使用) を作成します。 ローカライズされた文字列は既にどこかに用意されており、.resw ファイルにコピーするだけで済むものとします。このドキュメントでは、翻訳手順自体については説明しません。
たとえば、Strings\de-DE\resources.resw ファイルは次のようになります。強調表示されたテキストen-USから変更されます。
<?xml version="1.0" encoding="utf-8"?>
<root>
<data name="ApplicationDescription">
<value>Contoso Demo app with localized resources (German)</value>
</data>
<data name="ApplicationDisplayName">
<value>Contoso Demo Sample (German)</value>
</data>
<data name="PackageDisplayName">
<value>Contoso Demo Package (German)</value>
</data>
<data name="PublisherDisplayName">
<value>Contoso Samples, DE</value>
</data>
<data name="TileShortName">
<value>Contoso (DE)</value>
</data>
</root>
次の手順では、de-DE と fr-FRの両方のリソースを追加していることを前提としていますが、どの言語でも同じパターンに従うことができます。
サポートされている言語を一覧表示するようにパッケージ マニフェストを更新する
アプリでサポートされている言語を一覧表示するには、パッケージ マニフェストを更新する必要があります。 Desktop App Converter は既定の言語を追加しますが、他の言語は明示的に追加する必要があります。
<Resources>
<Resource Language="EN-US" />
<Resource Language="DE-DE" />
<Resource Language="FR-FR" />
</Resources>
Visual Studio を使用している場合は、何もする必要はありません。Package.appxmanifest を見ると、特別な x生成 値が表示されます。これにより、ビルド プロセスによって、プロジェクトで見つけた言語が (BCP-47 コードで名前付きフォルダーに基づいて) 挿入されます。 これは実際のパッケージ マニフェストの有効な値ではないことに注意してください。Visual Studio プロジェクトでのみ機能します。
<Resources>
<Resource Language="x-generate" />
</Resources>
ローカライズされた値を使用して再ビルドする
ここでもアプリケーションをビルドして展開できます。Windows で言語設定を変更すると、[スタート] メニューに新しくローカライズされた値が表示されます (言語を変更する手順は以下のとおりです)。
Visual Studio の場合も、Ctrl+Shift+B を使用してビルドし、プロジェクトを右クリックして Deployできます。
プロジェクトを手動でビルドする場合は、上記と同じ手順に従いますが、構成ファイルの作成時に、アンダースコアで区切られた言語を既定の修飾子リスト (/dq) に追加します。 たとえば、前の手順で追加した英語、ドイツ語、フランス語のリソースをサポートするには、次のようにします。
makepri createconfig /cf ..\contoso_demo.xml /dq en-US_de-DE_fr-FR /pv 10.0 /o
これにより、テストに簡単に使用できる指定されたすべての言語を含む PRI ファイルが作成されます。 リソースの合計サイズが小さい場合、または少数の言語のみをサポートしている場合、これは配送アプリで許容される可能性があります。これは、リソースのインストール/ダウンロード サイズを最小限に抑える利点が必要な場合にのみ、個別の言語パックを構築する追加作業を行う必要があります。
ローカライズされた値を使用してテストする
新しいローカライズされた変更をテストするには、Windows に新しい優先 UI 言語を追加するだけです。 言語パックをダウンロードしたり、システムを再起動したり、Windows UI 全体を外国語で表示したりする必要はありません。
-
Settingsアプリ (Windows + I) を実行する -
Time & languageに移動します。 -
Region & languageに移動します。 - [
Add a language] をクリックします - 必要な言語を入力 (または選択) します (例:
DeutschまたはGerman)- サブ言語がある場合は、目的の言語 (例:
Deutsch / Deutschland) を選択します。
- サブ言語がある場合は、目的の言語 (例:
- 言語一覧で新しい言語を選択する
- [
Set as default] をクリックします
[スタート] メニューを開き、アプリケーションを検索すると、選択した言語のローカライズされた値が表示されます (他のアプリもローカライズされた状態で表示される場合があります)。 ローカライズされた名前がすぐに表示されない場合は、スタート メニューのキャッシュが更新されるまで数分待ちます。 ネイティブ言語に戻すには、言語リストの既定の言語にします。
手順 1.4: パッケージ マニフェストのより多くの部分をローカライズする (省略可能)
パッケージ マニフェストの他のセクションをローカライズできます。 たとえば、アプリケーションがファイル拡張子を処理する場合は、マニフェストに windows.fileTypeAssociation 拡張子が必要です。(リソースを参照するため) 緑色の強調表示されたテキスト 正確に使用し、黄色で強調表示された テキスト をアプリケーション固有の情報に置き換えます。
<Extensions>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="default">
<uap:DisplayName>ms-resource:Resources/FileTypeDisplayName</uap:DisplayName>
<uap:Logo>Assets\StoreLogo.png</uap:Logo>
<uap:InfoTip>ms-resource:Resources/FileTypeInfoTip</uap:InfoTip>
<uap:SupportedFileTypes>
<uap:FileType ContentType="application/x-contoso">.contoso</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
</Extensions>
この情報は、Visual Studio マニフェスト デザイナーを使用して、Declarations タブを使用して、強調表示された値をメモ追加することもできます。
次に、対応するリソース名を各
... existing content...
<data name="FileTypeDisplayName">
<value>Contoso Demo File</value>
</data>
<data name="FileTypeInfoTip">
<value>Files used by Contoso Demo App</value>
</data>
これにより、エクスプローラーなどの Windows シェルの一部に表示されます。
以前と同様にパッケージをビルドしてテストし、新しい UI 文字列を表示する必要がある新しいシナリオを実行します。
フェーズ 2: MRT を使用してリソースを識別して見つける
前のセクションでは、MRT を使用してアプリのマニフェスト ファイルをローカライズし、Windows シェルでアプリの名前やその他のメタデータを正しく表示できるようにする方法を示しました。 これにはコードの変更は必要ありませんでした。単に .resw ファイルといくつかの追加ツールを使用する必要があります。 このセクションでは、MRT を使用して既存のリソース形式のリソースを検索し、既存のリソース処理コードを最小限の変更で使用する方法について説明します。
既存のファイル レイアウトとアプリケーション コードに関する前提条件
Win32 Desktop アプリをローカライズする方法は多数あるため、このホワイト ペーパーでは、特定の環境にマップする必要がある既存のアプリケーションの構造に関する前提条件を簡略化します。 MRT の要件に準拠するために、既存のコードベースまたはリソース レイアウトにいくつかの変更を加える必要がある場合があり、これらは主にこのドキュメントの範囲外です。
リソース ファイルのレイアウト
この記事では、ローカライズされたリソースはすべて同じファイル名 (たとえば、contoso_demo.exe.mui、contoso_strings.dll、contoso.strings.xml) を持ち、BCP-47 名 (en-US、de-DEなど) を持つ別のフォルダーに配置されていることを前提としています。 リソース ファイルの数、名前、ファイル形式や関連付けられている API などは関係ありません。重要なのは、すべての 論理 リソースが同じファイル名を持つということです (ただし、異なる 物理 ディレクトリに配置されます)。
反例として、アプリケーションで、Resources および english_strings.dllファイルを含む単一の french_strings.dll ディレクトリを持つフラットなファイル構造を使用する場合、MRT にうまく対応しません。 より良い構造は、サブディレクトリとファイルが Resources と en\strings.dllを持つ fr\strings.dll ディレクトリです。 同じ基本ファイル名を使用することもできますが、strings.lang-en.dll や strings.lang-fr.dllなどの埋め込み修飾子を使用することもできますが、言語コードでディレクトリを使用する方が概念的に簡単であるため、焦点を当てます。
注
このファイルの名前付け規則に従えない場合でも、MRT とパッケージ化の利点を引き続き使用できます。より多くの作業が必要です。
たとえば、UICommands フォルダーの下に配置された、ui.txtという名前の単純なテキスト ファイルに、一連のカスタム UI コマンド (ボタン ラベルなどに使用) がある場合があります。
+ ProjectRoot |--+ Strings | |--+ en-US | | \--- resources.resw | \--+ de-DE | \--- resources.resw |--+ UICommands | |--+ en-US | | \--- ui.txt | \--+ de-DE | \--- ui.txt |--- AppxManifest.xml |--- ...rest of project...
リソースの読み込みコード
この記事では、コード内のある時点で、ローカライズされたリソースを含むファイルを見つけて読み込み、使用することを前提としています。 リソースの読み込みに使用される API、リソースの抽出に使用される API などは重要ではありません。 擬似コードでは、基本的に 3 つの手順があります。
set userLanguage = GetUsersPreferredLanguage()
set resourceFile = FindResourceFileForLanguage(MY_RESOURCE_NAME, userLanguage)
set resource = LoadResource(resourceFile)
// now use 'resource' however you want
MRT では、このプロセスの最初の 2 つの手順 (最適な候補リソースを決定する方法と検索方法) を変更するだけで済みます。 リソースの読み込み方法や使用方法を変更する必要はありません (ただし、リソースを利用する場合はそれを行うための機能が提供されます)。
たとえば、アプリケーションでは、Win32 API GetUserPreferredUILanguages、CRT 関数 sprintf、Win32 API CreateFile を使用して上記の 3 つの擬似コード関数を置き換え、name=value ペアを探してテキスト ファイルを手動で解析します。 (詳細は重要ではありません。これは、MRT がリソースを見つけた後に処理するために使用される手法に影響がないことを示すためだけにあります)。
手順 2.1: MRT を使用してファイルを見つけるためのコード変更
リソースを検索するために MRT を使用するようにコードを切り替えることは困難ではありません。 いくつかの WinRT 型と数行のコードを使用する必要があります。 使用する主な種類は次のとおりです。
- ResourceContext。現在アクティブな修飾子値のセット (言語、スケール ファクターなど) をカプセル化します。
- resourceManager (.NET バージョンではなく WinRT バージョン) を
します。これにより、PRI ファイルからすべてのリソースにアクセスできるようになります。 - ResourceMap。PRI ファイル内のリソースの特定のサブセット (この例では、ファイル ベースのリソースと文字列リソース) を表します。
- NamedResource。論理リソースとその候補をすべて表します。
- ResourceCandidate。これは、1 つの具体的な候補リソースを表します
擬似コードでは、特定のリソース ファイル名を解決する方法 (上記のサンプルの UICommands\ui.txt など) は次のとおりです。
// Get the ResourceContext that applies to this app
set resourceContext = ResourceContext.GetForViewIndependentUse()
// Get the current ResourceManager (there's one per app)
set resourceManager = ResourceManager.Current
// Get the "Files" ResourceMap from the ResourceManager
set fileResources = resourceManager.MainResourceMap.GetSubtree("Files")
// Find the NamedResource with the logical filename we're looking for,
// by indexing into the ResourceMap
set desiredResource = fileResources["UICommands\ui.txt"]
// Get the ResourceCandidate that best matches our ResourceContext
set bestCandidate = desiredResource.Resolve(resourceContext)
// Get the string value (the filename) from the ResourceCandidate
set absoluteFileName = bestCandidate.ValueAsString
特に、UICommands\ui.txt を要求し、言語ディレクトリのいずれかで適切なディスク上のファイルを見つけるために MRT に依存します。
ここから、サンプル アプリでは引き続き CreateFile を使用して absoluteFileName を読み込み、前と同じように name=value ペアを解析できます。そのロジックのいずれもアプリで変更する必要はありません。 C# または C++/CX で記述する場合、実際のコードはこれよりも複雑ではありません (実際には、中間変数の多くを省略できます)。以下の「.NET リソースの読み込み」のセクションを参照してください。 C++/WRL ベースのアプリケーションは、WinRT API のアクティブ化と呼び出しに使用される低レベルの COM ベースの API により複雑になりますが、基本的な手順は同じです。後述の「Win32 MUI リソースの読み込み」のセクションを参照してください。
.NET リソースの読み込み
.NET にはリソースを検索して読み込むための組み込みメカニズム ("サテライト アセンブリ" と呼ばれます) があるため、上記の合成例のように置き換える明示的なコードはありません。.NET では、適切なディレクトリにリソース DLL が必要であり、自動的に配置されます。 アプリがリソース パックを使用して MSIX または .appx としてパッケージ化されている場合、ディレクトリ構造は多少異なります。リソース ディレクトリはメイン アプリケーション ディレクトリのサブディレクトリではなく、同じ階層に配置されます(ユーザーの設定に選択された言語がない場合は、リソース ディレクトリが存在しないこともあります)。
たとえば、次のレイアウトの .NET アプリケーションで、すべてのファイルが MainApp フォルダーの下に存在するとします。
+ MainApp |--+ en-us | \--- MainApp.resources.dll |--+ de-de | \--- MainApp.resources.dll |--+ fr-fr | \--- MainApp.resources.dll \--- MainApp.exe
.appxに変換した後、レイアウトは次のようになります。en-US が既定の言語であり、ユーザーの言語一覧にドイツ語とフランス語の両方が表示されていると仮定します。
+ WindowsAppsRoot |--+ MainApp_neutral | |--+ en-us | | \--- MainApp.resources.dll | \--- MainApp.exe |--+ MainApp_neutral_resources.language_de | \--+ de-de | \--- MainApp.resources.dll \--+ MainApp_neutral_resources.language_fr \--+ fr-fr \--- MainApp.resources.dll
ローカライズされたリソースはメインの実行可能ファイルのインストール場所の下のサブディレクトリに存在しなくなったため、組み込みの .NET リソース解決は失敗します。 幸いなことに、.NET には、失敗したアセンブリ読み込みの試行 (AssemblyResolve イベント) を処理するための明確に定義されたメカニズムがあります。 MRT を使用する .NET アプリは、このイベントに登録し、不足しているアセンブリを .NET リソース サブシステムに提供する必要があります。
WinRT API を使用して.NET で使用されるサテライト アセンブリを検索する方法の簡潔な例を次に示します。提示されたコードは、最小限の実装を示すために意図的に圧縮されていますが、上記の擬似コードに密接にマップされ、渡された ResolveEventArgs で見つける必要があるアセンブリの名前を指定できます。 このコードの実行可能なバージョン (詳細なコメントとエラー処理を含む) は、GitHubの
static class PriResourceResolver
{
internal static Assembly ResolveResourceDll(object sender, ResolveEventArgs args)
{
var fullAssemblyName = new AssemblyName(args.Name);
var fileName = string.Format(@"{0}.dll", fullAssemblyName.Name);
var resourceContext = ResourceContext.GetForViewIndependentUse();
resourceContext.Languages = new[] { fullAssemblyName.CultureName };
var resource = ResourceManager.Current.MainResourceMap.GetSubtree("Files")[fileName];
// Note use of 'UnsafeLoadFrom' - this is required for apps installed with .appx, but
// in general is discouraged. The full sample provides a safer wrapper of this method
return Assembly.UnsafeLoadFrom(resource.Resolve(resourceContext).ValueAsString);
}
}
上記のクラスでは、アプリケーションのスタートアップ コードの早い段階で (ローカライズされたリソースを読み込む前に) 次のコードを追加します。
void EnableMrtResourceLookup()
{
AppDomain.CurrentDomain.AssemblyResolve += PriResourceResolver.ResolveResourceDll;
}
.NET ランタイムは、リソース DLL が見つからない場合は常に AssemblyResolve イベントを発生させます。その時点で、指定されたイベント ハンドラーは MRT 経由で目的のファイルを検索し、アセンブリを返します。
注
アプリに他の目的で AssemblyResolve ハンドラーが既にある場合は、リソース解決コードを既存のコードと統合する必要があります。
Win32 MUI リソースの読み込み
Win32 MUI リソースの読み込みは基本的に .NET サテライト アセンブリの読み込みと同じですが、代わりに C++/CX または C++/WRL コードを使用します。 C++/CX を使用することで、上記の C# コードに近い、より簡潔なコードを書くことが可能になります。しかし、C++ の言語拡張機能、コンパイラ スイッチ、およびランタイムのオーバーヘッドが発生するため、これらを避けたいと考えるかもしれません。 その場合、C++/WRL を使用すると、より詳細なコードを犠牲にして、影響がはるかに低いソリューションが提供されます。 それでも、ATL プログラミング (または COM 全般) に慣れている場合は、WRL は使い慣れていると感じるはずです。
次のサンプル関数は、C++/WRL を使用して特定のリソース DLL を読み込み、通常の Win32 リソース API を使用してさらにリソースを読み込むのに使用できる HINSTANCE を返す方法を示しています。 .NET ランタイムによって要求された言語で ResourceContext を明示的に初期化する C# サンプルとは異なり、このコードはユーザーの現在の言語に依存します。
#include <roapi.h>
#include <wrl\client.h>
#include <wrl\wrappers\corewrappers.h>
#include <Windows.ApplicationModel.resources.core.h>
#include <Windows.Foundation.h>
#define IF_FAIL_RETURN(hr) if (FAILED((hr))) return hr;
HRESULT GetMrtResourceHandle(LPCWSTR resourceFilePath, HINSTANCE* resourceHandle)
{
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::ApplicationModel::Resources::Core;
using namespace ABI::Windows::Foundation;
*resourceHandle = nullptr;
HRESULT hr{ S_OK };
RoInitializeWrapper roInit{ RO_INIT_SINGLETHREADED };
IF_FAIL_RETURN(roInit);
// Get Windows.ApplicationModel.Resources.Core.ResourceManager statics
ComPtr<IResourceManagerStatics> resourceManagerStatics;
IF_FAIL_RETURN(GetActivationFactory(
HStringReference(
RuntimeClass_Windows_ApplicationModel_Resources_Core_ResourceManager).Get(),
&resourceManagerStatics));
// Get .Current property
ComPtr<IResourceManager> resourceManager;
IF_FAIL_RETURN(resourceManagerStatics->get_Current(&resourceManager));
// get .MainResourceMap property
ComPtr<IResourceMap> resourceMap;
IF_FAIL_RETURN(resourceManager->get_MainResourceMap(&resourceMap));
// Call .GetValue with supplied filename
ComPtr<IResourceCandidate> resourceCandidate;
IF_FAIL_RETURN(resourceMap->GetValue(HStringReference(resourceFilePath).Get(),
&resourceCandidate));
// Get .ValueAsString property
HString resolvedResourceFilePath;
IF_FAIL_RETURN(resourceCandidate->get_ValueAsString(
resolvedResourceFilePath.GetAddressOf()));
// Finally, load the DLL and return the hInst.
*resourceHandle = LoadLibraryEx(resolvedResourceFilePath.GetRawBuffer(nullptr),
nullptr, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);
return S_OK;
}
フェーズ 3: リソース パックのビルド
すべてのリソースを含む "fat pack" が作成されたので、ダウンロードとインストールのサイズを最小限に抑えるために、メイン パッケージとリソース パッケージを個別に構築するための 2 つのパスがあります。
- 既存の脂肪パックを取得し、バンドル ジェネレーター ツール
実行して、リソース パックを自動的に作成します。 これは、既に fat パックを生成するビルド システムがあり、それを後処理してリソース パックを生成する場合に推奨されるアプローチです。 - 個々のリソース パッケージを直接生成し、バンドルにビルドします。 これは、ビルド システムをより詳細に制御でき、パッケージを直接ビルドできる場合に推奨されるアプローチです。
手順 3.1: バンドルを作成する
バンドル ジェネレーター ツールの使用
バンドル ジェネレーター ツールを使用するには、パッケージ用に作成された PRI 構成ファイルを手動で更新して、<packaging> セクションを削除する必要があります。
Visual Studio を使用している場合は、「 が必要かどうかに関係なく、リソースがデバイスにインストールされていることを確認する」を参照してください。
ファイルを手動で編集する場合は、次の手順に従います。
正しいパス、ファイル名、言語を置き換えて、以前と同じ方法で構成ファイルを作成します。
makepri createconfig /cf ..\contoso_demo.xml /dq en-US_de-DE_es-MX /pv 10.0 /o作成した
.xmlファイルを手動で開き、<packaging&rt;セクション全体を削除します (ただし、他の操作はすべてそのままにしておきます)。<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <resources targetOsVersion="10.0.0" majorVersion="1"> <!-- Packaging section has been deleted... --> <index root="\" startIndexAt="\"> <default> ... ...更新された構成ファイルと適切なディレクトリとファイル名を使用して、以前と同様に
.priファイルと.appxパッケージをビルドします (これらのコマンドの詳細については、上記を参照してください)。makepri new /pr . /cf ..\contoso_demo.xml /of ..\resources.pri /mf AppX /o makeappx pack /m AppXManifest.xml /f ..\resources.map.txt /p ..\contoso_demo.appx /oパッケージが作成されたら、次のコマンドを使用して、適切なディレクトリとファイル名を使用してバンドルを作成します。
BundleGenerator.exe -Package ..\contoso_demo.appx -Destination ..\bundle -BundleName contoso_demo
これで、最後の手順である署名に進むことができます (下記参照)。
リソース パッケージの手動作成
リソース パッケージを手動で作成するには、個別の .pri ファイルと .appx ファイルをビルドするために、少し異なるコマンド セットを実行する必要があります。これらはすべて、脂肪パッケージを作成するために上記で使用したコマンドと似ていますので、最小限の説明が与えられます。 注: すべてのコマンドは、現在のディレクトリが AppXManifest.xml ファイルを含むディレクトリであることを前提としていますが、すべてのファイルは親ディレクトリに配置されます (必要に応じて別のディレクトリを使用できますが、これらのファイルでプロジェクト ディレクトリを汚染しないでください)。 いつも通り、「Contoso」というファイル名を独自のファイル名に置き換えてください。
次のコマンドを使用して、のみを既定の修飾子として、既定の言語 を設定する構成ファイルを作成します。この場合は
en-US。makepri createconfig /cf ..\contoso_demo.xml /dq en-US /pv 10.0 /o次のコマンドを使用して、メイン パッケージの既定の
.priと.map.txtファイルに加えて、プロジェクトで見つかった各言語の追加のファイル セットを作成します。makepri new /pr . /cf ..\contoso_demo.xml /of ..\resources.pri /mf AppX /o次のコマンドを使用して、メイン パッケージ (実行可能コードと既定の言語リソースを含む) を作成します。 常に、必要に応じて名前を変更しますが、後でバンドルを簡単に作成できるようにパッケージを別のディレクトリに配置する必要があります (この例では、
..\bundleディレクトリを使用します)。makeappx pack /m .\AppXManifest.xml /f ..\resources.map.txt /p ..\bundle\contoso_demo.main.appx /oメイン パッケージが作成されたら、追加言語ごとに次のコマンドを 1 回使用します (つまり、前の手順で生成された言語マップ ファイルごとにこのコマンドを繰り返します)。 ここでも、出力は別のディレクトリ (メイン パッケージと同じディレクトリ) に配置する必要があります。 言語は、
オプションと オプションの両方 指定され、新しい 引数 (リソース パッケージが必要であることを示します) の使用に注意してください。 makeappx pack /r /m .\AppXManifest.xml /f ..\resources.language-de.map.txt /p ..\bundle\contoso_demo.de.appx /oバンドル ディレクトリのすべてのパッケージを 1 つの
.appxbundleファイルに結合します。 新しい/dオプションでは、バンドル内のすべてのファイルに使用するディレクトリを指定します (これは、.appxファイルが前の手順で別のディレクトリに配置される理由です)。makeappx bundle /d ..\bundle /p ..\contoso_demo.appxbundle /o
パッケージをビルドする最後の手順は署名です。
手順 3.2: バンドルに署名する
.appxbundle ファイルを作成すると (バンドル ジェネレーター ツールを使用するか、手動で)、メイン パッケージとすべてのリソース パッケージを含む 1 つのファイルが作成されます。 最後の手順では、Windows によってインストールされるようにファイルに署名します。
signtool sign /fd SHA256 /a /f ..\contoso_demo_key.pfx ..\contoso_demo.appxbundle
これにより、メイン パッケージとすべての言語固有のリソース パッケージを含む署名された .appxbundle ファイルが生成されます。 パッケージ ファイルと同様にダブルクリックして、アプリと、ユーザーの Windows 言語設定に基づいて適切な言語をインストールできます。