質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

.NET Framework 4.0

Microsoft Windows用のソフトウェア開発環境/実行環境である .NET Frameworkの4番目のメジャーバージョンです。

Q&A

解決済

1回答

7207閲覧

EXEファイルと別のフォルダに配置したDLLの多国語対応

silverthyme

総合スコア10

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

.NET Framework 4.0

Microsoft Windows用のソフトウェア開発環境/実行環境である .NET Frameworkの4番目のメジャーバージョンです。

0グッド

1クリップ

投稿2016/09/05 10:45

編集2016/09/08 11:02

###前提・実現したいこと
Visual C#のWindows Formsでアプリケショーンを作成しています。
次のサイトを参考にしながら、EXEファイルとは別のフォルダ(サブフォルダではい)に配置したDLLを参照するアプリケーションを作成しています(DLLをプラグインとして後から追加可能とするため。)

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

(この方法であれば期待通りの言語で表示されるのですが「前提・実現したいこと」の解決とは少し異なります)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Tipo

2016/09/06 11:48

EXEとは別のフォルダに配置したDLL内で Thread.CurrentThread.CurrentUICulture は 'ja' と 'ja-JP' のどちらになっているでしょうか。
guest

回答1

0

自己解決

補足情報にも書いた通り、EXEファイルと同じ階層にプラグイン用のサブフォルダを作りそこにDLLを配置して、probingで参照する仕様に変更となりました。
ランタイムがアセンブリを検索する方法 - msdn

質問当時のWindows 7では、ユーザーがエクスプローラーで'Program Files'フォルダのサブフォルダへコピーしたファイルがアプリケーションから参照できないという現象がよくあった(実はUACの仮想化によりViratual Storeを参照している)ので、UACにより保護されていないフォルダに配置されたDLLも参照出来たらいいなということで質問のような仕様が発案されたのですが、結局変更後の仕様に落ち着き現在に至っています。

質問内容に対する解決策としては技術的にズレており、またteratailには質問を撤回する機能がないため閉じずにいたのですが、何年も回答中の状態で放置しておくのも気持ち悪いので本件については「解決済」とさせていただきます(実際に変更後の仕様でよしとなっている為)

投稿2021/12/03 04:14

silverthyme

総合スコア10

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問