2019年7月19日金曜日

古い.NET Frameworkでスレッドのデフォルトカルチャを変更する

.NET Framework 4.5から、CultureInfo.DefaultThreadCurrentCultureCultureInfo.DefaultThreadCurrentUICultureというプロパティが存在します。
これを設定しておくと、新しいスレッドを生成したときのカルチャを変更することができます。
逆にいうと、これより古いバージョンでは新しいスレッドのカルチャを変更する機能が提供されていなかったのです。
完全に自分で書いたコードであれば、スレッドの処理開始直後にカルチャを変更する方法で逃げることができました。
しかしライブラリの裏でスレッドを生成されると厄介です。
カルチャを変更したいときに手も足も…いえ、方法はありました。
リフレクションで無理やり更新してしまえば良いのです。
というわけでクラス内部のメンバを調査し、書き換えるコードを用意してみました。

using System.Globalization;
using System.Reflection;

// 変更したいカルチャ
CultureInfo culture = new CultureInfo("ja-JP");

// 固定値
Type targetType = typeof(CultureInfo);
BindingFlags getFlag = BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetField;
BindingFlags setFlag = BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.SetField;

// .NET Framework 3.5 以下
FieldInfo userDefaultCulture = targetType.GetField("m_userDefaultCulture", getFlag);
if (userDefaultCulture != null)
{
    userDefaultCulture.SetValue(CultureInfo.CurrentCulture, targetType, setFlag, null, CultureInfo.InvariantCulture);
}

FieldInfo userDefaultUICulture = targetType.GetField("m_userDefaultUICulture", getFlag);
if (userDefaultUICulture != null)
{
    userDefaultUICulture.SetValue(CultureInfo.CurrentUICulture, targetType, setFlag, null, CultureInfo.InvariantCulture);
}

// .NET Framework 4.0
FieldInfo defaultThreadCurrentCulture = targetType.GetField("s_DefaultThreadCurrentCulture", getFlag);
if (userDefaultCulture != null)
{
    userDefaultCulture.SetValue(CultureInfo.CurrentCulture, targetType, setFlag, null, CultureInfo.InvariantCulture);
}

FieldInfo defaultThreadCurrentUICulture = targetType.GetField("s_DefaultThreadCurrentUICulture", getFlag);
if (userDefaultUICulture != null)
{
    userDefaultUICulture.SetValue(CultureInfo.CurrentUICulture, targetType, setFlag, null, CultureInfo.InvariantCulture);
}

// .NET Framework 4.5 以上
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
こんな感じのコードを、プログラムの冒頭あたりで呼び出せばOKです。
実は3.5の方は確認したのですが、4.0の方はちゃんと動くか自信がないです。
動かなかったら適当に修正して使用してください。
Written with StackEdit.

0 件のコメント:

コメントを投稿