gpt4 book ai didi

multithreading - 如何独立于操作系统语言为多线程 .NET 进程设置 UI 语言?

转载 作者:行者123 更新时间:2023-12-02 05:08:41 27 4
gpt4 key购买 nike

问题:

我有一个在 Windows 7 上开发的 C# .NET 2.0 应用程序,它翻译了多种语言的资源(例如 zh-CHS 中文,es 西类牙文等) .).

我有一个客户想要以英语运行他们的 Windows 7 操作系统,但以西类牙语(es)运行我的 .NET 应用程序。

我的应用程序是多线程的,因此仅更改主 GUI 线程的文化不足以满足我的需求(相信我,我试过了)。这是因为通过 GUI 向用户显示的其他字符串是在其他线程上生成的。为了获得 100% 的完整覆盖率,我需要手动设置每个单独线程的文化,以确保资源文件中的所有文本都使用正确的语言。因为我的产品基本上是其他开发组编写的其他插件的框架,所以我无法控制在其他插件创建的线程中执行的操作。因此,手动更改每个线程的文化不是一个有效的选择。

我正在寻找一种为应用程序设置整体语言的方法,而无需更改任何操作系统用户设置。

在做一些研究时,我遇到了以下为进程设置首选 UI 语言的方法:SetProcessPreferredUILanguages

阅读完这篇文章后,看来这个电话正是我要找的。但是,当我在我的 C# 应用程序的 Main 方法中实现此调用时,它似乎没有执行任何操作。

以下代码的返回值为真,但我从未看到我的 GUI 应用程序以西类牙语显示文本。

    [DllImport("Kernel32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
public static extern Boolean SetProcessPreferredUILanguages(UInt32 dwFlags, String pwszLanguagesBuffer, ref UInt32 pulNumLanguages);

public void SetLanguages()
{
uint numLangs = 0;
string[] langs = new string[3];
uint MUI_LANGUAGE_NAME = 0x8; // Use ISO language (culture) name convention

langs[0] = "es\u0000";
langs[1] = "zh-CHS\u0000";
langs[2] = "en-US\u0000";

numLangs = (uint)langs.Length;

if (SetProcessPreferredUILanguages(MUI_LANGUAGE_NAME, String.Concat(langs), ref numLangs))
{
Console.WriteLine("Successfully changed UI language");
}
}

为了成功运行加载了西类牙语资源的 GUI 应用程序,我还缺少其他东西吗?

我正在尝试为 Building MUI Applications 实现 MSDN 页面底部表格的第二个选项。 ,其中我有特定于应用程序的 UI 语言设置,并希望获得所需的资源加载结果:

Application calls MUI API to set application-specific UI languages or process-preferred UI languages and then calls standard resource loading functions. Resources are returned in the languages set by the application or system languages.

我已成功设置进程首选 UI 语言,但我的资源未以我期望的语言加载。一位评论者提到此调用仅适用于非托管资源,我无法 100% 验证这一点,但行为似乎表明情况确实如此。

我不可能是唯一尝试过以这种方式实现 .NET 应用程序的人。令人沮丧的是,没有关于如何执行此操作的更多信息。

提前致谢

凯尔

最佳答案

从 .NET 4.5 开始 CultureInfo.DefaultThreadCurrentCulture属性允许您为当前应用程序域中的线程设置默认文化。除此之外,我还没有找到优雅地做到这一点的方法。

下面是将向您展示如何重现此行为的代码:

using System;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;

namespace SimpleMultithreadedTestForCulture {

class Program {

static void Main() {
const double value = 12345.78;
Console.WriteLine("Value from local thread - default culture: {0}", value.ToString("C"));
CultureInfo myCulture = new CultureInfo(Thread.CurrentThread.CurrentUICulture.Name);
myCulture.NumberFormat.CurrencySymbol = "₤";
Thread.CurrentThread.CurrentUICulture = myCulture;
Thread.CurrentThread.CurrentCulture = myCulture;
Console.WriteLine("Value from local thread - 'my' culture: {0}", value.ToString("C"));
Task.Factory.StartNew(() => Console.WriteLine("Value from a different thread: {0}", value.ToString("C")));
Console.ReadKey();
}

}

}

输出:

Value from local thread - default culture: $12,345.78
Value from local thread - 'my' culture: £12,345.78
Value from a different thread: $12,345.78

这是一个related question使用 .NET 4.0 或更早版本的可能解决方案,使用帮助程序类创建线程。尽管他们在那里谈论 WPF,但它也适用于其他 .NET 多线程应用程序。

我知道你不想改变每个新线程的文化,但我想不出任何其他有效的替代方案。

关于multithreading - 如何独立于操作系统语言为多线程 .NET 进程设置 UI 语言?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8312345/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com