定位和使用特定区域性的资源

更新:2010 年 5 月

公共语言运行时为检索打包和部署在附属程序集中的区域性特定资源提供了支持。 附属程序集仅包含诸如 .gif 文件之类的资源文件(或松散资源)。 它们不包含任何可执行代码。

在附属程序集部署模型中,所创建的应用程序具有一个默认程序集(主程序集)和几个附属程序集。 将默认或非特定区域性的资源与主程序集打包在一起,并为应用程序支持的每一种语言创建单独的附属程序集。 因为附属程序集不是主程序集的一部分,所以您可以轻松地替换或更新与特定区域性对应的资源,而不必替换应用程序的主程序集。

例如,在简单的“Hello world”应用程序中,如果默认或非特定区域性为“en”(英语),则可创建一个名为 Greeting 的资源,并在其中存储一个其值为“Hello world!”的名为 HelloString 的字符串。若要指示“en”为应用程序的默认区域性,则您还必须将以下 System.Resources.NeutralResourcesLanguageAttribute 特性添加到应用程序的 AssemblyInfo 文件或某个将编译为应用程序的主程序集的源代码文件。

<Assembly: NeutralResourcesLanguageAttribute("en")>

然后,向您的应用程序添加对其他区域性的支持。 例如,可以按如下方式支持“en-US”、“fr-FR”和“ru-RU”区域性:

  • 若要支持“en-US”或“英语(美国)”区域性,请创建一个名为 Greeting.en-US.resx 的资源文件,并在该文件中存储一个其值为“Hi world!”的名为 HelloString 的字符串。

  • 若要支持“fr-FR”或“法语(法国)”区域性,请创建一个名为 Greeting.fr-FR.resx 的资源文件,并在该文件中存储一个其值为“Salut tout le monde!”的名为 HelloString 的字符串。

  • 若要支持“ru-RU”或“俄语(俄罗斯)”区域性,请创建一个名为 Greeting.ru-RU.resx 的资源文件,并在该文件中存储一个其值为“Всем привет!”的名为 HelloString 的字符串。

System.Resources.ResourceManager 类在运行时提供对区域性特定资源的访问,并使用资源后备进程来控制应用程序检索资源的方式。 有关更多信息,请参见打包和部署资源主题中的“资源后备进程”一节。

ResourceManager 对象确定要根据当前线程的 CultureInfo.CurrentUICulture 属性来检索哪些资源。 例如,如果使用主程序集中的默认英语语言资源以及两个附属程序集中的“法语(法国)”和“俄语(俄罗斯)”语言资源来编译应用程序,并且将 CurrentUICulture 属性设置为“fr-FR”,则 ResourceManager 对象将检索法语资源。

可显式或隐式设置 CurrentUICulture 属性。 设置此属性的方式会影响 ResourceManager 对象根据区域性来检索资源的方式:

  • 如果应用程序将 CurrentUICulture 属性显式设置为应用程序节点中的某个特定区域性,则可保证无论用户使用哪种浏览器或操作系统语言,总是能够检索到该区域性的资源。 请考虑一个用默认英语语言资源和三个包含“英语(美国)”、“法语(法国)”和“俄语(俄罗斯)”资源的附属程序集编译的应用程序。 如果将 CurrentUICulture 属性设置为“fr-FR”,则 ResourceManager 对象总是检索“法语(法国)”资源,即使用户的操作系统语言不是法语。 在显式设置此属性之前,请确保这是所需的行为。

    备注

    在 ASP.NET 应用程序中,您必须显式设置 CurrentUICulture 属性,因为服务器上的设置很可能与传入的客户端请求不匹配。ASP.NET 应用程序可将 CurrentUICulture 属性显式设置为用户浏览器接受的语言。

  • 如果应用程序未显式设置 CurrentUICulture 属性,则 Windows 2000 和 Windows XP 中的 GetUserDefaultUILanguage 函数将隐式设置该属性。 此函数由多语言用户界面 (MUI) 提供,它允许用户设置默认语言。 如果用户没有设置 UI 语言,则默认为系统安装的语言(即操作系统资源的语言)。

下面的示例显式设置了 CurrentUICulture 属性。 它定义了一个数组,该数组包含简单“Hello world”应用程序的受支持区域性的名称。 然后,该示例随机选择某个区域性名称,再使用它来实例化 CultureInfo 对象并将该区域性设置为当前线程的当前区域性。 然后,对 MessageBox.Show 方法的调用(在 C# 示例中)或对 Interaction.MsgBox 函数的调用(在 Visual Basic 示例中)会显式分配给 HelloString 资源的本地化字符串。

Imports System.Globalization
Imports System.Resources
Imports System.Threading

Module Module1

   Sub Main()
      ' Create array of supported cultures
      Dim cultures() As String = {"en-CA", "en-US", "fr-FR", "ru-RU" }
      Dim rnd As New Random()
      Dim cultureNdx As Integer = rnd.Next(0, cultures.Length)
      Dim originalCulture As CultureInfo = Thread.CurrentThread.CurrentCulture

      Try
         Dim newCulture As New CultureInfo(cultures(cultureNdx))
         Thread.CurrentThread.CurrentCulture = newCulture
         Thread.CurrentThread.CurrentUICulture = newCulture
         Dim greeting As String = String.Format("The current culture is {0}.{1}{2}",
                                                Thread.CurrentThread.CurrentUICulture.Name,
                                                vbCrLf, My.Resources.Greetings.HelloString)

         MsgBox(greeting)
      Catch e As CultureNotFoundException
         Console.WriteLine("Unable to instantiate culture {0}", e.InvalidCultureName)
      Finally
         Thread.CurrentThread.CurrentCulture = originalCulture
         Thread.CurrentThread.CurrentUICulture = originalCulture
      End Try
   End Sub
End Module
using System;
using System.Globalization;
using System.Reflection;
using System.Resources;
using System.Threading;
using System.Windows.Forms;

class Program
{
   static void Main()
   {
      // Create array of supported cultures
      string[] cultures = {"en-CA", "en-US", "fr-FR", "ru-RU"};
      Random rnd = new Random();
      int cultureNdx = rnd.Next(0, cultures.Length);
      CultureInfo originalCulture = Thread.CurrentThread.CurrentCulture;

      try {
         CultureInfo newCulture = new CultureInfo(cultures[cultureNdx]);
         Thread.CurrentThread.CurrentCulture = newCulture;
         Thread.CurrentThread.CurrentUICulture = newCulture;
         ResourceManager rm = new ResourceManager("LocatingCS1.Greetings", Assembly.GetExecutingAssembly()); 
         string greeting = String.Format("The current culture is {0}.\n{1}",
                                         Thread.CurrentThread.CurrentUICulture.Name,
                                         rm.GetString("HelloString"));

         MessageBox.Show(greeting);
      }
      catch (CultureNotFoundException e) {
         Console.WriteLine("Unable to instantiate culture {0}", e.InvalidCultureName);
      }
      finally {
         Thread.CurrentThread.CurrentCulture = originalCulture;
         Thread.CurrentThread.CurrentUICulture = originalCulture;
      }
   }
}

请参见

概念

应用程序中的资源

检索附属程序集中的资源

Resources in ASP.NET Applications

其他资源

编码和本地化

修订记录

日期

修订记录

原因

2010 年 5 月

做了大范围修订。

客户反馈