Compartilhar via


Classe System.Resources.ResourceManager

Este artigo fornece comentários complementares à documentação de referência para esta API.

Importante

Chamar métodos dessa classe com dados não confiáveis é um risco à segurança. Chame os métodos dessa classe apenas com dados confiáveis. Para obter mais informações, consulte Validar Todas as Entradas.

A ResourceManager classe recupera recursos de um arquivo .resources binário inserido em um assembly ou de um arquivo .resources autônomo. Se um aplicativo tiver sido localizado e os recursos localizados tiverem sido implantados em assemblies satélites, ele procurará recursos específicos da cultura, fornecerá fallback de recursos quando um recurso localizado não existir e oferecerá suporte à serialização de recursos.

Aplicativos de desktop

Para aplicativos da área de trabalho, a ResourceManager classe recupera recursos de arquivos de recurso binário (.resources). Normalmente, um compilador de idiomas ou o Assembly Linker (AL.exe) insere esses arquivos de recurso em um assembly. Você também pode usar um objeto ResourceManager para chamar o método CreateFileBasedResourceManager e recuperar recursos diretamente de um arquivo .resources que não está incorporado em um assembly.

Cuidado

O uso de arquivos .resources autônomos em um aplicativo ASP.NET interromperá a implantação do XCOPY, pois os recursos permanecem bloqueados até que sejam liberados explicitamente pelo ReleaseAllResources método. Se quiser implantar recursos com seus aplicativos ASP.NET, você deverá compilar seus arquivos .resources em assemblies satélites.

Em um aplicativo baseado em recursos, um arquivo .resources contém os recursos da cultura padrão, cujos recursos são usados caso não sejam encontrados recursos específicos para uma determinada cultura. Por exemplo, se a cultura padrão de um aplicativo for inglês (en), os recursos de idioma inglês serão usados sempre que recursos localizados não puderem ser encontrados para uma cultura específica, como inglês (Estados Unidos) (en-US) ou francês (França) (fr-FR). Normalmente, os recursos da cultura padrão são inseridos no assembly principal do aplicativo e os recursos de outras culturas localizadas são inseridos em assemblies satélites. Assemblies satélites contêm apenas recursos. Eles têm o mesmo nome de arquivo raiz que o assembly principal e uma extensão de .resources.dll. Para aplicativos cujos assemblies não estão registrados no cache de assembly global, os assemblies satélites são armazenados em um subdiretório do aplicativo cujo nome corresponde à cultura do assembly.

Criar recursos

Ao desenvolver um aplicativo baseado em recursos, você armazena informações de recurso em arquivos de texto (arquivos que têm uma extensão de .txt ou .restext) ou XML (arquivos que têm uma extensão .resx). Em seguida, você compila os arquivos de texto ou XML com o Gerador de Arquivos de Recurso (Resgen.exe) para criar um arquivo .resources binário. Em seguida, você pode inserir o arquivo .resources resultante em um executável ou biblioteca usando uma opção de compilador, como /resources para os compiladores do C# e do Visual Basic, ou pode inserí-lo em um assembly satélite usando o Assembly Linker (AI.exe). Se você incluir um arquivo .resx em seu projeto do Visual Studio, o Visual Studio manipulará a compilação e a inserção de recursos padrão e localizados automaticamente como parte do processo de build.

Idealmente, você deve criar recursos para cada idioma compatível com seu aplicativo ou pelo menos para um subconjunto significativo de cada idioma. Os nomes de arquivo binários .resources seguem a convenção de nomenclatura basename.cultureName.resources, onde basename é o nome do aplicativo ou o nome de uma classe, dependendo do nível de detalhe que você deseja. A CultureInfo.Name propriedade é usada para determinar cultureName. Um recurso para a cultura padrão do aplicativo deve ser chamado basename.resources.

Por exemplo, suponha que um assembly tenha vários recursos em um arquivo de recurso que tenha o nome base MyResources. Esses arquivos de recurso devem ter nomes como MyResources.ja-JP.resources para a cultura do Japão (japonês), MyResources.de.resources para a cultura alemã, MyResources.zh-CHS.resources para a cultura chinesa simplificada e MyResources.fr-BE.resources para a cultura francesa (Bélgica). O arquivo de recurso padrão deve ser denominado MyResources.resources. Os arquivos de recurso específicos da cultura geralmente são empacotados em assemblies satélites para cada cultura. O arquivo de recurso padrão deve ser inserido no assembly principal do aplicativo.

Observe que o Assembly Linker permite que os recursos sejam marcados como privados, mas você deve sempre marcá-los como públicos para que possam ser acessados por outros assemblies. (Como um assembly satélite não contém código, os recursos marcados como privados não estão disponíveis para seu aplicativo por meio de nenhum mecanismo.)

Para obter mais informações sobre como criar, empacotar e implantar recursos, consulte os artigos Criando arquivos de recursos, criando assemblies satélites e empacotando e implantando recursos.

Instanciar um objeto ResourceManager

Você cria uma instância de um objeto ResourceManager que recupera recursos de um arquivo .resources inserido chamando uma das sobrecargas de construtor de classe. Isso vincula fortemente um objeto ResourceManager a um arquivo .resources específico e a quaisquer arquivos .resources localizados associados em assemblies satélites.

Os dois construtores mais comumente chamados são:

  • ResourceManager(String, Assembly) pesquisa recursos com base em duas informações que você fornece: o nome base do arquivo .resources e o assembly no qual reside o arquivo .resources padrão. O nome base inclui o namespace e o nome raiz do arquivo .resources, sem sua cultura ou extensão. Observe que os arquivos .resources compilados da linha de comando normalmente não incluem um nome de namespace, enquanto os arquivos .resources criados no ambiente do Visual Studio incluem. Por exemplo, se um arquivo de recurso for chamado MyCompany.StringResources.resources e o ResourceManager construtor for chamado de um método estático chamado Example.Main, o código a seguir criará uma instância de um ResourceManager objeto que pode recuperar recursos do arquivo .resources:

    ResourceManager rm = new ResourceManager("MyCompany.StringResources",
                                             typeof(Example).Assembly);
    
    Dim rm As New ResourceManager("MyCompany.StringResources",
                                GetType(Example2).Assembly)
    
  • ResourceManager(Type) pesquisa recursos em assemblies satélites com base em informações de um objeto de tipo. O nome totalmente qualificado do tipo corresponde ao nome base do arquivo .resources sem a extensão de nome de arquivo. Em aplicativos da área de trabalho criados usando o Designer de Recursos do Visual Studio, o Visual Studio cria uma classe wrapper cujo nome totalmente qualificado é o mesmo que o nome raiz do arquivo .resources. Por exemplo, se um arquivo de recurso for chamado MyCompany.StringResources.resources e houver uma classe wrapper chamada MyCompany.StringResources, o código a seguir criará uma instância de um ResourceManager objeto que pode recuperar recursos do arquivo .resources:

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

Se os recursos apropriados não puderem ser encontrados, a chamada do construtor criará um objeto válido ResourceManager . No entanto, a tentativa de recuperar um recurso gera uma MissingManifestResourceException exceção. Para obter informações sobre como lidar com a exceção, consulte a seção Handle MissingManifestResourceException e MissingSatelliteAssemblyException Exceptions mais adiante neste artigo.

O exemplo a seguir mostra como instanciar um ResourceManager objeto. Ele contém o código-fonte de um executável chamado ShowTime.exe. Ele também inclui o seguinte arquivo de texto chamado Strings.txt que contém um único recurso de cadeia de caracteres: TimeHeader

TimeHeader=The current time is

Você pode usar um arquivo em lote para gerar o arquivo de recurso e inserê-lo no executável. Aqui está o arquivo em lote para gerar um executável usando o compilador C#:

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

Para o compilador do Visual Basic, você pode usar o seguinte arquivo em lote:

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($"{timeString} {DateTime.Now:T}");
    }
}
// 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 e recursos específicos da cultura

Um aplicativo localizado requer que os recursos sejam implantados, conforme discutido no artigo Empacotamento e Implantação de Recursos. Se os assemblies estiverem configurados corretamente, o gerenciador de recursos determinará quais recursos recuperar com base na propriedade do Thread.CurrentUICulture thread atual. (Essa propriedade também retorna a cultura da interface do thread atual.) Por exemplo, se um aplicativo for compilado com recursos padrão de idioma inglês no assembly principal e com recursos de idioma francês e russo em dois assemblies satélites, e a propriedade Thread.CurrentUICulture estiver definida como fr-FR, o gerenciador de recursos recuperará os recursos franceses.

Você pode definir a CurrentUICulture propriedade explicitamente ou implicitamente. A maneira como você o define determina como o ResourceManager objeto recupera recursos com base na cultura:

  • Se você definir explicitamente a Thread.CurrentUICulture propriedade como uma cultura específica, o gerenciador de recursos sempre recuperará os recursos dessa cultura, independentemente do navegador do usuário ou da linguagem do sistema operacional. Considere um aplicativo compilado com recursos padrão em inglês e três assemblies satélites que contêm recursos para inglês (Estados Unidos), francês (França) e russo (Rússia). Se a CurrentUICulture propriedade estiver definida como fr-FR, o ResourceManager objeto sempre recuperará os recursos franceses (França), mesmo que o idioma do sistema operacional do usuário não seja francês. Verifique se esse é o comportamento desejado antes de definir a propriedade explicitamente.

    Em ASP.NET aplicativos, você deve definir a Thread.CurrentUICulture propriedade explicitamente, pois é improvável que a configuração no servidor corresponda às solicitações de cliente de entrada. Um aplicativo ASP.NET pode definir a Thread.CurrentUICulture propriedade explicitamente como o idioma de aceitação do navegador do usuário.

    Definir explicitamente a propriedade Thread.CurrentUICulture determina a cultura atual da interface para esse thread. Isso não afeta a cultura atual da interface de nenhum outro thread em um aplicativo.

  • Você pode definir a cultura da interface do usuário de todos os threads em um domínio de aplicativo atribuindo um CultureInfo objeto que representa essa cultura à propriedade estática CultureInfo.DefaultThreadCurrentUICulture .

  • Se você não definir explicitamente a cultura da interface do usuário atual e não definir uma cultura padrão para o domínio do aplicativo atual, a CultureInfo.CurrentUICulture propriedade será definida implicitamente pela função do Windows GetUserDefaultUILanguage . Essa função é fornecida pela MUI (Interface do Usuário Multilíngue), que permite que o usuário defina o idioma padrão. Se o idioma da interface do usuário não for definido pelo usuário, ele usará como padrão o idioma instalado pelo sistema, que é o idioma dos recursos do sistema operacional.

O exemplo "Olá, mundo" simples a seguir define explicitamente a cultura atual da interface do usuário. Contém recursos para três culturas: inglês (Estados Unidos) ou en-US, francês (França) ou fr-FRe russo (Rússia) ou ru-RU. Os recursos de en-US estão contidos em um arquivo de texto chamado Greetings.txt:

HelloString=Hello world!

Os recursos de fr-FR estão contidos em um arquivo de texto chamado Greetings.fr-FR.txt:

HelloString=Salut tout le monde!

Os recursos de ru-RU estão contidos em um arquivo de texto chamado Greetings.ru-RU.txt:

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

Este é o código-fonte do exemplo (Example.vb para a versão do Visual Basic ou Example.cs para a versão do C#):

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 {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.
'       Всем привет!

Para compilar este exemplo, crie um arquivo de lote (.bat) que contenha os comandos a seguir e execute-o no prompt de comando. Se você estiver usando C#, especifique csc em vez de vbc .Example.csExample.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

Recuperar recursos

Você chama os métodos GetObject(String) e GetString(String) para acessar um recurso específico. Você também pode chamar o GetStream(String) método para recuperar recursos que não são de cadeia de caracteres como uma matriz de bytes. Por padrão, em um aplicativo que possui recursos de localização, esses métodos retornam o recurso para a cultura definida pela cultura de interface atual do thread que fez a chamada. Consulte a seção anterior, ResourceManager e recursos específicos à cultura, para obter mais informações sobre como as culturas atuais da interface de usuário de um thread são definidas. Se o gerenciador de recursos não conseguir encontrar o recurso para a cultura da interface do usuário do thread atual, ele usará um processo de fallback para recuperar o recurso especificado. Se o gerenciador de recursos não encontrar recursos localizados, ele usará os recursos da cultura padrão. Para obter mais informações sobre regras de fallback de recursos, consulte a seção "Processo de Fallback de Recursos" do artigo Empacotamento e Implantação de Recursos.

Observação

Se o arquivo .resources especificado no construtor da classe ResourceManager não puder ser encontrado, a tentativa de recuperar um recurso gerará uma exceção MissingManifestResourceException ou MissingSatelliteAssemblyException. Para obter informações sobre como lidar com a exceção, consulte a seção Handle MissingManifestResourceException e MissingSatelliteAssemblyException Exceptions mais adiante neste artigo.

O exemplo a seguir usa o GetString método para recuperar recursos específicos da cultura. Consiste em recursos compilados de arquivos .txt para as culturas em inglês (en), francês (França) (fr-FR) e russo (Rússia) (ru-RU). O exemplo altera a cultura atual e a cultura atual da interface do usuário para inglês (Estados Unidos), francês (França), russo (Rússia) e sueco (Suécia). Em seguida, ele chama o GetString método para recuperar a cadeia de caracteres localizada, exibida junto com o dia e o mês atuais. Observe que a saída exibe a cadeia de caracteres localizada apropriada, exceto quando a cultura atual da interface do usuário é sueca (Suécia). Como os recursos de idioma sueco não estão disponíveis, o aplicativo usa os recursos da cultura padrão, que é inglês.

O exemplo requer os arquivos de recurso baseados em texto listados na tabela a seguir. Cada um tem um único recurso de cadeia de caracteres chamado DateStart.

Cultura Nome do arquivo Nome do recurso Valor do recurso
pt-BR DateStrings.txt DateStart Hoje é
fr-FR DateStrings.fr-FR.txt DateStart Hoje é o
ru-RU DateStrings.ru-RU.txt DateStart Сегодня

Este é o código-fonte do exemplo (ShowDate.vb para a versão do Visual Basic ou ShowDate.cs para a versão C# do código).

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: {CultureInfo.CurrentUICulture.Name}");
            string dateString = rm.GetString("DateStart");
            Console.WriteLine($"{dateString} {DateTime.Now:M}.\n");
        }
    }
}
// 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.

Para compilar este exemplo, crie um arquivo em lote que contenha os comandos a seguir e execute-o no prompt de comando. Se você estiver usando C#, especifique csc em vez de vbc .showdate.csshowdate.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

Há duas maneiras de recuperar os recursos de uma cultura específica diferente da cultura atual da interface do usuário:

  • Você pode chamar o método GetString(String, CultureInfo), GetObject(String, CultureInfo) ou GetStream(String, CultureInfo) para recuperar um recurso para uma cultura específica. Se um recurso localizado não puder ser encontrado, o gerenciador de recursos usará o processo de substituição para encontrar um recurso adequado.
  • Você pode chamar o GetResourceSet método para obter um ResourceSet objeto que representa os recursos de uma cultura específica. Na chamada de método, você pode determinar se o gerenciador de recursos verifica as culturas parentais caso não consiga encontrar recursos locais ou se ele simplesmente recorrerá aos recursos da cultura padrão. Em seguida, você pode usar os ResourceSet métodos para acessar os recursos (localizados para essa cultura) pelo nome ou enumerar os recursos no conjunto.

Processar exceções MissingManifestResourceException e MissingSatelliteAssemblyException

Se você tentar recuperar um recurso específico, mas o gerenciador de recursos não conseguir encontrar esse recurso e nenhuma cultura padrão tiver sido definida ou os recursos dela não puderem ser localizados, o gerenciador de recursos lançará uma exceção MissingManifestResourceException se esperar encontrar os recursos no assembly principal ou MissingSatelliteAssemblyException se esperar encontrar os recursos em um assembly satélite. Observe que a exceção é gerada quando você chama um método de recuperação de recurso, como GetString ou GetObject, e não quando você cria uma instância de um ResourceManager objeto.

Normalmente, a exceção é gerada nas seguintes condições:

  • O arquivo de recurso apropriado ou o assembly satélite não existe. Se o gerenciador de recursos espera que os recursos padrão do aplicativo estejam inseridos no assembly principal do aplicativo, eles estão ausentes. Se o atributo NeutralResourcesLanguageAttribute indicar que os recursos padrão do aplicativo residem em um assembly satélite, esse assembly não poderá ser encontrado. Ao compilar seu aplicativo, verifique se os recursos estão inseridos no assembly principal ou se o assembly satélite necessário é gerado e é nomeado adequadamente. Seu nome deve usar o formato appName.resources.dlle deve estar localizado em um diretório nomeado conforme a cultura cujos recursos contém.

  • Seu aplicativo não tem uma cultura padrão ou neutra definida. Adicione o NeutralResourcesLanguageAttribute atributo a um arquivo de código-fonte ou ao arquivo de informações do projeto (AssemblyInfo.vb para um aplicativo do Visual Basic ou AssemblyInfo.cs para um aplicativo C#).

  • O baseName parâmetro no ResourceManager(String, Assembly) construtor não especifica o nome de um arquivo .resources. O nome deve incluir o namespace totalmente qualificado do arquivo de recurso, mas não sua extensão de nome de arquivo. Normalmente, os arquivos de recurso criados no Visual Studio incluem nomes de namespace, mas os arquivos de recurso criados e compilados no prompt de comando não. Você pode determinar os nomes dos arquivos .resources inseridos compilando e executando o utilitário a seguir. Este é um aplicativo de console que aceita o nome de uma assembleia principal ou assembleia satélite como parâmetro na linha de comando. Ele exibe as cadeias de caracteres que devem ser fornecidas como o baseName parâmetro para que o gerenciador de recursos possa identificar corretamente o recurso.

    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($"{filename} does not exist.");
             return;
          }   
          
          // Try to load the assembly.
          Assembly assem = Assembly.LoadFrom(filename);
          Console.WriteLine($"File: {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: {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
    

Se você estiver alterando explicitamente a cultura atual do aplicativo, lembre-se também de que o gerenciador de recursos recupera um conjunto de recursos com base no valor da CultureInfo.CurrentUICulture propriedade e não na CultureInfo.CurrentCulture propriedade. Normalmente, se você alterar um valor, também deverá alterar o outro.

Controle de versão de recursos

Como o assembly principal que contém os recursos padrão de um aplicativo é separado dos assemblies satélites do aplicativo, você pode lançar uma nova versão do assembly principal sem reimplantar os assemblies satélites. O atributo SatelliteContractVersionAttribute usa assemblies satélites existentes e instrui o gerenciador de recursos a não os reimplantar junto com uma nova versão do assembly principal.

Para obter mais informações sobre o suporte de controle de versão para assemblies satélites, consulte o artigo Recuperando recursos.

<satelliteassemblies> nó do arquivo de configuração

Observação

Esta seção é específica para aplicativos do .NET Framework.

Para executáveis implantados e executados em um site (arquivos HREF .exe), o objeto ResourceManager pode investigar assemblies satélite na Web, o que pode prejudicar o desempenho do aplicativo. Para eliminar o problema de desempenho, você pode limitar essa investigação aos assemblies satélites implantados com o aplicativo. Para fazer isso, crie um <satelliteassemblies> nó no arquivo de configuração do aplicativo para especificar que você implantou um conjunto específico de culturas para seu aplicativo e que o ResourceManager objeto não deve tentar investigar nenhuma cultura que não esteja listada nesse nó.

Observação

A alternativa preferencial para a criação de um nó <satelliteassemblies> é usar o recurso ClickOnce Deployment Manifest.

No arquivo de configuração do aplicativo, crie uma seção semelhante à seguinte:

<?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>

Edite estas informações de configuração da seguinte maneira:

  • Especifique um ou mais nós <assembly> para cada assembly principal que você implementar, em que cada nó especifica um nome totalmente qualificado de assembly. Especifique o nome do seu assembly principal no lugar de MainAssemblyName e especifique os valores de atributo Version, PublicKeyToken e Culture que correspondem ao seu assembly principal.

    Para o Version atributo, especifique o número de versão do assembly. Por exemplo, a primeira versão do assembly pode ser a versão número 1.0.0.0.

    Para o PublicKeyToken atributo, especifique a palavra-chave null se você não assinou seu assembly com um nome forte ou especifique seu token de chave pública se tiver assinado o assembly.

    Para o atributo Culture, especifique a palavra-chave neutral para designar o assembly principal e faça a classe ResourceManager investigar apenas as culturas listadas nos nós <culture>.

    Para obter mais informações sobre nomes de assembly totalmente qualificados, consulte o artigo Nomes de assembly. Para obter mais informações sobre assemblies de nome forte, consulte o artigo Criar e usar assemblies de nome forte.

  • Especifique um ou mais nós <culture> com um nome de cultura específico, como "fr-FR", ou um nome de cultura neutro, como "fr".

Se forem necessários recursos para qualquer assembly não listado no nó <satelliteassemblies>, a classe ResourceManager investigará culturas usando regras de investigação padrão.

Aplicativos do Windows 8.x

Importante

Embora a ResourceManager classe tenha suporte em aplicativos do Windows 8.x, não recomendamos seu uso. Use essa classe somente quando você desenvolver projetos da Biblioteca de Classes Portátil que podem ser usados com aplicativos do Windows 8.x. Para recuperar recursos de aplicativos do Windows 8.x, use a classe Windows.ApplicationModel.Resources.ResourceLoader.

Para aplicativos do Windows 8.x, a ResourceManager classe recupera recursos de arquivos PRI (índice de recursos de pacote). Um único arquivo PRI (o arquivo PRI do pacote de aplicativos) contém os recursos para a cultura padrão e quaisquer culturas localizadas. Use o utilitário MakePRI para criar um arquivo PRI de um ou mais arquivos de recurso que estão no formato de recurso XML (.resw). Para recursos incluídos em um projeto do Visual Studio, o Visual Studio manipula o processo de criação e empacotamento automático do arquivo PRI. Em seguida, você pode usar a classe .NET ResourceManager para acessar os recursos do aplicativo ou da biblioteca.

Você pode criar uma instância de um objeto ResourceManager para um aplicativo Windows 8.x da mesma forma que faz para um aplicativo de desktop.

Em seguida, você pode acessar os recursos de uma cultura específica passando o nome do recurso a ser recuperado para o GetString(String) método. Por padrão, esse método retorna o recurso para a cultura determinada pela cultura de interface atual do thread que executou a chamada. Você também pode recuperar os recursos de uma cultura específica passando o nome do recurso e um CultureInfo objeto que representa a cultura cujo recurso deve ser recuperado para o GetString(String, CultureInfo) método. Se o recurso para a cultura de interface do usuário atual ou a cultura especificada não puder ser encontrado, o gerenciador de recursos usará uma lista de fallback de linguagem de interface do usuário para localizar um recurso adequado.

Exemplos

O exemplo a seguir demonstra como usar uma cultura explícita e a cultura de interface atual implícita para obter recursos de cadeia de caracteres de um assembly principal e de um assembly satélite. Para obter mais informações, consulte a seção "Locais de diretório para assemblies satélites não instalados no cache global de assembly" do tópico Criando assemblies satélites.

Para executar este exemplo:

  1. No diretório do aplicativo, crie um arquivo chamado rmc.txt que contenha as seguintes cadeias de caracteres de recurso:

    day=Friday
    year=2006
    holiday="Cinco de Mayo"
    
  2. Use o Gerador de Arquivos de Recurso para gerar o arquivo de recurso rmc.resources do arquivo de entrada rmc.txt da seguinte maneira:

    resgen rmc.txt
    
  3. Crie um subdiretório do diretório do aplicativo e nomeie-o como "es-MX". Esse é o nome da cultura do assembly satélite que você criará nas próximas três etapas.

  4. Crie um arquivo chamado rmc.es-MX.txt no diretório es-MX que contém as seguintes cadeias de caracteres de recurso:

    day=Viernes
    year=2006
    holiday="Cinco de Mayo"
    
  5. Use o Gerador de Arquivos de Recurso para gerar o arquivo de recurso rmc.es-MX.resources a partir do arquivo de entrada rmc.es-MX.txt da seguinte forma:

    resgen rmc.es-MX.txt
    
  6. Suponha que o nome do arquivo para este exemplo seja rmc.vb ou rmc.cs. Copie o código-fonte a seguir em um arquivo. Em seguida, compile-o e insira o arquivo de recurso do assembly principal, rmc.resources, no assembly executável. Se você estiver usando o compilador do Visual Basic, a sintaxe será:

    vbc rmc.vb /resource:rmc.resources
    

    A sintaxe correspondente para o compilador C# é:

    csc /resource:rmc.resources rmc.cs
    
  7. Para criar um assembly satélite, use o Assembly Linker. Se o nome base do aplicativo for rmc, o nome do assembly satélite deverá ser rmc.resources.dll. A montagem do satélite deve ser criada no diretório es-MX. Se es-MX for o diretório atual, use este comando:

    al /embed:rmc.es-MX.resources /c:es-MX /out:rmc.resources.dll
    
  8. Execute rmc.exe para obter e exibir as cadeias de caracteres de recurso inseridas.

    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.