System.Resources.ResourceManager 類別

本文提供此 API 參考文件的補充備註。

重要

使用不信任的資料呼叫此類別的方法,會造成安全性上的風險。 呼叫此類別的方法時,請一律使用信任的資料。 如需詳細資訊,請參閱 驗證所有輸入

類別 ResourceManager 會從內嵌在元件或獨立 .resources 檔案中的二進位 .resources 檔案擷取資源。 如果應用程式已當地語系化,且已本地化的資源已部署在附屬元件,則會查閱特定文化特性的資源、在當地語系化資源不存在時提供資源後援,並支援資源串行化。

傳統型應用程式

針對傳統型應用程式,類別 ResourceManager 會從二進位資源 (.resources) 檔案擷取資源。 一般而言,語言編譯程式或 元件連結器 (AL.exe) 會將這些資源檔內嵌在元件中。 您也可以呼叫 方法,CreateFileBasedResourceManager使用 ResourceManager 物件直接從未內嵌在元件中的 .resources 檔案擷取資源。

警告

在 ASP.NET 應用程式中使用獨立 .resources 檔案會中斷 XCOPY 部署,因為資源會保持鎖定,直到方法明確釋放 ReleaseAllResources 它們為止。 如果您想要使用 ASP.NET 應用程式部署資源,您應該將 .resources 檔案編譯成附屬元件。

在資源型應用程式中,一個 .resources 檔案包含預設文化特性的資源,如果找不到特定文化特性的資源,則會使用其資源。 例如,如果應用程式的預設文化特性是英文(en),則每當找不到特定文化特性的當地語系化資源時,就會使用英文語言資源,例如英文(美國)或法文(法國)(fr-FR)。 默認文化特性的資源通常會內嵌在主要應用程式元件中,而其他當地語系化文化特性的資源則內嵌在附屬元件中。 附屬元件只包含資源。 它們有相同的根檔案名稱,以及主要組件的延伸模組 .resources.dll。 對於未在全域程式集緩存中註冊元件的應用程式,附屬元件會儲存在名稱對應至元件文化特性的應用程式子目錄中。

建立資源

當您開發以資源為基礎的應用程式時,您會將資源資訊儲存在文本檔中(具有.txt或 .restext 擴展名的檔案)或 XML 檔案(擴展名為 .resx 的檔案)。 接著,您可以使用資源文件產生器編譯文字或 XML 檔案 (Resgen.exe), 以建立二進位 .resources 檔案。 接著,您可以使用 C# 和 Visual Basic 編譯程式之類的 /resources 編譯程式選項,將產生的 .resources 檔案內嵌在可執行檔或連結庫中,或者您可以使用 元件連結器 (AI.exe) 將它內嵌在附屬元件中。 如果您在 Visual Studio 專案中包含 .resx 檔案,Visual Studio 會在建置程式中自動處理預設和當地語系化資源的編譯和內嵌。

在理想情況下,您應該為應用程式支援的每個語言建立資源,或至少針對每個語言有意義的子集。 二進位 .resources 檔名遵循命名慣例 basenamecultureName.resources,其中 basename 是應用程式的名稱或類別的名稱,視您想要的詳細數據層級而定。 屬性 CultureInfo.Name 是用來判斷 cultureName。 應用程式預設文化特性的資源應命名為 basename.resources

例如,假設元件在具有基底名稱 MyResources 的資源檔中有數個資源。 這些資源文件的名稱應包括日文(日文)文化特性的 MyResources.ja-JP.resources、德國文化特性的 MyResources.de.resources、簡化中國文化的 MyResources.zh-CHS.resources,以及法文(比利時)文化特性的 MyResources.fr-BE.resources。 默認資源文件應該命名為 MyResources.resources。 特定文化特性的資源檔通常會封裝在每個文化特性的附屬元件中。 默認資源檔案應該內嵌在應用程式的主要元件中。

請注意, 元件連結器 允許將資源標示為私用,但您應該一律將它們標示為公用,以便其他元件存取它們。 (因為附屬元件不包含任何程式代碼,因此透過任何機制,將標示為私用的資源無法供您的應用程式使用。

如需建立、封裝及部署資源的詳細資訊,請參閱建立資源檔建立附屬元件封裝及部署資源一文。

具現化 ResourceManager 物件

您可以藉由呼叫其中一個類別建構函式多載,具現化 ResourceManager 物件,從內嵌的 .resources 檔案擷取資源。 這會緊密結合 ResourceManager 物件與特定 .resources 檔案,以及附屬元件中任何相關聯的當地語系化 .resources 檔案。

最常見的兩個建構函式如下:

  • ResourceManager(String, Assembly) 根據您提供的兩項資訊來查閱資源:.resources 檔案的基底名稱,以及預設 .resources 檔案所在的元件。 基底名稱包含 .resources 檔案的命名空間和根名稱,不含其文化特性或擴展名。 請注意,從命令行編譯的 .resources 檔案通常不包含命名空間名稱,而 Visual Studio 環境中建立的 .resources 檔案則為 。 例如,如果資源檔名為 MyCompany.StringResources.resources,而且 ResourceManager 建構函式是從名為 Example.Main的靜態方法呼叫,下列程式代碼會具現化 ResourceManager 可從 .resources 檔案擷取資源的 物件:

    ResourceManager rm = new ResourceManager("MyCompany.StringResources",
                                             typeof(Example).Assembly);
    
    Dim rm As New ResourceManager("MyCompany.StringResources",
                                GetType(Example2).Assembly)
    
  • ResourceManager(Type) 根據類型物件的資訊,查閱附屬元件中的資源。 類型的完整名稱會對應至 .resources 檔案的基底名稱,但擴展名為 。 在使用 Visual Studio 資源設計工具建立的桌面應用程式中,Visual Studio 會建立包裝函式類別,其完整名稱與 .resources 檔案的根名稱相同。 例如,如果資源檔名為 MyCompany.StringResources.resources,而且有名為 MyCompany.StringResources的包裝函式類別,下列程式代碼會具現化 ResourceManager 可從 .resources 檔案擷取資源的 物件:

    ResourceManager rm = new ResourceManager(typeof(MyCompany.StringResources));
    
    Dim rm As New ResourceManager(GetType(MyCompany.StringResources))
    

如果找不到適當的資源,建構函式呼叫會建立有效的 ResourceManager 物件。 不過,嘗試擷取資源會 MissingManifestResourceException 擲回例外狀況。 如需處理例外狀況的相關信息,請參閱 本文稍後的 Handle MissingManifestResourceException 和 MissingSatelliteAssemblyException Exceptions 一節。

下列範例示範如何具現化 ResourceManager 物件。 其中包含名為 ShowTime.exe 之可執行檔的原始程式碼。 它也包含下列名為 Strings.txt 的文字檔,其中包含單一字串資源: TimeHeader

TimeHeader=The current time is

您可以使用批次處理檔來產生資源檔,並將它內嵌至可執行檔。 以下是使用 C# 編譯程式產生可執行檔的批處理檔:

resgen strings.txt
csc ShowTime.cs /resource:strings.resources

針對 Visual Basic 編譯程式,您可以使用下列批處理檔:

resgen strings.txt
vbc ShowTime.vb /resource:strings.resources
using System;
using System.Resources;

public class ShowTimeEx
{
    public static void Main()
    {
        ResourceManager rm = new ResourceManager("Strings",
                                 typeof(Example).Assembly);
        string timeString = rm.GetString("TimeHeader");
        Console.WriteLine("{0} {1:T}", timeString, DateTime.Now);
    }
}
// The example displays output like the following:
//        The current time is 2:03:14 PM
Imports System.Resources

Module Example6
    Public Sub Main()
        Dim rm As New ResourceManager("Strings", GetType(Example6).Assembly)
        Dim timeString As String = rm.GetString("TimeHeader")
        Console.WriteLine("{0} {1:T}", timeString, Date.Now)
    End Sub
End Module
' The example displays output similar to the following:
'       The current time is 2:03:14 PM

ResourceManager 和文化特性特定資源

本地化的應用程式需要部署資源,如封裝和部署資源一文所述。 如果元件已正確設定,資源管理員會根據目前線程的 Thread.CurrentUICulture 屬性決定要擷取的資源。 (該屬性也會傳回目前線程的UI文化特性。例如,如果應用程式是以主要元件中的預設英文語言資源編譯,並在兩個附屬元件中使用法文和俄文語言資源進行編譯,而 Thread.CurrentUICulture 屬性會設定為fr-FR,則資源管理員會擷取法文資源。

您可以明確或隱含地設定 CurrentUICulture 屬性。 設定的方式會決定物件如何 ResourceManager 根據文化特性擷取資源:

  • 如果您明確將 Thread.CurrentUICulture 屬性設定為特定文化特性,則不論使用者的瀏覽器或操作系統語言為何,資源管理員一律會擷取該文化特性的資源。 請考慮使用預設英文資源編譯的應用程式,以及包含英文(美國)、法文(法國)和俄文(俄羅斯)資源的三個附屬元件。 CurrentUICulture如果 屬性設定為fr-FR,ResourceManager物件一律會擷取法文 (France) 資源,即使使用者的操作系統語言不是法文也一樣。 在明確設定 屬性之前,請確定這是所需的行為。

    在 ASP.NET 應用程式中,您必須明確設定 Thread.CurrentUICulture 屬性,因為伺服器上的設定不太可能符合傳入的用戶端要求。 ASP.NET 應用程式可以將 屬性明確設定 Thread.CurrentUICulture 為使用者的瀏覽器接受語言。

    明確設定 屬性會 Thread.CurrentUICulture 定義該線程目前的UI文化特性。 它不會影響應用程式中任何其他線程的目前UI文化特性。

  • 您可以將代表該文化特性的物件指派 CultureInfo 給靜態 CultureInfo.DefaultThreadCurrentUICulture 屬性,以設定應用程式域中所有線程的UI文化特性。

  • 如果您未明確設定目前的UI文化特性,而且未定義目前應用程式域的預設文化特性,則 CultureInfo.CurrentUICulture 屬性會由Windows GetUserDefaultUILanguage 函式隱含設定。 此函式是由 多語系使用者介面 (MUI) 提供,可讓使用者設定預設語言。 如果使用者未設定UI語言,則預設為系統安裝的語言,這是作業系統資源的語言。

下列簡單的 「Hello world」 範例會明確設定目前的 UI 文化特性。 其中包含三種文化特性的資源:英文(美國)或 en-US、法文(法國)或 fr-FR、俄文(俄羅斯)或 ru-RU。 en-US 資源包含在名為 Greetings.txt 的文字檔中:

HelloString=Hello world!

fr-FR 資源包含在名為 Greetings.fr-FR.txt 的文字檔中:

HelloString=Salut tout le monde!

ru-RU 資源包含在名為 Greetings.ru-RU.txt的文字檔中:

HelloString=Всем привет!

以下是範例的原始碼(適用於 Visual Basic 版本Example.vb或 C# 版本的Example.cs):

using System;
using System.Globalization;
using System.Resources;
using System.Threading;

public class Example
{
    public 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;
        ResourceManager rm = new ResourceManager("Greetings", typeof(Example).Assembly);
        try
        {
            CultureInfo newCulture = new CultureInfo(cultures[cultureNdx]);
            Thread.CurrentThread.CurrentCulture = newCulture;
            Thread.CurrentThread.CurrentUICulture = newCulture;
            string greeting = String.Format("The current culture is {0}.\n{1}",
                                            Thread.CurrentThread.CurrentUICulture.Name,
                                            rm.GetString("HelloString"));
            Console.WriteLine(greeting);
        }
        catch (CultureNotFoundException e)
        {
            Console.WriteLine("Unable to instantiate culture {0}", e.InvalidCultureName);
        }
        finally
        {
            Thread.CurrentThread.CurrentCulture = originalCulture;
            Thread.CurrentThread.CurrentUICulture = originalCulture;
        }
    }
}
// The example displays output like the following:
//       The current culture is ru-RU.
//       Всем привет!
Imports System.Globalization
Imports System.Resources
Imports System.Threading

Module Example
   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
      Dim rm As New ResourceManager("Greetings", GetType(Example).Assembly)
      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, rm.GetString("HelloString"))

         Console.WriteLine(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
' The example displays output like the following:
'       The current culture is ru-RU.
'       Всем привет!

若要編譯此範例,請建立包含下列命令的批次 (.bat) 檔案,並從命令提示字元執行它。 如果您使用 C#,請指定 csc 而不是 vbcExample.cs ,而不是 Example.vb

resgen Greetings.txt
vbc Example.vb /resource:Greetings.resources

resgen Greetings.fr-FR.txt
Md fr-FR
al /embed:Greetings.fr-FR.resources /culture:fr-FR /out:fr-FR\Example.resources.dll

resgen Greetings.ru-RU.txt
Md ru-RU
al /embed:Greetings.ru-RU.resources /culture:ru-RU /out:ru-RU\Example.resources.dll

擷取資源

您可以呼叫 GetObject(String)GetString(String) 方法來存取特定資源。 您也可以呼叫 GetStream(String) 方法,將非字串資源擷取為位元組陣列。 根據預設,在具有當地語系化資源的應用程式中,這些方法會傳回由發出呼叫之線程目前UI文化特性所決定之文化特性的資源。 如需如何定義線程目前UI文化特性的詳細資訊,請參閱上一節 ResourceManager和特定文化特性資源。 如果資源管理員找不到目前線程 UI 文化特性的資源,它會使用後援進程來擷取指定的資源。 如果資源管理員找不到任何本地化的資源,則會使用預設文化特性的資源。 如需資源後援規則的詳細資訊,請參閱封裝和部署資源一文的一節。

注意

如果找不到類別建構函式中指定的 ResourceManager .resources 檔案,則嘗試擷取資源會 MissingManifestResourceException 擲回 或 MissingSatelliteAssemblyException 例外狀況。 如需處理例外狀況的相關信息,請參閱 本文稍後的 Handle MissingManifestResourceException 和 MissingSatelliteAssemblyException Exceptions 一節。

下列範例會使用 GetString 方法來擷取特定文化特性的資源。 它由英文(en)、法文(法國)(fr-FR)和俄羅斯(俄羅斯)(ru-RU)文化.txt檔案所編譯的資源組成。 此範例會將目前的文化和目前的UI文化特性變更為英文(美國)、法文(法國)、俄文(俄羅斯)和瑞典文(瑞典)。 然後,它會呼叫 GetString 方法來擷取本地化的字串,其與目前日和月一起顯示。 請注意,輸出會顯示適當的當地語系化字串,但目前的UI文化特性為瑞典文(瑞典)。 由於無法使用瑞典文語言資源,因此應用程式會改用預設文化特性的資源,也就是英文。

此範例需要下表所列的文字型資源檔。 每個都有一 DateStart個名為的單一字串資源。

文化特性 File name 資源名稱 資源值
zh-TW DateStrings.txt DateStart 今天是
fr-FR DateStrings.fr-FR.txt DateStart 奧約爾德『輝, c』est le
ru-RU DateStrings.ru-RU.txt DateStart Сегодня

以下是範例的原始碼(適用於 Visual Basic 版本的ShowDate.vb,或 C# 版本的程式代碼ShowDate.cs)。

using System;
using System.Globalization;
using System.Resources;
using System.Threading;

[assembly: NeutralResourcesLanguage("en")]

public class ShowDateEx
{
    public static void Main()
    {
        string[] cultureNames = { "en-US", "fr-FR", "ru-RU", "sv-SE" };
        ResourceManager rm = new ResourceManager("DateStrings",
                                                 typeof(Example).Assembly);

        foreach (var cultureName in cultureNames)
        {
            CultureInfo culture = CultureInfo.CreateSpecificCulture(cultureName);
            Thread.CurrentThread.CurrentCulture = culture;
            Thread.CurrentThread.CurrentUICulture = culture;

            Console.WriteLine("Current UI Culture: {0}",
                              CultureInfo.CurrentUICulture.Name);
            string dateString = rm.GetString("DateStart");
            Console.WriteLine("{0} {1:M}.\n", dateString, DateTime.Now);
        }
    }
}
// The example displays output similar to the following:
//       Current UI Culture: en-US
//       Today is February 03.
//       
//       Current UI Culture: fr-FR
//       Aujourd'hui, c'est le 3 février
//       
//       Current UI Culture: ru-RU
//       Сегодня февраля 03.
//       
//       Current UI Culture: sv-SE
//       Today is den 3 februari.
Imports System.Globalization
Imports System.Resources
Imports System.Threading

<Assembly:NeutralResourcesLanguage("en")>

Module Example5
    Public Sub Main()
        Dim cultureNames() As String = {"en-US", "fr-FR", "ru-RU", "sv-SE"}
        Dim rm As New ResourceManager("DateStrings",
                                    GetType(Example5).Assembly)

        For Each cultureName In cultureNames
            Dim culture As CultureInfo = CultureInfo.CreateSpecificCulture(cultureName)
            Thread.CurrentThread.CurrentCulture = culture
            Thread.CurrentThread.CurrentUICulture = culture

            Console.WriteLine("Current UI Culture: {0}",
                           CultureInfo.CurrentUICulture.Name)
            Dim dateString As String = rm.GetString("DateStart")
            Console.WriteLine("{0} {1:M}.", dateString, Date.Now)
            Console.WriteLine()
        Next
    End Sub
End Module
' The example displays output similar to the following:
'       Current UI Culture: en-US
'       Today is February 03.
'       
'       Current UI Culture: fr-FR
'       Aujourd'hui, c'est le 3 février
'       
'       Current UI Culture: ru-RU
'       Сегодня февраля 03.
'       
'       Current UI Culture: sv-SE
'       Today is den 3 februari.

若要編譯此範例,請建立包含下列命令的批處理檔,並從命令提示字元執行。 如果您使用 C#,請指定 csc 而不是 vbcshowdate.cs ,而不是 showdate.vb

resgen DateStrings.txt
vbc showdate.vb /resource:DateStrings.resources

md fr-FR
resgen DateStrings.fr-FR.txt
al /out:fr-FR\Showdate.resources.dll /culture:fr-FR /embed:DateStrings.fr-FR.resources

md ru-RU
resgen DateStrings.ru-RU.txt
al /out:ru-RU\Showdate.resources.dll /culture:ru-RU /embed:DateStrings.ru-RU.resources

有兩種方式可擷取目前 UI 文化特性以外的特定文化特性的資源:

  • 您可以呼叫 GetString(String, CultureInfo)GetObject(String, CultureInfo)GetStream(String, CultureInfo) 方法來擷取特定文化特性的資源。 如果找不到本地化的資源,資源管理員會使用資源後援程序來尋找適當的資源。
  • 您可以呼叫 GetResourceSet 方法,以取得 ResourceSet 代表特定文化特性之資源的物件。 在方法呼叫中,您可以判斷如果資源管理員找不到本地化的資源,還是只回到預設文化特性的資源,資源管理員會探查父文化特性。 然後 ResourceSet ,您可以使用 方法來依名稱存取資源(針對該文化特性當地語系化),或列舉集合中的資源。

處理MissingManifestResourceException和MissingSatelliteAssemblyException 例外狀況

如果您嘗試擷取特定資源,但資源管理員找不到該資源,而且未定義預設文化特性,或無法找到預設文化特性的資源,如果資源管理員預期在主要元件中尋找資源,或預期在附屬元件MissingSatelliteAssemblyException中尋找資源,則會擲回MissingManifestResourceException例外狀況。 請注意,當您呼叫 或 GetObject之類的GetString資源擷取方法時,不會在具現化 物件時擲回例外狀況ResourceManager

例外狀況通常會在下列情況下擲回:

  • 適當的資源檔或附屬元件不存在。 如果資源管理員預期應用程式的預設資源會內嵌在主要應用程式元件中,則不存在這些資源。 NeutralResourcesLanguageAttribute如果屬性指出應用程式的預設資源位於附屬元件中,則找不到該元件。 當您編譯應用程式時,請確定資源內嵌在主要元件中,或產生必要的附屬元件,並適當地命名。 其名稱格式應為appName .resources.dll,而且應該位於名為之後它所包含之資源的文化特性的目錄。

  • 您的應用程式未定義預設或中性文化特性。 將 NeutralResourcesLanguageAttribute 屬性新增至原始碼檔案或專案資訊檔(AssemblyInfo.vb Visual Basic 應用程式或 C# 應用程式AssemblyInfo.cs) 檔案。

  • baseName 構函式中的 ResourceManager(String, Assembly) 參數不會指定 .resources 檔案的名稱。 名稱應該包含資源檔的完整命名空間,但不包含其擴展名。 一般而言,在 Visual Studio 中建立的資源檔包含命名空間名稱,但在命令提示字元建立和編譯的資源檔則不會。 您可以編譯並執行下列公用程式,以判斷內嵌 .resources 檔案的名稱。 這是主控台應用程式,可接受主要元件或附屬元件的名稱做為命令行參數。 它會顯示應提供為 參數的 baseName 字串,讓資源管理員能夠正確識別資源。

    using System;
    using System.IO;
    using System.Reflection;
    
    public class Example0
    {
       public static void Main()
       {
          if (Environment.GetCommandLineArgs().Length == 1) { 
             Console.WriteLine("No filename.");
             return;
          }
          
          string filename = Environment.GetCommandLineArgs()[1].Trim();
          // Check whether the file exists.
          if (! File.Exists(filename)) {
             Console.WriteLine("{0} does not exist.", filename);
             return;
          }   
          
          // Try to load the assembly.
          Assembly assem = Assembly.LoadFrom(filename);
          Console.WriteLine("File: {0}", filename);
             
          // Enumerate the resource files.
          string[] resNames = assem.GetManifestResourceNames();
          if (resNames.Length == 0)
             Console.WriteLine("   No resources found.");
    
          foreach (var resName in resNames)
             Console.WriteLine("   Resource: {0}", resName.Replace(".resources", ""));
    
          Console.WriteLine();
       }
    }
    
    Imports System.IO
    Imports System.Reflection
    Imports System.Resources
    
    Module Example
       Public Sub Main()
          If Environment.GetCommandLineArgs.Length = 1 Then 
             Console.WriteLine("No filename.")
             Exit Sub
          End If
          Dim filename As String = Environment.GetCommandLineArgs(1).Trim()
          ' Check whether the file exists.
          If Not File.Exists(filename) Then
             Console.WriteLine("{0} does not exist.", filename)
             Exit Sub
          End If   
          
          ' Try to load the assembly.
          Dim assem As Assembly = Assembly.LoadFrom(filename)
          Console.WriteLine("File: {0}", filename)
             
          ' Enumerate the resource files.
          Dim resNames() As String = assem.GetManifestResourceNames()
          If resNames.Length = 0 Then
             Console.WriteLine("   No resources found.")
          End If
          For Each resName In resNames
             Console.WriteLine("   Resource: {0}", resName.Replace(".resources", ""))
          Next
          Console.WriteLine()
       End Sub
    End Module
    

如果您要明確變更應用程式目前的文化特性,您也應該記住,資源管理員會根據 屬性的值 CultureInfo.CurrentUICulture 擷取資源集,而不是 CultureInfo.CurrentCulture 屬性。 一般而言,如果您變更一個值,也應該變更另一個值。

資源版本控制

因為包含應用程式默認資源的主要元件與應用程式的附屬元件不同,因此您可以發行新版的主要元件,而不需重新部署附屬元件。 您可以使用 SatelliteContractVersionAttribute 屬性來使用現有的附屬元件,並指示資源管理員不要使用新版的主要元件重新部署它們,

如需附屬元件版本控制支援的詳細資訊,請參閱擷取資源一文

<satelliteassemblies> 組態檔節點

注意

本節專屬於 .NET Framework 應用程式。

針對從網站部署和執行的可執行檔(HREF .exe檔案), ResourceManager 物件可能會透過 Web 探查附屬元件,這可能會損害應用程式的效能。 若要消除效能問題,您可以將此探查限制為已使用應用程式部署的附屬元件。 若要這樣做,您會在應用程式的組態檔中建立 <satelliteassemblies> 節點,以指定您已為應用程式部署一組特定的文化特性,而且 ResourceManager 對象不應該嘗試探查該節點中未列出的任何文化特性。

注意

建立 <satelliteassemblies> 節點的慣用替代方案是使用 ClickOnce 部署指令清單 功能。

在應用程式的組態檔中,建立類似下列的區段:

<?xml version ="1.0"?>
<configuration>
  <satelliteassemblies>
    <assembly name="MainAssemblyName, Version=versionNumber, Culture=neutral, PublicKeyToken=null|yourPublicKeyToken">
      <culture>cultureName1</culture>
      <culture>cultureName2</culture>
      <culture>cultureName3</culture>
    </assembly>
  </satelliteassemblies>
</configuration>

編輯此組態資訊,如下所示:

  • 針對您所部署的每個主要元件指定一或多個 <assembly> 節點,其中每個節點會指定完整元件名稱。 指定主要元件的名稱來取代 MainAssemblyName,並指定 Version對應至主要元件的、 PublicKeyTokenCulture 屬性值。

    Version針對屬性,指定元件的版本號碼。 例如,您元件的第一個版本可能是版本號碼 1.0.0.0。

    PublicKeyToken針對 屬性,如果您尚未使用強名稱簽署元件,請指定 關鍵詞null,或如果您已簽署元件,請指定公鑰令牌。

    Culture針對屬性,指定 關鍵詞neutral以指定主要元件,並讓 ResourceManager 類別只探查節點中<culture>所列的文化特性。

    如需完整元件名稱的詳細資訊,請參閱元件名稱一文。 如需強名稱元件的詳細資訊,請參閱建立和使用強名稱元件一文

  • 指定一或多個 <culture> 具有特定文化特性名稱的節點,例如 「fr-FR」 或中性文化特性名稱,例如 「fr」。

如果節點下 <satelliteassemblies> 未列出的任何元件都需要資源,則 ResourceManager 類別會使用標準探查規則探查文化特性。

Windows 8.x 應用程式

重要

雖然 Windows 8.x 應用程式中支援 類別 ResourceManager ,但我們不建議使用類別。 只有在您開發可與 Windows 8.x 應用程式搭配使用的可攜式類別庫專案時,才使用此類別。 若要從 Windows 8.x 應用程式擷取資源,請改用 Windows.ApplicationModel.Resources.ResourceLoader 類別。

針對 Windows 8.x 應用程式,類別 ResourceManager 會從套件資源索引 (PRI) 檔案擷取資源。 單一 PRI 檔案 (應用程式套件 PRI 檔案) 包含預設文化特性和任何當地語系化文化特性的資源。 您可以使用 MakePRI 公用程式,從 XML 資源 (.resw) 格式的一或多個資源檔建立 PRI 檔案。 針對 Visual Studio 專案中包含的資源,Visual Studio 會自動處理建立和封裝 PRI 檔案的程式。 然後,您可以使用 .NET ResourceManager 類別來存取應用程式的或連結庫資源。

您可以使用與傳統型應用程式相同的方式,具現化 ResourceManager Windows 8.x 應用程式的物件。

接著,您可以傳遞要擷取至 GetString(String) 方法的資源名稱,以存取特定文化特性的資源。 根據預設,這個方法會傳回由發出呼叫之線程目前UI文化特性所決定之文化特性的資源。 您也可以傳遞資源的名稱,以及 CultureInfo 代表資源要擷取至 GetString(String, CultureInfo) 方法之資源之文化特性的物件,以擷取特定文化特性的資源。 如果找不到目前 UI 文化特性或指定文化特性的資源,資源管理員會使用 UI 語言後援清單來尋找適當的資源。

範例

下列範例示範如何使用明確文化特性和隱含目前的UI文化特性,從主要元件和附屬元件取得字串資源。 如需詳細資訊,請參閱建立附屬元件主題的<未安裝在全域程式集緩存中的附屬元件的目錄位置>一節

若要執行此範例:

  1. 在應用程式目錄中,建立名為 rmc.txt 的檔案,其中包含下列資源字串:

    day=Friday
    year=2006
    holiday="Cinco de Mayo"
    
  2. 使用資源文件產生器,從rmc.txt輸入檔產生 rmc.resources 資源檔,如下所示:

    resgen rmc.txt
    
  3. 建立應用程式目錄的子目錄,並將其命名為 「es-MX」。。 這是您將在接下來的三個步驟中建立的附屬元件文化特性名稱。

  4. 在包含下列資源字串的 es-MX 目錄中建立名為 rmc.es-MX.txt 的檔案:

    day=Viernes
    year=2006
    holiday="Cinco de Mayo"
    
  5. 使用資源文件產生器,從rmc.es-MX.txt輸入檔產生 rmc.es-MX.resources 資源檔,如下所示:

    resgen rmc.es-MX.txt
    
  6. 假設此範例的檔名是rmc.vb或rmc.cs。 將下列原始程式碼複製到檔案中。 然後編譯它,並將主要元件資源檔 rmc.resources 內嵌在可執行檔元件中。 如果您使用 Visual Basic 編譯程式,語法為:

    vbc rmc.vb /resource:rmc.resources
    

    C# 編譯程序的對應語法如下:

    csc /resource:rmc.resources rmc.cs
    
  7. 使用元件連結器建立附屬元件。 如果應用程式的基底名稱是 rmc,則必須rmc.resources.dll附屬元件名稱。 附屬元件應該在 es-MX 目錄中建立。 如果 es-MX 是目前目錄,請使用此指令:

    al /embed:rmc.es-MX.resources /c:es-MX /out:rmc.resources.dll
    
  8. 運行rmc.exe以獲取並顯示嵌入的資源字符串。

    using System;
    using System.Globalization;
    using System.Resources;
    
    class Example2
    {
        public static void Main()
        {
            string day;
            string year;
            string holiday;
            string celebrate = "{0} will occur on {1} in {2}.\n";
    
            // Create a resource manager.
            ResourceManager rm = new ResourceManager("rmc",
                                     typeof(Example).Assembly);
    
            Console.WriteLine("Obtain resources using the current UI culture.");
    
            // Get the resource strings for the day, year, and holiday
            // using the current UI culture.
            day = rm.GetString("day");
            year = rm.GetString("year");
            holiday = rm.GetString("holiday");
            Console.WriteLine(celebrate, holiday, day, year);
    
            // Obtain the es-MX culture.
            CultureInfo ci = new CultureInfo("es-MX");
    
            Console.WriteLine("Obtain resources using the es-MX culture.");
    
            // Get the resource strings for the day, year, and holiday
            // using the specified culture.
            day = rm.GetString("day", ci);
            year = rm.GetString("year", ci);
            holiday = rm.GetString("holiday", ci);
            // ---------------------------------------------------------------
            // Alternatively, comment the preceding 3 code statements and
            // uncomment the following 4 code statements:
            // ----------------------------------------------------------------
            // Set the current UI culture to "es-MX" (Spanish-Mexico).
            //    Thread.CurrentThread.CurrentUICulture = ci;
    
            // Get the resource strings for the day, year, and holiday
            // using the current UI culture. Use those strings to
            // display a message.
            //    day  = rm.GetString("day");
            //    year = rm.GetString("year");
            //    holiday = rm.GetString("holiday");
            // ---------------------------------------------------------------
    
            // Regardless of the alternative that you choose, display a message
            // using the retrieved resource strings.
            Console.WriteLine(celebrate, holiday, day, year);
        }
    }
    /*
    This example displays the following output:
    
       Obtain resources using the current UI culture.
       "5th of May" will occur on Friday in 2006.
    
       Obtain resources using the es-MX culture.
       "Cinco de Mayo" will occur on Viernes in 2006.
    */
    
    Imports System.Resources
    Imports System.Reflection
    Imports System.Threading
    Imports System.Globalization
    
    Class Example4
        Public Shared Sub Main()
            Dim day As String
            Dim year As String
            Dim holiday As String
            Dim celebrate As String = "{0} will occur on {1} in {2}." & vbCrLf
    
            ' Create a resource manager. 
            Dim rm As New ResourceManager("rmc", GetType(Example4).Assembly)
    
            Console.WriteLine("Obtain resources using the current UI culture.")
    
            ' Get the resource strings for the day, year, and holiday 
            ' using the current UI culture. 
            day = rm.GetString("day")
            year = rm.GetString("year")
            holiday = rm.GetString("holiday")
            Console.WriteLine(celebrate, holiday, day, year)
    
            ' Obtain the es-MX culture.
            Dim ci As New CultureInfo("es-MX")
    
            Console.WriteLine("Obtain resources using the es-MX culture.")
    
            ' Get the resource strings for the day, year, and holiday 
            ' using the es-MX culture.  
            day = rm.GetString("day", ci)
            year = rm.GetString("year", ci)
            holiday = rm.GetString("holiday", ci)
    
            ' ---------------------------------------------------------------
            ' Alternatively, comment the preceding 3 code statements and 
            ' uncomment the following 4 code statements:
            ' ----------------------------------------------------------------
            ' Set the current UI culture to "es-MX" (Spanish-Mexico).
            '    Thread.CurrentThread.CurrentUICulture = ci
            ' Get the resource strings for the day, year, and holiday 
            ' using the current UI culture. 
            '    day  = rm.GetString("day")
            '    year = rm.GetString("year")
            '    holiday = rm.GetString("holiday")
            ' ---------------------------------------------------------------
    
            ' Regardless of the alternative that you choose, display a message 
            ' using the retrieved resource strings.
            Console.WriteLine(celebrate, holiday, day, year)
        End Sub
    End Class
    ' This example displays the following output:
    'Obtain resources using the current UI culture.
    '"5th of May" will occur on Friday in 2006.
    '
    'Obtain resources using the es-MX culture.
    '"Cinco de Mayo" will occur on Viernes in 2006.