いまさらなのですが、サテライトアセンブリを使用してメッセージをローカライズする方法のメモを記載します。動作確認は、Visual Studio 2010 で開発したプログラムを Windows Server 2008 R2 上で動作させて行っています。

1. リソースファイルを使用するソリューションの作成

今回作成するソリューションの構成は次の通りです。HelloWorld はコンソールプロジェクトです。SatelliteLibrary は クラスライブラリプロジェクトです。SatelliteLibrary プロジェクトのResources フォルダにリソースファイルを作成します。それぞれの resx ファイル にリソース文字列を格納します。resxには画像なども含めることができますが、今回は文字列のみ格納します。同プロジェクトのMessageUtil.cs で、Messages.xx.resx に格納された文字列を使用します。

Message.resx の内容は次の通り日本語が格納されます。カルチャが含まれないデフォルトのリソースファイルなので、コンパイルすると、SatelliteLibrary.dll に含まれます。

英語用のリソースファイル Mesage.en.resx は次の通りです。enという言語コードが含まれるので、コンパイルすると、enというフォルダにサテライトアセンブリとして格納されます。

ドイツ語用のリソースファイル Mesage.de.resx は次の通りです。deという言語コードが含まれるので、コンパイルすると、deというフォルダにサテライトアセンブリとして格納されます。

Message.xx.resx を使用するプログラムは次のようになっています。GetMessage は引数に リソースの名前(ID)とCultureInfor を取り、適切なサテライトアセンブリからリソースを取得して、文字列を返します。CultureInfo を指定しないメソッドも用意しています。この場合、スレッドのUIカルチャに従ってどの言語ようのリソースを取得するかが決定されます。CultreInfo で指定されたカルチャがない場合、埋め込まれたリソース(Messages.resx)ないの文字が返されます。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Resources;

namespace SatelliteLibrary
{
    public static class MessageUtil
    {
        public static string GetMessage(string msgid, CultureInfo culture)
        {
            ResourceManager rm = new ResourceManager("SatelliteLibrary.Resources.Messages", typeof(MessageUtil).Assembly);
            return rm.GetString(msgid, culture);
        }
        public static string GetMessage(string msgid)
        {
            ResourceManager rm = new ResourceManager("SatelliteLibrary.Resources.Messages", typeof(MessageUtil).Assembly);
            return rm.GetString(msgid);
        }
    }
}

SatelliteLibrary.dll を使用するHelloWorld プロジェクトの Program.cs は次のようになっています。既定のカルチャを使用する方法、カルチャを指定して文字列を取得する2通りの方法でリソースファイルから文字列を取得しています。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SatelliteLibrary;

namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            // 既定のカルチャ
            Console.WriteLine(MessageUtil.GetMessage("Hello"));
            // 英語のカルチャ
            Console.WriteLine(MessageUtil.GetMessage("Hello", new System.Globalization.CultureInfo("en")));
            // ドイツ語のカルチャ
            Console.WriteLine(MessageUtil.GetMessage("Hello", new System.Globalization.CultureInfo("de")));
            // 米国英語の指定
            Console.WriteLine(MessageUtil.GetMessage("Hello", new System.Globalization.CultureInfo("en")));
            // スペイン語のカルチャ(リソースがないので既定の日本語が表示される)
            Console.WriteLine(MessageUtil.GetMessage("Hello", new System.Globalization.CultureInfo("es")));

            Console.ReadLine();
        }

   }
}

ソリューションをDebugモードでコンパイルすると、Debugフォルダは以下は次のようになり、de, en フォルダが作成されます。既定の日本語用のresxファイルはSatelliteLibrary.dll に埋め込まれるためフォルダは作成されません。

deフォルダを表示すると、下図のようにSatelliteLibrary.resources.dll という名前のサテライトアセンブリが配置されていることが確認できます。

プログラムを実行すると、下図のように適切な言語のリソースが表示されることがわかります。さいごに日本語であいさつが表示されているのは、スペイン語のサテライトアセンブリがないため、既定のリソースファイルから文字列が取得されたためです。

2. サテライトアセンブリをコマンドラインから個別に作成する

上記のソリューションでは、プロジェクトに各言語用のリソースファイルを作成することで、コンパイル時に自動的にサテライトアセンブリが作成されました。サテライトアセンブリは別個に作成することができます。今回は上記サンプルのProgram.csのmainで指定されているが、サテライトアセンブリが存在しないスペイン語用のサテライトアセンブリを作成してみます。

2.1 リソースファイルの準備

サテライトアセンブリは、次の3種類のリソーソファイルのいづれかから作成します。最終的には resources ファイルを作成します。最初の例で示したように、Visual Studio 上では.resx ファイルを使用して簡単にサテライトアセンブリを作成できます。

テキスト ファイル形式のリソース
http://msdn.microsoft.com/ja-jp/library/s9eey0h7.aspx

.Resx ファイル形式のリソース
http://msdn.microsoft.com/ja-jp/library/ekyft91f.aspx

.Resources ファイル形式のリソース
http://msdn.microsoft.com/ja-jp/library/zew6azb7.aspx

今回はテキストファイルからリソースファイルを作成します。ファイルの文字コードはUTF-8にしてください。ファイルを次のように編集します。;や#はコメントです。

 

Visual Studio 用のコマンドプロンプトを起動します。 リソースファイルのあるフォルダまで移動して、 resgen Messages.es.txt と入力します。処理が正常終了すると、 Messages.es.resources ファイルが生成されます。resgen は テキストファイル形式のリソースから resx, resources を作成したり、その逆にリソースファイルを生成できます。

resgen の使い方
http://msdn.microsoft.com/ja-jp/library/ccec7sz1.aspx

次に、 作成した resources ファイルを al.exe を使用してサテライトアセンブリを生成します。次のようにコマンドを入力します。コマンドラインオプションを間違えないように注意してください。

al /t:lib /embed:Messages.es.resources,SatelliteLibrary.Resources.Messages.es.resources /culture:es /out:SatelliteLibrary.resources.dll

/cultureでカルチャ用の文字列を指定して下さい。出力ファイル名は、サテライトアセンブリ名(今回は SatelliteLibrary.resources.dll) 、 dllを作成するので /t:lib を指定します。そして、 /embed オプションで、 リソースファイルとdll内でのリソースファイルの位置をカルチャをつけて正確に指定するようにしてください。リソースファイルとリソースのdll内でのパスはカンマ( , ) で区切ります。

al.exe が成功すると、 SatelliteLibrary.resources.dll とうサテライトアセンブリが作成されます。アセンブリリンカ(al.exe) の使い方は次のリンクを参照してください。

Al.exe (アセンブリ リンカー)
http://msdn.microsoft.com/ja-jp/library/c405shex.aspx

最初のソリューションをコンパイルしたときにDebugフォルダに配置された HelloWorld.exe と SatelliteLibrary.dll があるフォルダに es という スペイン語用のフォルダを作成し、作成された サテライトアセンブリを配置します。プログラムを再度実行すると、今度は、最後に、テキストファイルから作成されたスペイン語の挨拶がコンソールに出力されることが確認できます。

3. まとめ

説明は以上です。いまさらですが、サテライトアセンブリを使用した ローカリゼーションについて復習してみました。

サンプルでは、言語コードのみを使用したサテライトアセンブリの方法を記載しました。紹介した方法で、ja-jp , es-es など、言語コードと地域コードを使用したサテライトアセンブリを作成することも同じように可能です。