###前提・実現したいこと
Visual C#のWindows Formsでアプリケショーンを作成しています。
次のサイトを参考にしながら、EXEファイルとは別のフォルダ(サブフォルダではい)に配置したDLLを参照するアプリケーションを作成しています(DLLをプラグインとして後から追加可能とするため。)
- exeと別フォルダのDLLを参照する方法 : 3流プログラマのメモ書き
- DLLの配置場所を変更する(probing, codebase, developmentMode) - tekkの日記 C#,VB.NET
DLLを厳密名で署名してアプリケーション構成ファイルにDLLのフルパスをCodeBaseで指定して公開キートークンを記述することで、EXEとは別のフォルダに配置したDLLを参照することが出来るようになりました。
次にこのアプリケーションを多国語に対応させるために、EXE内に定義したフォームと、EXEとは別のフォルダに配置したDLL内に定義したフォーム各々のLanguageプロパティにおいて「日本語」等のローカライズ言語を指定してその言語のUIを作成し、Language=(既定値)のフォームには英語のUIを作成しましたが、次節のような問題が発生しており多言語対応がうまくいきません。
そこで標題の件ですが、EXEファイルとは別のサブフォルダではないフォルダに配置したDLLに於いてLanguage=(既定値)以外の言語に対応させるにはどうしたらよいのでしょうか?
###発生している問題・エラーメッセージ
- EXE内で定義されているフォームはThread.CurrentThread.CurrentCultureの値に応じて、期待通りの言語のUIが表示される(これはOK)。
- EXEとは別のフォルダに配置したDLL内で定義されているフォームはThread.CurrentThread.CurrentCultureの値に関わらず「Language=(既定値)」で作成したUIが表示されてしまう。今回の例では日本語のWindowsで実行しているにも関わらず英語で表示されてしまう。
ちなみに、EXEと同じフォルダ内に配置したDLL(こちらは厳密な署名なし)で定義されているフォームについては期待通りの言語で表示されます。
###該当のソースコード
EXE(仮にC:\Program Files\Foo\Hoge.exe)と、EXEとは別のフォルダに配置するDLL(仮にC:\Bar\Plugins\Fuga.dll)は別々のプロジェクトで作成し、Hoge.exeのプロジェクトからC:\Bar\Plugins\Fuga.dllのアセンブリを「ローカルコピー = False」で参照しています。
- Hogeプロジェクト(Hoge.exe)内のコード
(MainFormのGUIはデザイナ上で「Language=(既定値)」と「Language=日本語」の2種類を作成。(既定値)のときは英語とする)
C#
1/* hoge.cs */ 2namespace Hoge 3{ 4 public partial class MainForm : Form 5 { 6 public MainForm() 7 { 8 InitializeComponent(); 9 } 10 private void MainForm_Load(object sender, EventArgs e) 11 { 12 this.label1.Text = Thread.CurrentThread.CurrentUICulture.DisplayName; 13 this.label2.Text = Properties.Resources.AppTest; 14 } 15 private void button1_Click(object sender, EventArgs e) 16 { 17 Fuga.DLLForm frm = new Fuga.DLLForm(); 18 frm.Show(); 19 } 20 } 21}
XML
1<!-- アプリケーション構成ファイル(Hoge\App.config) --> 2<?xml version="1.0" encoding="utf-8" ?> 3<configuration> 4 <runtime> 5 <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 6 <dependentAssembly> 7 <assemblyIdentity name="Fuga" 8 publicKeyToken="****************" 9 culture="neutral" /> 10 <codeBase version="1.0.0.0" href="file:///C:/Bar/Plugins/Fuga.dll"/> 11 </dependentAssembly> 12 </assemblyBinding> 13 </runtime> 14</configuration>
(Hoge\Properties\Resources.ja.resx ファイル) 名前: AppTest 値: 日本語フォーム
(Hoge\Properties\Resources.resx ファイル) 名前: AppTest 値: English Form
- EXEとは別フォルダ(C:\Bar\Plugins)に配置するDLL(Fuga.dll)のプロジェクト内のコード
(DLLFormのGUIはデザイナ上で「Language=(既定値)」と「Language=日本語」の2種類を作成。(既定値)のときは英語とする)
C#
1namespace Fuga 2{ 3 public partial class DLLForm : Form 4 { 5 public DLLForm() 6 { 7 InitializeComponent(); 8 } 9 private void DLLForm_Load(object sender, EventArgs e) 10 { 11 this.label1.Text = Thread.CurrentThread.CurrentUICulture.DisplayName; 12 // 日本語Windowsで実行すると、この label1 には「日本語」と表示される。 13 14 this.label2.Text = Properties.Resources.DllTest; 15 // label2 には日本語版Windowsでも「English Plugin」と表示されてしまう。 16 } 17 } 18}
(Fuga\Properties\Resources.ja.resx ファイル) 名前: DllTest 値: 日本語プラグイン
(Fuga\Properties\Resources.resx ファイル) 名前: DllTest 値: English Plugin
なお、 C:\Bar\Plugins\ja\ にFuga.dllの日本語リソースの Fuga.resources.dll を配置しています。
###試したこと
Fuga.dllのプロジェクト内でもアプリケーション構成ファイルを作成して、C:\Bar\Plugins\jaフォルダ内のFuga.resources.dllのパスを指定してみましたが、結果は変わりませんでした。
XML
1<!-- アプリケーション構成ファイル(Fuga\App.config) --> 2<?xml version="1.0" encoding="utf-8" ?> 3<configuration> 4 <runtime> 5 <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 6 <dependentAssembly> 7 <assemblyIdentity name="Fuga" 8 publicKeyToken="****************" 9 culture="neutral" /> 10 <codeBase version="1.0.0.0" href="file:///C:/Bar/Plugins/ja/Fuga.resources.dll"/> 11 </dependentAssembly> 12 </assemblyBinding> 13 </runtime> 14</configuration>
あるいはculture="neutral"を次のように変えてみたり、
XML
1<!-- アプリケーション構成ファイル(Fuga\App.config)(抜粋) --> 2<assemblyIdentity name="Fuga" 3 publicKeyToken="****************" 4 culture="ja" /> 5<codeBase version="1.0.0.0" href="file:///C:/Bar/Plugins/Fuga.dll"/> 6<!-- あるいは↓ --> 7<!-- codeBase version="1.0.0.0" href="file:///C:/Bar/Plugins/ja/Fuga.resources.dll"/ -->
はたまた、<runtime>~</runtime>内を次のように変えてみたり、
XML
1<!-- アプリケーション構成ファイル(Fuga\App.config)(抜粋) --> 2<runtime> 3 <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 4 <probing privatePath="ja"/> 5 </assemblyBinding> 6</runtime>
等々、アプリケーション構成ファイルをいじってみましたが、Fuga.dll内のフォームの表示は日本語になりませんでした。
2016年9月8日 追加
EXEファイルとは別のフォルダに配置したDLLで Thread.CurrentThread.CurrentUICulture の値を調べてみました。同DLLのフォーム(DLLForm)にTextBoxを二つ貼り付けて、次のコードで検証
C#
1textBox1.Text = Thread.CurrentThread.CurrentUICulture.TextInfo.CultureName; 2textBox2.Text = Thread.CurrentThread.CurrentUICulture.ToString();
[結果]
EXE側で、Fuga.DLLForm frm = new Fuga.DLLForm();する前に
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("ja");
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("ja");
としたとき
textBox1: ja-JP textBox2: ja
同じく(中略)CultureInfo.GetCultureInfo("ja-JP");としたとき
textBox1: ja-JP textBox2: ja-JP
試しにDLLFormのLanguageプロパティを「日本語 (日本)」にした版も用意してみましたが、相変わらず(既定値)のUIが表示されてしまう状況です。
###補足情報(言語/FW/ツール等のバージョンなど)
- 開発環境は以下の通りです。
Visual Studio Professional 2013
.NET Framework 4.0
Windows Form
DLLのプラグイン化にはMEF(Managed Extensibility Framework)を使用していますが、MEFを用いていなくても同問題が発生します。
- 残念ながら…
今回は時間切れと言うことで、EXEファイルと同じ階層にプラグイン用のサブフォルダを作ってそこにDLLを配置して、probingで参照する仕様に変更となりました。
ランタイムがアセンブリを検索する方法 - msdn
(この方法であれば期待通りの言語で表示されるのですが「前提・実現したいこと」の解決とは少し異なります)

回答1件
あなたの回答
tips
プレビュー