System.Resources.ResourceManager クラス

この記事は、この API のリファレンス ドキュメントの補足説明です。

重要

このクラスのメソッドを信頼されていないデータを指定して呼び出すことには、セキュリティ上のリスクが伴います。 このクラスのメソッドの呼び出しは、信頼されたデータだけを指定して実行してください。 詳細については、「すべての入力の検証」を参照してください

ResourceManager クラスは、アセンブリに埋め込まれているバイナリ .resources ファイル、または、スタンドアロンの .resources ファイルからリソースを取得します。 アプリがローカライズされ、ローカライズされたリソースがサテライト アセンブリに配置されているなら、アプリは、カルチャ固有のリソースを検索し、ローカライズされたリソースが存在しない場合は、リソース フォールバックを提供します。また、リソースのシリアル化をサポートします。

デスクトップ アプリ

デスクトップ アプリの場合、ResourceManager クラスは、バイナリ リソース (.resources) ファイルからリソースを取得します。 通常は、言語コンパイラかアセンブリ リンカー (AL.exe) がアセンブリにこれらのリソース ファイルを埋め込みます。 CreateFileBasedResourceManager メソッドを呼び出すことによって、ResourceManager オブジェクトを使用して、アセンブリに埋め込まれていない .resources ファイルからリソースを直接取得できます。

注意

ASP.NET アプリでスタンドアロン .resources ファイルを使用すると、XCOPY による配置が中断されます。ReleaseAllResources メソッドによって明示的に解放されるまで、リソースがロックされたままになるためです。 ASP.NET アプリでリソースを配置する場合は、サテライト アセンブリに .resources ファイルをコンパイルする必要があります。

リソース ベースのアプリでは、1 つの .resources ファイルは既定のカルチャのリソースを含んでいます。そのリソースは、カルチャ固有のリソースが見つからない場合に使用されます。 たとえば、アプリの既定のカルチャが英語 (en) の場合は、英語 (米国) (en-US) やフランス語 (フランス) (fr-FR) などの、特定のカルチャに対してローカライズされたリソースが見つからないときに、英語の言語リソースが使用されます。 通常は、既定のカルチャのリソースはメイン アプリ アセンブリに埋め込まれ、他のローカライズされたリソースはサテライト アセンブリに埋め込まれます。 サテライト アセンブリはリソースのみを含みます。 サテライト アセンブリは、メイン アセンブリと同じルート ファイル名と、resources.dll の拡張子を持ちます。 アプリのアセンブリがグローバル アセンブリ キャッシュに登録されていない場合は、サテライト アセンブリは、アセンブリのカルチャに対応する名前を持つ、アプリのサブディレクトリに格納されます。

リソースを作成する

リソース ベースのアプリを開発する際は、テキスト ファイル (.txt か .restext 拡張子を持つファイル) または XML ファイル (.resx 拡張子を持つファイル) にリソース情報を格納します。 それからリソース ファイル ジェネレーター (Resgen.exe) を使用して、テキスト ファイルまたは XML ファイルをコンパイルし、バイナリ .resources ファイルを作成します。 その後、C# コンパイラや Visual Basic コンパイラなどの/resourcesコンパイラ オプションを使用して、実行可能ファイルまたはライブラリに結果の .resources ファイルを埋め込んだり、アセンブリ リンカー (AI.exe) を使用してサテライト アセンブリに埋め込んだりできます。 Visual Studio プロジェクトに .resx ファイルを含めると、Visual Studio はビルド プロセスの一部として、既定のリソースとローカライズされたリソースのコンパイルおよび埋め込みを自動的に処理します。

理想的には、アプリがサポートするすべての言語か、少なくとも各言語で意味をなすサブセットに対して、リソースを作成してください。 バイナリ .resources ファイルの名前は、basename.cultureName.resources の名前付け規則に従います。ここで basename は、必要な詳細のレベルに応じて、アプリの名前またはクラスの名前になります。 cultureName を判断するには、CultureInfo.Name プロパティを使用します。 アプリの既定のカルチャのリソースには、basename.resources の名前をつけてください。

たとえば、ベースの名前に MyResources を持つリソース ファイルにいくつかのリソースが含まれているアセンブリを想定します。 これらのリソース ファイルは、日本 (日本語) のカルチャには MyResources.ja-JP.resources、ドイツのカルチャには MyResources.de.resources、簡体中国語のカルチャには MyResources.zh-CHS.resources、フランス語 (ベルギー) のカルチャには MyResources.fr-BE.resources、などの名前を持つ必要があります。 既定のリソース ファイルは MyResources.resources の名前を持つ必要があります。 通常は、カルチャ固有のリソース ファイルは、カルチャごとにサテライト アセンブリにパッケージ化されます。 既定のリソース ファイルは、アプリのメイン アセンブリに埋め込まれる必要があります。

アセンブリ リンカーではリソースをプライベートとしてマークできますが、他のアセンブリからアクセスできるように常にパブリックとしてマークする必要があることに注意してください。 (サテライト アセンブリはコードを含まないため、プライベートとしてマークされたリソースは、どんな方法を使ってもアプリで使用できません。)

リソースの作成、パッケージ化、および、配置の詳細については、リソース ファイルの作成サテライト アセンブリの作成リソースのパッケージ化と配置の記事を参照してください。

ResourceManager オブジェクトをインスタンス化する

埋め込まれた .resources ファイルからリソースを取得する ResourceManager オブジェクトのインスタンス化は、それのクラス コンストラクターのオーバーロードの 1 つを呼び出すことによって行います。 これは、ResourceManager オブジェクトを、特定の .resources ファイルや、サテライト アセンブリにあり関連するローカライズされた .resources ファイルとを密に結びつけます。

最もよく呼び出されるコンストラクターは次の 2 つです。

  • ResourceManager(String, Assembly) は、指定した 2 つの情報に基づいてリソースを検索します。それらは .resources ファイルのベース名と、既定の .resources ファイルが存在するアセンブリです。 ベース名は、.resources ファイルの名前空間とルート名を含み、それのカルチャや拡張子を含みません。 コマンド ラインからコンパイルされた .resources ファイルは、通常は名前空間の名前を含みませんが、Visual Studio 環境で作成した .resources ファイルはそれを含むことに注意してください。 たとえば、リソース ファイルの名前が MyCompany.StringResources.resources であり、Example.Main という名前の静的メソッドから ResourceManager コンストラクターを呼び出す場合、次のコードが .resources ファイルからリソースを取得できる ResourceManager オブジェクトをインスタンス化します。

    ResourceManager rm = new ResourceManager("MyCompany.StringResources",
                                             typeof(Example).Assembly);
    
    Dim rm As New ResourceManager("MyCompany.StringResources",
                                GetType(Example2).Assembly)
    
  • ResourceManager(Type) は、型オブジェクトからの情報に基づいて、サテライト アセンブリにあるリソースを検索します。 型の完全修飾名は、ファイル名の拡張子を含まない .resources ファイルのベース名に対応します。 Visual Studio リソース デザイナーを使用して作成されたデスクトップ アプリでは、Visual Studio は .resources ファイルのルート名と同じ完全修飾名を持つラッパー クラスを作成します。 たとえば、リソース ファイルの名前が MyCompany.StringResources.resources であり、MyCompany.StringResources という名前のラッパー クラスがある場合、次のコードが .resources ファイルからリソースを取得できる ResourceManager オブジェクトをインスタンス化します。

    ResourceManager rm = new ResourceManager(typeof(MyCompany.StringResources));
    
    Dim rm As New ResourceManager(GetType(MyCompany.StringResources))
    

適切なリソースが見つからない場合、コンストラクターの呼び出しは有効な ResourceManager オブジェクトを作成します。 ただし、リソースを取得しようとすると、MissingManifestResourceException 例外がスローされます。 例外の処理の詳細については、この記事で後述する 「MissingManifestResourceException と MissingSatelliteAssemblyException 例外 の処理」セクションを参照してください。

次の例は、ResourceManager オブジェクトをインスタンス化する方法を示しています。 それには ShowTime.exe という名前の実行可能ファイルのソース コードが含まれています。 また、次に示す TimeHeader という唯一の文字列リソースを含む、Strings.txt という名前のテキスト ファイルも含まれます。

TimeHeader=The current time is

バッチ ファイルを使用して、リソース ファイルを生成し、実行可能ファイルに埋め込むことができます。 C# コンパイラを使用して、実行可能ファイルを生成するバッチ ファイルを次に示します。

resgen strings.txt
csc ShowTime.cs /resource:strings.resources

Visual Basic コンパイラでは、次のバッチ ファイルを使用できます。

resgen strings.txt
vbc ShowTime.vb /resource:strings.resources
using System;
using System.Resources;

public class ShowTimeEx
{
    public static void Main()
    {
        ResourceManager rm = new ResourceManager("Strings",
                                 typeof(Example).Assembly);
        string timeString = rm.GetString("TimeHeader");
        Console.WriteLine("{0} {1:T}", timeString, DateTime.Now);
    }
}
// The example displays output like the following:
//        The current time is 2:03:14 PM
Imports System.Resources

Module Example6
    Public Sub Main()
        Dim rm As New ResourceManager("Strings", GetType(Example6).Assembly)
        Dim timeString As String = rm.GetString("TimeHeader")
        Console.WriteLine("{0} {1:T}", timeString, Date.Now)
    End Sub
End Module
' The example displays output similar to the following:
'       The current time is 2:03:14 PM

ResourceManager とカルチャ固有のリソース

リソースのパッケージ化と配置の記事で説明したように、ローカライズされたアプリはリソースを配置する必要があります。 アセンブリが正しく構成されているなら、リソース マネージャーは、現在のスレッドの Thread.CurrentUICulture プロパティに基づいて、どのリソースを取得するかを決定します。 (そのプロパティは現在のスレッドの UI カルチャを返します。) たとえば、メイン アセンブリに既定の英語の言語リソースがあり、2 つのサテライト アセンブリにフランス語とロシア語の言語リソースがあるようにアプリがコンパイルされていて、Thread.CurrentUICulture プロパティが fr-FR に設定されている場合、リソース マネージャーはフランス語のリソースを取得します。

CurrentUICulture プロパティは明示的または暗黙的に設定できます。 それを設定する方法によって、ResourceManager オブジェクトがカルチャに基づいてリソースを取得する方法が決定されます。

  • 明示的に Thread.CurrentUICulture プロパティに特定のカルチャを設定する場合、リソース マネージャーは常に、ユーザーのブラウザーまたはオペレーティング システムの言語に関係なく、そのカルチャのリソースを取得します。 既定の英語の言語リソースと、英語 (米国)、フランス語 (フランス)、およびロシア語 (ロシア) のリソースを含む 3 つのサテライト アセンブリとともにコンパイルされているアプリを考えます。 CurrentUICulture プロパティが fr-FR に設定されている場合、たとえユーザーのオペレーティング システムの言語がフランス語ではないとしても、ResourceManager オブジェクトは常にフランス語 (フランス) のリソースを取得します。 プロパティを明示的に設定する前に、これが目的の動作であることを確認してください。

    ASP.NET アプリでは、サーバーの設定が受信したクライアント要求と一致しない可能性があるため、Thread.CurrentUICulture プロパティを明示的に設定する必要があります。 ASP.NET アプリは Thread.CurrentUICulture プロパティをユーザーのブラウザーが受け入れ可能な言語に明示的に設定できます。

    Thread.CurrentUICulture プロパティを明示的に設定することによって、そのスレッドの現在の UI カルチャが定義されます。 これは、アプリの他のスレッドの現在の UI カルチャには影響しません。

  • CultureInfo.DefaultThreadCurrentUICulture 静的プロパティに UI カルチャを表す CultureInfo オブジェクトを割り当てることで、アプリ ドメイン内のすべてのスレッドの UI カルチャを設定できます。

  • 現在の UI カルチャを明示的に設定せず、現在のアプリ ドメインに既定のカルチャを定義しない場合、CultureInfo.CurrentUICulture プロパティは Windows の GetUserDefaultUILanguage 関数によって暗黙的に設定されます。 この関数は Multilingual User Interface (MUI) によって提供されます。MUI は、ユーザーが既定の言語を設定できるようにします。 UI 言語がユーザーによって設定されていない場合、その既定値はシステムによってインストールされた言語になります。これはオペレーティング システムのリソースの言語です。

次の単純な "Hello world" の例では、現在の UI カルチャを明示的に設定します。 これには、英語 (米国) (en-US)、フランス語 (フランス) (fr-FR)、およびロシア語 (ロシア) (ru-RU) の 3 つのカルチャのリソースが含まれています。 en-US のリソースは、Greetings.txt という名前のテキスト ファイルに含まれています。

HelloString=Hello world!

fr-FR のリソースは、Greetings.fr-FR.txt という名前のテキスト ファイルに含まれています。

HelloString=Salut tout le monde!

ru-RU のリソースは、Greetings.ru-RU.txt という名前のテキスト ファイルに含まれています。

HelloString=Всем привет!

次に、この例のソース コード (Visual Basic バージョンの Example.vb または C# バージョンの Example.cs) を示します。

using System;
using System.Globalization;
using System.Resources;
using System.Threading;

public class Example
{
    public static void Main()
    {
        // Create array of supported cultures
        string[] cultures = { "en-CA", "en-US", "fr-FR", "ru-RU" };
        Random rnd = new Random();
        int cultureNdx = rnd.Next(0, cultures.Length);
        CultureInfo originalCulture = Thread.CurrentThread.CurrentCulture;
        ResourceManager rm = new ResourceManager("Greetings", typeof(Example).Assembly);
        try
        {
            CultureInfo newCulture = new CultureInfo(cultures[cultureNdx]);
            Thread.CurrentThread.CurrentCulture = newCulture;
            Thread.CurrentThread.CurrentUICulture = newCulture;
            string greeting = String.Format("The current culture is {0}.\n{1}",
                                            Thread.CurrentThread.CurrentUICulture.Name,
                                            rm.GetString("HelloString"));
            Console.WriteLine(greeting);
        }
        catch (CultureNotFoundException e)
        {
            Console.WriteLine("Unable to instantiate culture {0}", e.InvalidCultureName);
        }
        finally
        {
            Thread.CurrentThread.CurrentCulture = originalCulture;
            Thread.CurrentThread.CurrentUICulture = originalCulture;
        }
    }
}
// The example displays output like the following:
//       The current culture is ru-RU.
//       Всем привет!
Imports System.Globalization
Imports System.Resources
Imports System.Threading

Module Example
   Sub Main()
      ' Create array of supported cultures
      Dim cultures() As String = {"en-CA", "en-US", "fr-FR", "ru-RU" }
      Dim rnd As New Random()
      Dim cultureNdx As Integer = rnd.Next(0, cultures.Length)
      Dim originalCulture As CultureInfo = Thread.CurrentThread.CurrentCulture
      Dim rm As New ResourceManager("Greetings", GetType(Example).Assembly)
      Try
         Dim newCulture As New CultureInfo(cultures(cultureNdx))
         Thread.CurrentThread.CurrentCulture = newCulture
         Thread.CurrentThread.CurrentUICulture = newCulture
         Dim greeting As String = String.Format("The current culture is {0}.{1}{2}",
                                                Thread.CurrentThread.CurrentUICulture.Name,
                                                vbCrLf, rm.GetString("HelloString"))

         Console.WriteLine(greeting)
      Catch e As CultureNotFoundException
         Console.WriteLine("Unable to instantiate culture {0}", e.InvalidCultureName)
      Finally
         Thread.CurrentThread.CurrentCulture = originalCulture
         Thread.CurrentThread.CurrentUICulture = originalCulture
      End Try
   End Sub
End Module
' The example displays output like the following:
'       The current culture is ru-RU.
'       Всем привет!

この例をコンパイルするには、次のコマンドを含むバッチ (.bat) ファイルを作成し、コマンド プロンプトからそれを実行します。 C# を使用している場合は、vbc の代わりに csc を指定し、Example.vb の代わりに Example.cs を指定します。

resgen Greetings.txt
vbc Example.vb /resource:Greetings.resources

resgen Greetings.fr-FR.txt
Md fr-FR
al /embed:Greetings.fr-FR.resources /culture:fr-FR /out:fr-FR\Example.resources.dll

resgen Greetings.ru-RU.txt
Md ru-RU
al /embed:Greetings.ru-RU.resources /culture:ru-RU /out:ru-RU\Example.resources.dll

リソースを取得する

特定のリソースにアクセスするには、GetObject(String)GetString(String) メソッドを呼び出します。 GetStream(String) メソッドを呼び出して、文字列以外のリソースをバイト配列として取得することもできます。 既定では、リソースがローカライズされているアプリでは、これらのメソッドは、呼び出しを行ったスレッドの現在の UI カルチャによって決定されるカルチャのリソースを返します。 スレッドの現在の UI カルチャの定義方法の詳細については、前のセクション ResourceManager とカルチャ固有のリソースを参照してください。 リソース マネージャーが現在のスレッドの UI カルチャのリソースを見つけられない場合は、フォールバック プロセスを使用して、指定したリソースを取得します。 リソース マネージャーがローカライズされたリソースを何も見つけられない場合は、既定のカルチャのリソースを使用します。 リソース フォールバック規則の詳細については、リソースのパッケージ化と配置の記事内の「リソース フォールバック プロセス」セクションを参照してください。

Note

ResourceManager クラスのコンストラクターで指定された .resources ファイルが見つからない場合、リソースを取得しようとすると、MissingManifestResourceException または MissingSatelliteAssemblyException 例外がスローされます。 例外の処理の詳細については、この記事で後述する 「MissingManifestResourceException と MissingSatelliteAssemblyException 例外 の処理」セクションを参照してください。

次の例では、GetString メソッドを使用して、カルチャ固有のリソースを取得します。 これは、英語 (en)、フランス語 (フランス) (fr-FR)、およびロシア語 (ロシア) (ru-RU) の .txt ファイルからコンパイルされたリソースで構成されます。 例では、現在のカルチャと現在の UI カルチャを、英語 (米国)、フランス語 (フランス)、ロシア語 (ロシア)、およびスウェーデン語 (スウェーデン) に変更します。 それから、GetString メソッドを呼び出して、ローカライズされた文字列を取得します。この文字列は現在の日付と月と一緒に表示されます。 現在の UI カルチャがスウェーデン語 (スウェーデン) である場合を除き、適切なローカライズされた文字列が出力に表示されることに注意してください。 スウェーデン語の言語リソースが利用できないため、アプリは代わりに既定のカルチャである英語のリソースを使用します。

例には、次の表に記載されたテキスト ベースのリソース ファイルが必要です。 それぞれには DateStart という名前の唯一の文字列リソースがあります。

カルチャ ファイル名 リソース名 リソースの値
ja-JP DateStrings.txt DateStart Today is
fr-FR DateStrings.fr-FR.txt DateStart Aujourd'hui, c'est le
ru-RU DateStrings.ru-RU.txt DateStart Сегодня

次に、この例のソース コード (Visual Basic バージョンの ShowDate.vb または C# バージョンの ShowDate.cs) を示します。

using System;
using System.Globalization;
using System.Resources;
using System.Threading;

[assembly: NeutralResourcesLanguage("en")]

public class ShowDateEx
{
    public static void Main()
    {
        string[] cultureNames = { "en-US", "fr-FR", "ru-RU", "sv-SE" };
        ResourceManager rm = new ResourceManager("DateStrings",
                                                 typeof(Example).Assembly);

        foreach (var cultureName in cultureNames)
        {
            CultureInfo culture = CultureInfo.CreateSpecificCulture(cultureName);
            Thread.CurrentThread.CurrentCulture = culture;
            Thread.CurrentThread.CurrentUICulture = culture;

            Console.WriteLine("Current UI Culture: {0}",
                              CultureInfo.CurrentUICulture.Name);
            string dateString = rm.GetString("DateStart");
            Console.WriteLine("{0} {1:M}.\n", dateString, DateTime.Now);
        }
    }
}
// The example displays output similar to the following:
//       Current UI Culture: en-US
//       Today is February 03.
//       
//       Current UI Culture: fr-FR
//       Aujourd'hui, c'est le 3 février
//       
//       Current UI Culture: ru-RU
//       Сегодня февраля 03.
//       
//       Current UI Culture: sv-SE
//       Today is den 3 februari.
Imports System.Globalization
Imports System.Resources
Imports System.Threading

<Assembly:NeutralResourcesLanguage("en")>

Module Example5
    Public Sub Main()
        Dim cultureNames() As String = {"en-US", "fr-FR", "ru-RU", "sv-SE"}
        Dim rm As New ResourceManager("DateStrings",
                                    GetType(Example5).Assembly)

        For Each cultureName In cultureNames
            Dim culture As CultureInfo = CultureInfo.CreateSpecificCulture(cultureName)
            Thread.CurrentThread.CurrentCulture = culture
            Thread.CurrentThread.CurrentUICulture = culture

            Console.WriteLine("Current UI Culture: {0}",
                           CultureInfo.CurrentUICulture.Name)
            Dim dateString As String = rm.GetString("DateStart")
            Console.WriteLine("{0} {1:M}.", dateString, Date.Now)
            Console.WriteLine()
        Next
    End Sub
End Module
' The example displays output similar to the following:
'       Current UI Culture: en-US
'       Today is February 03.
'       
'       Current UI Culture: fr-FR
'       Aujourd'hui, c'est le 3 février
'       
'       Current UI Culture: ru-RU
'       Сегодня февраля 03.
'       
'       Current UI Culture: sv-SE
'       Today is den 3 februari.

この例をコンパイルするには、次のコマンドを含むバッチ ファイルを作成し、コマンド プロンプトからそれを実行します。 C# を使用している場合は、vbc の代わりに csc を指定し、showdate.vb の代わりに showdate.cs を指定します。

resgen DateStrings.txt
vbc showdate.vb /resource:DateStrings.resources

md fr-FR
resgen DateStrings.fr-FR.txt
al /out:fr-FR\Showdate.resources.dll /culture:fr-FR /embed:DateStrings.fr-FR.resources

md ru-RU
resgen DateStrings.ru-RU.txt
al /out:ru-RU\Showdate.resources.dll /culture:ru-RU /embed:DateStrings.ru-RU.resources

現在の UI カルチャ以外の特定のカルチャのリソースを取得する方法は 2 つあります。

  • GetString(String, CultureInfo)GetObject(String, CultureInfo)、またはGetStream(String, CultureInfo) メソッドを呼び出して、指定したカルチャのリソースを取得できます。 ローカライズされたリソースが見つからない場合、リソース マネージャーはリソース フォールバック プロセスを使用して、適切なリソースを見つけます。
  • GetResourceSet メソッドを呼び出して、特定のカルチャのリソースを表す ResourceSet オブジェクトを取得できます。 メソッドの呼び出しでは、ローカライズされたリソースが見つからない場合に、親カルチャのリソース マネージャーのプローブを作成するかどうかや、単純に既定のカルチャのリソースにフォールバックするかどうかを指定できます。 その後、ResourceSet のメソッドを使用して、(そのカルチャに向けてローカライズされた) リソースに名前でアクセスしたり、または、セット内のリソースを列挙したりできます。

MissingManifestResourceException 例外と MissingSatelliteAssemblyException 例外を処理する

特定のリソースを取得しようとしても、リソース マネージャーがそのリソースを見つけられないときに、既定のカルチャが定義されていないか、または既定のカルチャのリソースが見つからない場合、リソース マネージャーは、メイン アセンブリにリソースを探しているなら、MissingManifestResourceException 例外をスローし、サテライト アセンブリにリソースを探しているなら、MissingSatelliteAssemblyException 例外をスローします。 例外がスローされるのは、GetStringGetObject などのリソース取得メソッドを呼び出すときであり、ResourceManager オブジェクトをインスタンス化するときではないことに注意してください。

通常、例外は次の条件下でスローされます。

  • 適切なリソース ファイルまたはサテライト アセンブリが存在しません。 リソース マネージャーによって、アプリの既定のリソースがメイン アプリ アセンブリに埋め込まれていることが期待される場合に、それらが存在しません。 NeutralResourcesLanguageAttribute 属性によって、アプリの既定のリソースがサテライト アセンブリに存在することが指示されている場合に、そのアセンブリが見つかりません。 アプリをコンパイルするときに、リソースがメイン アセンブリに埋め込まれているか、あるいは必要なサテライト アセンブリが生成され、適切な名前がついていることを確認します。 その名前は appName.resources.dll の形式をとる必要があります。また、含まれているリソースのカルチャに基づいて名前をつけたディレクトリに配置する必要があります。

  • アプリに既定のカルチャ、あるいはニュートラル カルチャがありません。 ソース コード ファイルまたはプロジェクトの情報ファイル (Visual Basic アプリでは AssemblyInfo.vb、C# アプリでは AssemblyInfo.cs) に NeutralResourcesLanguageAttribute 属性を追加します。

  • ResourceManager(String, Assembly) コンストラクターの baseName パラメーターに .resources ファイルの名前が指定されていません。 名前には、リソース ファイルの完全修飾名前空間を含める必要がありますが、そのファイル名拡張子は不要です。 通常、Visual Studio で作成されるリソース ファイルは名前空間の名前を含みますが、コマンド プロンプトで作成されコンパイルされたリソース ファイルはそれを含みません。 次のユーティリティをコンパイルして実行すると、埋め込まれた .resources ファイルの名前を判断できます。 これは、メイン アセンブリまたはサテライト アセンブリの名前をコマンド ライン パラメーターとして指定するコンソール アプリです。 これは、リソース マネージャーがリソースを正しく特定できるように、baseName パラメーターに指定するべき文字列を表示します。

    using System;
    using System.IO;
    using System.Reflection;
    
    public class Example0
    {
       public static void Main()
       {
          if (Environment.GetCommandLineArgs().Length == 1) { 
             Console.WriteLine("No filename.");
             return;
          }
          
          string filename = Environment.GetCommandLineArgs()[1].Trim();
          // Check whether the file exists.
          if (! File.Exists(filename)) {
             Console.WriteLine("{0} does not exist.", filename);
             return;
          }   
          
          // Try to load the assembly.
          Assembly assem = Assembly.LoadFrom(filename);
          Console.WriteLine("File: {0}", filename);
             
          // Enumerate the resource files.
          string[] resNames = assem.GetManifestResourceNames();
          if (resNames.Length == 0)
             Console.WriteLine("   No resources found.");
    
          foreach (var resName in resNames)
             Console.WriteLine("   Resource: {0}", resName.Replace(".resources", ""));
    
          Console.WriteLine();
       }
    }
    
    Imports System.IO
    Imports System.Reflection
    Imports System.Resources
    
    Module Example
       Public Sub Main()
          If Environment.GetCommandLineArgs.Length = 1 Then 
             Console.WriteLine("No filename.")
             Exit Sub
          End If
          Dim filename As String = Environment.GetCommandLineArgs(1).Trim()
          ' Check whether the file exists.
          If Not File.Exists(filename) Then
             Console.WriteLine("{0} does not exist.", filename)
             Exit Sub
          End If   
          
          ' Try to load the assembly.
          Dim assem As Assembly = Assembly.LoadFrom(filename)
          Console.WriteLine("File: {0}", filename)
             
          ' Enumerate the resource files.
          Dim resNames() As String = assem.GetManifestResourceNames()
          If resNames.Length = 0 Then
             Console.WriteLine("   No resources found.")
          End If
          For Each resName In resNames
             Console.WriteLine("   Resource: {0}", resName.Replace(".resources", ""))
          Next
          Console.WriteLine()
       End Sub
    End Module
    

アプリケーションの現在のカルチャを明示的に変更する場合、リソース マネージャーは CultureInfo.CurrentUICulture プロパティではなく CultureInfo.CurrentCulture プロパティの値に基づいてリソース セットを取得することも覚えておいてください。 通常は、一方の値を変更するなら、もう一方も変更する必要があります。

リソースのバージョン管理

アプリの既定のリソースを含むメイン アセンブリは、アプリのサテライト アセンブリから切り離されているため、サテライト アセンブリを再配置せずに、メイン アセンブリの新しいバージョンをリリースできます。 既存のサテライト アセンブリを使用し、メイン アセンブリの新しいバージョンと一緒にそれらを再配置しないようにリソース マネージャーに指示するためには、SatelliteContractVersionAttribute 属性を使用します。

サテライト アセンブリのバージョン管理サポートの詳細については、リソースの取得の記事を参照してください。

<satelliteassemblies> 構成ファイル ノード

Note

このセクションは、.NET Framework アプリに固有です。

Web サイト (HREF .exe ファイル) から展開と実行がされる実行可能ファイルの場合、ResourceManager オブジェクトは Web 経由でサテライト アセンブリのプローブを作成する可能性があり、アプリのパフォーマンスが低下することがあります。 パフォーマンスの問題を排除するために、アプリと一緒に配置したサテライト アセンブリへのプローブを制限できます。 これを行うには、アプリの構成ファイル内に <satelliteassemblies> ノードを作成し、アプリの特定のカルチャのセットを配置したことと、ResourceManager オブジェクトがそのノードに示されていないカルチャのプローブを作成するべきではないことを指定します。

Note

<satelliteassemblies> ノードの作成より推奨される方法は、ClickOnce 配置マニフェストの機能を使用することです。

アプリの構成ファイルで、次のようなセクションを作成します。

<?xml version ="1.0"?>
<configuration>
  <satelliteassemblies>
    <assembly name="MainAssemblyName, Version=versionNumber, Culture=neutral, PublicKeyToken=null|yourPublicKeyToken">
      <culture>cultureName1</culture>
      <culture>cultureName2</culture>
      <culture>cultureName3</culture>
    </assembly>
  </satelliteassemblies>
</configuration>

この構成情報は次のように編集します。

  • 配置するメイン アセンブリごとに <assembly> ノードを 1 つ以上指定し、各ノードで完全修飾アセンブリ名を指定します。 MainAssemblyName の場所にメイン アセンブリの名前を指定し、メイン アセンブリに対応する VersionPublicKeyToken、および Culture 属性の値を指定します。

    Version 属性には、アセンブリのバージョン番号を指定します。 たとえば、アセンブリの最初のリリースでは、バージョン番号は 1.0.0.0 になるでしょう。

    PublicKeyToken 属性には、厳密な名前でアセンブリに署名していない場合は、キーワード null を指定し、アセンブリに署名した場合は、公開キー トークンを指定します。

    Culture 属性には、メイン アセンブリを指定するためにキーワード neutral を指定し、ResourceManager クラスが <culture> ノードに示されているカルチャに対してのみプローブを作成するようにします。

    完全修飾アセンブリ名の詳細については、アセンブリ名の記事を参照してください。 厳密な名前付きアセンブリの詳細については、「厳密な名前付きアセンブリの 作成と使用」を参照してください。

  • "fr-FR" などの特定のカルチャ名、または "fr" などのニュートラル カルチャ名を持つ <culture> ノードを 1 つ以上指定します。

<satelliteassemblies> ノード下に示されていないアセンブリにリソースが必要な場合、ResourceManager クラスは標準のプローブ規則を使用してカルチャにプローブを作成します。

Windows 8.x アプリ

重要

この ResourceManager クラスは Windows 8.x アプリでサポートされていますが、その使用はお勧めしません。 このクラスは、Windows 8.x アプリで使用できるポータブル クラス ライブラリ プロジェクトを開発する場合にのみ使用します。 Windows 8.x アプリからリソースを取得するには、代わりに Windows.ApplicationModel.Resources.ResourceLoader クラスを使用します。

Windows 8.x アプリの場合、クラスは ResourceManager パッケージ リソース インデックス (PRI) ファイルからリソースを取得します。 単一の PRI ファイル (アプリケーション パッケージの PRI ファイル) には、既定のカルチャとすべてのローカライズされたリソースの両方が含まれています。 1 つ以上の XML リソース (.resw) 形式のリソース ファイルから PRI ファイルを作成するには、MakePRI ユーティリティを使用します。 Visual Studio プロジェクトに含まれているリソースは、Visual Studio が自動的に PRI ファイルの作成とパッケージ化のプロセスを処理します。 その後、.NET ResourceManager クラスを使用して、アプリまたはライブラリのリソースにアクセスできます。

Windows 8.x アプリのオブジェクトは、デスクトップ アプリの場合と同じ方法でインスタンス化 ResourceManager できます。

それから、GetString(String) メソッドに取得するリソースの名前を渡すことによって、特定のカルチャのリソースにアクセスすることができます。 既定では、このメソッドは、呼び出しを行ったスレッドの現在の UI カルチャによって決定されるカルチャのリソースを返します。 リソースの名前と、取得するリソースのカルチャを表す CultureInfo オブジェクトを GetString(String, CultureInfo) メソッドに渡すことによって、特定のカルチャのリソースも取得できます。 現在の UI カルチャまたは指定したカルチャのリソースが見つからない場合、リソース マネージャーは UI 言語フォールバック リストを使用して、適切なリソースを見つけます。

次の例では、明示的なカルチャおよび暗黙的な現在の UI カルチャを使用して、メイン アセンブリとサテライト アセンブリから文字列リソースを取得する方法を示します。 詳細については、サテライト アセンブリの作成の記事内の「グローバル アセンブリ キャッシュにインストールされていないサテライト アセンブリのディレクトリの場所」セクションを参照してください。

この例を実行するには、

  1. アプリ ディレクトリで、次のリソース文字列を含む rmc.txt という名前のファイルを作成します。

    day=Friday
    year=2006
    holiday="Cinco de Mayo"
    
  2. 次のように、リソース ファイル ジェネレーター を使用して、入力ファイル rmc.txt からリソース ファイル rmc.resources を生成します。

    resgen rmc.txt
    
  3. アプリ ディレクトリのサブディレクトリを作成し、"es-MX" という名前をつけます。 これは、続く 3 つの手順で作成するサテライト アセンブリのカルチャ名です。

  4. 次のリソース文字列を含む rmc.es-MX.txt という名前のファイルを es-MX のディレクトリに作成します。

    day=Viernes
    year=2006
    holiday="Cinco de Mayo"
    
  5. 次のように、リソース ファイル ジェネレーター を使用して、入力ファイル rmc.es-MX.txt からリソース ファイル rmc.es-MX.resources を生成します。

    resgen rmc.es-MX.txt
    
  6. この例のファイル名が rmc.vb または rmc.cs のどちらかであると仮定します。 下記のソース コードをファイルにコピーします。 それをコンパイルし、メイン アセンブリのリソース ファイルである rmc.resources を実行可能アセンブリに埋め込みます。 Visual Basic コンパイラを使用している場合、構文は次のようになります。

    vbc rmc.vb /resource:rmc.resources
    

    これは C# コンパイラの対応する構文です。

    csc /resource:rmc.resources rmc.cs
    
  7. アセンブリ リンカー を使用して、サテライト アセンブリを作成します。 アプリのベース名が rmc なら、サテライト アセンブリの名前は rmc.resources.dll である必要があります。 サテライト アセンブリは es-MX ディレクトリに作成する必要があります。 es-MX が現在のディレクトリの場合は、このコマンドを使用します。

    al /embed:rmc.es-MX.resources /c:es-MX /out:rmc.resources.dll
    
  8. rmc.exe を実行して、埋め込まれたリソース文字列の取得と表示を行います。

    using System;
    using System.Globalization;
    using System.Resources;
    
    class Example2
    {
        public static void Main()
        {
            string day;
            string year;
            string holiday;
            string celebrate = "{0} will occur on {1} in {2}.\n";
    
            // Create a resource manager.
            ResourceManager rm = new ResourceManager("rmc",
                                     typeof(Example).Assembly);
    
            Console.WriteLine("Obtain resources using the current UI culture.");
    
            // Get the resource strings for the day, year, and holiday
            // using the current UI culture.
            day = rm.GetString("day");
            year = rm.GetString("year");
            holiday = rm.GetString("holiday");
            Console.WriteLine(celebrate, holiday, day, year);
    
            // Obtain the es-MX culture.
            CultureInfo ci = new CultureInfo("es-MX");
    
            Console.WriteLine("Obtain resources using the es-MX culture.");
    
            // Get the resource strings for the day, year, and holiday
            // using the specified culture.
            day = rm.GetString("day", ci);
            year = rm.GetString("year", ci);
            holiday = rm.GetString("holiday", ci);
            // ---------------------------------------------------------------
            // Alternatively, comment the preceding 3 code statements and
            // uncomment the following 4 code statements:
            // ----------------------------------------------------------------
            // Set the current UI culture to "es-MX" (Spanish-Mexico).
            //    Thread.CurrentThread.CurrentUICulture = ci;
    
            // Get the resource strings for the day, year, and holiday
            // using the current UI culture. Use those strings to
            // display a message.
            //    day  = rm.GetString("day");
            //    year = rm.GetString("year");
            //    holiday = rm.GetString("holiday");
            // ---------------------------------------------------------------
    
            // Regardless of the alternative that you choose, display a message
            // using the retrieved resource strings.
            Console.WriteLine(celebrate, holiday, day, year);
        }
    }
    /*
    This example displays the following output:
    
       Obtain resources using the current UI culture.
       "5th of May" will occur on Friday in 2006.
    
       Obtain resources using the es-MX culture.
       "Cinco de Mayo" will occur on Viernes in 2006.
    */
    
    Imports System.Resources
    Imports System.Reflection
    Imports System.Threading
    Imports System.Globalization
    
    Class Example4
        Public Shared Sub Main()
            Dim day As String
            Dim year As String
            Dim holiday As String
            Dim celebrate As String = "{0} will occur on {1} in {2}." & vbCrLf
    
            ' Create a resource manager. 
            Dim rm As New ResourceManager("rmc", GetType(Example4).Assembly)
    
            Console.WriteLine("Obtain resources using the current UI culture.")
    
            ' Get the resource strings for the day, year, and holiday 
            ' using the current UI culture. 
            day = rm.GetString("day")
            year = rm.GetString("year")
            holiday = rm.GetString("holiday")
            Console.WriteLine(celebrate, holiday, day, year)
    
            ' Obtain the es-MX culture.
            Dim ci As New CultureInfo("es-MX")
    
            Console.WriteLine("Obtain resources using the es-MX culture.")
    
            ' Get the resource strings for the day, year, and holiday 
            ' using the es-MX culture.  
            day = rm.GetString("day", ci)
            year = rm.GetString("year", ci)
            holiday = rm.GetString("holiday", ci)
    
            ' ---------------------------------------------------------------
            ' Alternatively, comment the preceding 3 code statements and 
            ' uncomment the following 4 code statements:
            ' ----------------------------------------------------------------
            ' Set the current UI culture to "es-MX" (Spanish-Mexico).
            '    Thread.CurrentThread.CurrentUICulture = ci
            ' Get the resource strings for the day, year, and holiday 
            ' using the current UI culture. 
            '    day  = rm.GetString("day")
            '    year = rm.GetString("year")
            '    holiday = rm.GetString("holiday")
            ' ---------------------------------------------------------------
    
            ' Regardless of the alternative that you choose, display a message 
            ' using the retrieved resource strings.
            Console.WriteLine(celebrate, holiday, day, year)
        End Sub
    End Class
    ' This example displays the following output:
    'Obtain resources using the current UI culture.
    '"5th of May" will occur on Friday in 2006.
    '
    'Obtain resources using the es-MX culture.
    '"Cinco de Mayo" will occur on Viernes in 2006.