如何独立于OS语言为多线程.NET进程设置UI语言? [英] How do I set the UI language for a multi-threaded .NET process, independent of the OS language?

查看:129
本文介绍了如何独立于OS语言为多线程.NET进程设置UI语言?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题:

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

I have a C# .NET 2.0 application developed on Windows 7 that has translated resources for multiple languages (ex. zh-CHS for Chinese, es for Spanish, etc.).

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

I have a customer who wants to run their Windows 7 OS in English, but run my .NET application in Spanish (es).

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

My application is multi-threaded, so just changing the culture of the main GUI thread is not sufficient for my needs (trust me, I tried). This is because other strings displayed to the user through the GUI are generated on other threads. In order to get 100% complete coverage, I would need to set the culture of each individual thread manually to ensure all text from resource files is in the correct language. Because my product is basically a framework for other plugins that other development groups write, I don't have control over actions performed in threads created in other plugins. Because of this, manually changing the culture for each thread is not a valid option.

我正在寻找一种无需更改任何OS用户设置即可设置应用程序整体语言的方法.

What I am looking for is a way to set the overall language for the application, without having to change any of the OS user settings.

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

In doing some research, I came across the following method for setting the preferred UI language for a process: SetProcessPreferredUILanguages

在阅读完此书后,看来这是我要找的电话.但是,当我在C#应用程序的Main方法中实现此调用时,它似乎没有任何作用.

After reading up on this, it appears that this call is what I am looking for. However, when I implemented this call in the Main method of my C# application, it doesn't appear to do anything.

以下代码的返回值是正确的,但我从未见过我的GUI应用程序以西班牙语显示文本.

The return value from the following code is true, but I never see my GUI application displaying the text in Spanish.

    [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应用程序?

Is there something else I am missing in order for this to successfully run my GUI application with the Spanish resources loaded?

我正在尝试为

I am trying to implement the 2nd option of the table at the bottom of the MSDN page for Building MUI Applications, where I have Application-specific UI language settings and want to achieve the desired result for resource loading:

应用程序调用MUI API来设置特定于应用程序的UI语言或流程首选的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%,但是该行为似乎表明确实是这种情况.

I have made the call to successfully set the process preferred UI languages, but my resources are not being loaded in the language I would expect. A commenter mentioned this call will only work for un-managed resources, which I could not verify 100%, but the behavior seems in indicate this is the case.

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

I can't be the only person who has ever tried to implement a .NET application in this manner. It's frustrating that there isn't more information about how to do this.

预先感谢

凯尔

推荐答案

您的代码有一些问题.不幸的是,解决问题并没有带来所要求的行为.

Your code has a few problems. Unfortunately the fix of problems do not bring the requested behaviour.

代码应为:

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

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

  langs[0] = "es\0";
  langs[1] = "zh-CHS\0";
  langs[2] = "en-US\0";
  langs[3] = "\0"; //double null ending

  numLangs = (uint)langs.Length;

  if (SetProcessPreferredUILanguages(MUI_LANGUAGE_NAME, String.Concat(langs), ref numLangs))
  {
    if (numLangs == langs.Length - 1)
      Console.WriteLine("Successfully changed UI language");
    else if (numLangs < 1)
      Console.WriteLine("No language could be set");
    else
      Console.WriteLine("Not all languages were set");
  }
  else
    Console.WriteLine("No language could be set");
}

pwszLanguagesBuffer定义为PCZZWSTR,这意味着宽字符串(因此为Charset.Unicode)的列表,字符串以零个字符结尾(无需使用Unicode转义序列),列表以双零字符结尾(因此,新的空语言";另一种方法是将双\ 0放在最后一种语言上).我还添加了新的调试描述,以测试当前设置的语言,但是不幸的是,由于该功能需要Win7,因此我无法在此处(工作中)对其进行测试.

The pwszLanguagesBuffer is defined as PCZZWSTR and that means list of wide string (therefore Charset.Unicode), string end by zero character (no need to use unicode escape sequence), list ends with double zero character (therefore new "empty language"; other way is to put double \0 to last language). I also added new debug description, to test currently set languages, but unfortunately I can not test it here (at work) because the function needs Win7.

但是有完全不同的方法来做到这一点.请参见 AppLocale

But there is a fully different way how to do this. See AppLocale

我不能保证它将在您的情况下起作用.该应用程序需要Windows XP和更高版本的(在Windows 7上安装时有一个小问题;请记住以管理员模式启动安装,否则将无法正常工作).该应用程序还有另一个更大的问题.从中欧切换到西方是不可能的.但是它从中欧到希腊以及其他字符不同的国家都可以使用.

I can not give a guarantee, that it will work in your case. The application needs Windows XP and newer (there is a small problem in installing on Windows 7; remember to start the installation in administrator mode, otherwise it would not work). The application has also another, bigger problem. It is not possible to switch from Central Europe to Western. But it works from Central Europe to Greece, and other countries with different characters.

我使用此应用程序为某些国家/地区开发较旧的(非unicode)应用程序.不幸的是,它在启动时发出了麻烦的警告...

I use this application to develop an older (non unicode) application for some countries. Unfortunately it gives a troublesome warning on start...

这篇关于如何独立于OS语言为多线程.NET进程设置UI语言?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆