Recuperar recursos em aplicativos .NET

Quando você trabalha com recursos localizados em aplicativos .NET, idealmente deve empacotar os recursos para a cultura padrão ou neutra com o assembly principal e criar um assembly satélite separado para cada idioma ou cultura suportada pelo seu aplicativo. Em seguida, você pode usar a ResourceManager classe conforme descrito na próxima seção para acessar recursos nomeados. Se você optar por não incorporar seus recursos no assembly principal e nos assemblies satélite, também poderá acessar arquivos .resources binários diretamente, conforme discutido na seção Recuperar recursos de arquivos .resources mais adiante neste artigo.

Recuperar recursos de assemblies

A ResourceManager classe fornece acesso a recursos em tempo de execução. Use o ResourceManager.GetString método para recuperar recursos de cadeia de caracteres e o ResourceManager.GetObject método ou ResourceManager.GetStream para recuperar recursos que não sejam de cadeia de caracteres. Cada método tem duas sobrecargas:

O gerenciador de recursos usa o processo de fallback de recursos para controlar como o aplicativo recupera recursos específicos da cultura. Para obter mais informações, consulte a seção "Processo de fallback de recursos" em Empacotar e implantar recursos. Para obter informações sobre como instanciar um ResourceManager objeto, consulte a seção "Instanciando um objeto ResourceManager" no tópico da ResourceManager classe.

Exemplo de recuperação de dados de cadeia de caracteres

O exemplo a seguir chama o GetString(String) método para recuperar os recursos de cadeia de caracteres da cultura atual da interface do usuário. Inclui um recurso de cadeia de caracteres neutro para a cultura inglesa (Estados Unidos) e recursos localizados para as culturas francesa (França) e russa (Rússia). O seguinte recurso em inglês (Estados Unidos) está em um arquivo chamado Strings.txt:

TimeHeader=The current time is

O recurso francês (França) está em um arquivo chamado Strings.fr-FR.txt:

TimeHeader=L'heure actuelle est

O recurso russo (Rússia) está em um arquivo chamado Strings.ru-RU.txt:

TimeHeader=Текущее время —

O código-fonte deste exemplo, que está em um arquivo chamado GetString.cs para a versão C# do código e GetString.vb para a versão do Visual Basic, define uma matriz de cadeia de caracteres que contém o nome de quatro culturas: as três culturas para as quais os recursos estão disponíveis e a cultura espanhola (Espanha). Um loop que executa cinco vezes aleatoriamente seleciona uma dessas culturas e a atribui às Thread.CurrentCulture propriedades e CultureInfo.CurrentUICulture . Em seguida, ele chama o GetString(String) método para recuperar a cadeia de caracteres localizada, que ele exibe junto com a hora do dia.

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

[assembly: NeutralResourcesLanguageAttribute("en-US")]

public class Example
{
   public static void Main()
   {
      string[] cultureNames = { "en-US", "fr-FR", "ru-RU", "es-ES" };
      Random rnd = new Random();
      ResourceManager rm = new ResourceManager("Strings",
                               typeof(Example).Assembly);

      for (int ctr = 0; ctr <= cultureNames.Length; ctr++) {
         string cultureName = cultureNames[rnd.Next(0, cultureNames.Length)];
         CultureInfo culture = CultureInfo.CreateSpecificCulture(cultureName);
         Thread.CurrentThread.CurrentCulture = culture;
         Thread.CurrentThread.CurrentUICulture = culture;

         Console.WriteLine("Current culture: {0}", culture.NativeName);
         string timeString = rm.GetString("TimeHeader");
         Console.WriteLine("{0} {1:T}\n", timeString, DateTime.Now);
      }
   }
}
// The example displays output like the following:
//    Current culture: English (United States)
//    The current time is 9:34:18 AM
//
//    Current culture: Español (España, alfabetización internacional)
//    The current time is 9:34:18
//
//    Current culture: русский (Россия)
//    Текущее время — 9:34:18
//
//    Current culture: français (France)
//    L'heure actuelle est 09:34:18
//
//    Current culture: русский (Россия)
//    Текущее время — 9:34:18
Imports System.Globalization
Imports System.Resources
Imports System.Threading

<Assembly: NeutralResourcesLanguageAttribute("en-US")>

Module Example
    Public Sub Main()
        Dim cultureNames() As String = {"en-US", "fr-FR", "ru-RU", "es-ES"}
        Dim rnd As New Random()
        Dim rm As New ResourceManager("Strings", GetType(Example).Assembly)

        For ctr As Integer = 0 To cultureNames.Length
            Dim cultureName As String = cultureNames(rnd.Next(0, cultureNames.Length))
            Dim culture As CultureInfo = CultureInfo.CreateSpecificCulture(cultureName)
            Thread.CurrentThread.CurrentCulture = culture
            Thread.CurrentThread.CurrentUICulture = culture

            Console.WriteLine("Current culture: {0}", culture.NativeName)
            Dim timeString As String = rm.GetString("TimeHeader")
            Console.WriteLine("{0} {1:T}", timeString, Date.Now)
            Console.WriteLine()
        Next
    End Sub
End Module
' The example displays output similar to the following:
'    Current culture: English (United States)
'    The current time is 9:34:18 AM
'    
'    Current culture: Español (España, alfabetización internacional)
'    The current time is 9:34:18
'    
'    Current culture: русский (Россия)
'    Текущее время — 9:34:18
'    
'    Current culture: français (France)
'    L'heure actuelle est 09:34:18
'    
'    Current culture: русский (Россия)
'    Текущее время — 9:34:18

O seguinte arquivo de lote (.bat) compila o exemplo e gera assemblies satélite nos diretórios apropriados. Os comandos são fornecidos para a linguagem C# e compilador. Para Visual Basic, altere csc para vbce altere GetString.cs para GetString.vb.

resgen strings.txt
csc GetString.cs -resource:strings.resources

resgen strings.fr-FR.txt
md fr-FR
al -embed:strings.fr-FR.resources -culture:fr-FR -out:fr-FR\GetString.resources.dll

resgen strings.ru-RU.txt
md ru-RU
al -embed:strings.ru-RU.resources -culture:ru-RU -out:ru-RU\GetString.resources.dll

Quando a cultura atual da interface do usuário é espanhol (Espanha), observe que o exemplo exibe recursos do idioma inglês, porque os recursos do idioma espanhol não estão disponíveis, e o inglês é a cultura padrão do exemplo.

Recuperar exemplos de dados de objeto

Você pode usar os métodos e GetStream para recuperar dados de GetObject objeto. Isso inclui tipos de dados primitivos, objetos serializáveis e objetos armazenados em formato binário (como imagens).

O exemplo a seguir usa o GetStream(String) método para recuperar um bitmap que é usado na janela inicial de abertura de um aplicativo. O código-fonte a seguir em um arquivo chamado CreateResources.cs (para C#) ou CreateResources.vb (para Visual Basic) gera um arquivo .resx que contém a imagem serializada. Nesse caso, a imagem é carregada de um arquivo chamado SplashScreen.jpg; Você pode modificar o nome do arquivo para substituir sua própria imagem.

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Resources;

public class Example
{
   public static void Main()
   {
      Bitmap bmp = new Bitmap(@".\SplashScreen.jpg");
      MemoryStream imageStream = new MemoryStream();
      bmp.Save(imageStream, ImageFormat.Jpeg);

      ResXResourceWriter writer = new ResXResourceWriter("AppResources.resx");
      writer.AddResource("SplashScreen", imageStream);
      writer.Generate();
      writer.Close();
   }
}
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.IO
Imports System.Resources

Module Example
    Public Sub Main()
        Dim bmp As New Bitmap(".\SplashScreen.jpg")
        Dim imageStream As New MemoryStream()
        bmp.Save(imageStream, ImageFormat.Jpeg)

        Dim writer As New ResXResourceWriter("AppResources.resx")
        writer.AddResource("SplashScreen", imageStream)
        writer.Generate()
        writer.Close()
    End Sub
End Module

O código a seguir recupera o recurso e exibe a imagem em um PictureBox controle.

using System;
using System.Drawing;
using System.IO;
using System.Resources;
using System.Windows.Forms;

public class Example
{
   public static void Main()
   {
      ResourceManager rm = new ResourceManager("AppResources", typeof(Example).Assembly);
      Bitmap screen = (Bitmap) Image.FromStream(rm.GetStream("SplashScreen"));

      Form frm = new Form();
      frm.Size = new Size(300, 300);

      PictureBox pic = new PictureBox();
      pic.Bounds = frm.RestoreBounds;
      pic.BorderStyle = BorderStyle.Fixed3D;
      pic.Image = screen;
      pic.SizeMode = PictureBoxSizeMode.StretchImage;

      frm.Controls.Add(pic);
      pic.Anchor = AnchorStyles.Top | AnchorStyles.Bottom |
                   AnchorStyles.Left | AnchorStyles.Right;

      frm.ShowDialog();
   }
}
Imports System.Drawing
Imports System.IO
Imports System.Resources
Imports System.Windows.Forms

Module Example
    Public Sub Main()
        Dim rm As New ResourceManager("AppResources", GetType(Example).Assembly)
        Dim screen As Bitmap = CType(Image.FromStream(rm.GetStream("SplashScreen")), Bitmap)

        Dim frm As New Form()
        frm.Size = new Size(300, 300)

        Dim pic As New PictureBox()
        pic.Bounds = frm.RestoreBounds
        pic.BorderStyle = BorderStyle.Fixed3D
        pic.Image = screen
        pic.SizeMode = PictureBoxSizeMode.StretchImage

        frm.Controls.Add(pic)
        pic.Anchor = AnchorStyles.Top Or AnchorStyles.Bottom Or
                     AnchorStyles.Left Or AnchorStyles.Right

        frm.ShowDialog()
    End Sub
End Module

Você pode usar o seguinte arquivo em lotes para criar o exemplo em C#. Para Visual Basic, altere csc para vbce altere a extensão do arquivo de código-fonte de .cs para .vb.

csc CreateResources.cs
CreateResources

resgen AppResources.resx

csc GetStream.cs -resource:AppResources.resources

O exemplo a seguir usa o ResourceManager.GetObject(String) método para desserializar um objeto personalizado. O exemplo inclui um arquivo de código-fonte chamado UIElements.cs (UIElements.vb para Visual Basic) que define a seguinte estrutura chamada PersonTable. Essa estrutura destina-se a ser usada por uma rotina geral de exibição de tabela que exibe os nomes localizados das colunas da tabela. Observe que a estrutura está marcada PersonTable com o SerializableAttribute atributo.

using System;

[Serializable] public struct PersonTable
{
   public readonly int nColumns;
   public readonly string column1;
   public readonly string column2;
   public readonly string column3;
   public readonly int width1;
   public readonly int width2;
   public readonly int width3;

   public PersonTable(string column1, string column2, string column3,
                  int width1, int width2, int width3)
   {
      this.column1 = column1;
      this.column2 = column2;
      this.column3 = column3;
      this.width1 = width1;
      this.width2 = width2;
      this.width3 = width3;
      this.nColumns = typeof(PersonTable).GetFields().Length / 2;
   }
}
<Serializable> Public Structure PersonTable
    Public ReadOnly nColumns As Integer
    Public Readonly column1 As String
    Public ReadOnly column2 As String
    Public ReadOnly column3 As String
    Public ReadOnly width1 As Integer
    Public ReadOnly width2 As Integer
    Public ReadOnly width3 As Integer

    Public Sub New(column1 As String, column2 As String, column3 As String,
                   width1 As Integer, width2 As Integer, width3 As Integer)
        Me.column1 = column1
        Me.column2 = column2
        Me.column3 = column3
        Me.width1 = width1
        Me.width2 = width2
        Me.width3 = width3
        Me.nColumns = Me.GetType().GetFields().Count \ 2
    End Sub
End Structure

O código a seguir de um arquivo chamado CreateResources.cs (CreateResources.vb para Visual Basic) cria um arquivo de recurso XML chamado UIResources.resx que armazena um título de tabela e um PersonTable objeto que contém informações para um aplicativo localizado para o idioma inglês.

using System;
using System.Resources;

public class CreateResource
{
   public static void Main()
   {
      PersonTable table = new PersonTable("Name", "Employee Number",
                                          "Age", 30, 18, 5);
      ResXResourceWriter rr = new ResXResourceWriter(@".\UIResources.resx");
      rr.AddResource("TableName", "Employees of Acme Corporation");
      rr.AddResource("Employees", table);
      rr.Generate();
      rr.Close();
   }
}
Imports System.Resources

Module CreateResource
    Public Sub Main()
        Dim table As New PersonTable("Name", "Employee Number", "Age", 30, 18, 5)
        Dim rr As New ResXResourceWriter(".\UIResources.resx")
        rr.AddResource("TableName", "Employees of Acme Corporation")
        rr.AddResource("Employees", table)
        rr.Generate()
        rr.Close()
    End Sub
End Module

O código a seguir em um arquivo de código-fonte chamado GetObject.cs (GetObject.vb) recupera os recursos e os exibe no console.

using System;
using System.Resources;

[assembly: NeutralResourcesLanguageAttribute("en")]

public class Example
{
   public static void Main()
   {
      string fmtString = String.Empty;
      ResourceManager rm = new ResourceManager("UIResources", typeof(Example).Assembly);
      string title = rm.GetString("TableName");
      PersonTable tableInfo = (PersonTable) rm.GetObject("Employees");

      if (! String.IsNullOrEmpty(title)) {
         fmtString = "{0," + ((Console.WindowWidth + title.Length) / 2).ToString() + "}";
         Console.WriteLine(fmtString, title);
         Console.WriteLine();
      }

      for (int ctr = 1; ctr <= tableInfo.nColumns; ctr++) {
         string columnName = "column"  + ctr.ToString();
         string widthName = "width" + ctr.ToString();
         string value = tableInfo.GetType().GetField(columnName).GetValue(tableInfo).ToString();
         int width = (int) tableInfo.GetType().GetField(widthName).GetValue(tableInfo);
         fmtString = "{0,-" + width.ToString() + "}";
         Console.Write(fmtString, value);
      }
      Console.WriteLine();
   }
}
Imports System.Resources

<Assembly: NeutralResourcesLanguageAttribute("en")>

Module Example
    Public Sub Main()
        Dim fmtString As String = String.Empty
        Dim rm As New ResourceManager("UIResources", GetType(Example).Assembly)
        Dim title As String = rm.GetString("TableName")
        Dim tableInfo As PersonTable = DirectCast(rm.GetObject("Employees"), PersonTable)

        If Not String.IsNullOrEmpty(title) Then
            fmtString = "{0," + ((Console.WindowWidth + title.Length) \ 2).ToString() + "}"
            Console.WriteLine(fmtString, title)
            Console.WriteLine()
        End If

        For ctr As Integer = 1 To tableInfo.nColumns
            Dim columnName As String = "column" + ctr.ToString()
            Dim widthName As String = "width" + ctr.ToString()
            Dim value As String = CStr(tableInfo.GetType().GetField(columnName).GetValue(tableInfo))
            Dim width As Integer = CInt(tableInfo.GetType().GetField(widthName).GetValue(tableInfo))
            fmtString = "{0,-" + width.ToString() + "}"
            Console.Write(fmtString, value)
        Next
        Console.WriteLine()
    End Sub
End Module

Você pode criar o arquivo de recursos e assemblies necessários e executar o aplicativo executando o seguinte arquivo em lotes. Você deve usar a /r opção para fornecer Resgen.exe uma referência a UIElements.dll para que ele possa acessar informações sobre a PersonTable estrutura. Se você estiver usando C#, substitua o nome do vbc compilador por csc, e substitua a .vb extensão por .cs.

vbc -t:library UIElements.vb
vbc CreateResources.vb -r:UIElements.dll
CreateResources

resgen UIResources.resx  -r:UIElements.dll
vbc GetObject.vb -r:UIElements.dll -resource:UIResources.resources

GetObject.exe

Suporte de versão para montagens satélite

Por padrão, quando o ResourceManager objeto recupera recursos solicitados, ele procura assemblies satélite que tenham números de versão que correspondam ao número da versão do assembly principal. Depois de implantar um aplicativo, convém atualizar o assembly principal ou assemblies satélites de recursos específicos. O .NET Framework fornece suporte para versionamento do assembly principal e assemblies satélite.

O SatelliteContractVersionAttribute atributo fornece suporte de controle de versão para um assembly principal. Especificar esse atributo no assembly principal de um aplicativo permite que você atualize e reimplante um assembly principal sem atualizar seus assemblies satélite. Depois de atualizar o assembly principal, incremente o número da versão do assembly principal, mas deixe o número da versão do contrato satélite inalterado. Quando o gerenciador de recursos recupera os recursos solicitados, ele carrega a versão do assembly satélite especificada por esse atributo.

Os assemblies de política do editor fornecem suporte para assemblies satélites de controle de versão. Você pode atualizar e reimplantar um assembly satélite sem atualizar o assembly principal. Depois de atualizar um assembly satélite, incremente seu número de versão e envie-o com um assembly de política do editor. No assembly de política do editor, especifique que o novo assembly satélite é compatível com versões anteriores dele. O gerenciador de recursos usará o SatelliteContractVersionAttribute atributo para determinar a versão do assembly satélite, mas o carregador de assembly se ligará à versão do assembly satélite especificada pela política do editor. Para obter mais informações sobre assemblies de política do editor, consulte Criar um arquivo de política do editor.

Para habilitar o suporte total ao controle de versão de assembly, recomendamos que você implante assemblies de nome forte no cache de assembly global e implante assemblies que não tenham nomes fortes no diretório do aplicativo. Se desejar implantar assemblies de nome forte no diretório do aplicativo, não será possível incrementar o número de versão de um assembly satélite quando atualizar o assembly. Em vez disso, você deve executar uma atualização in-loco onde você substituir o código existente com o código atualizado e manter o mesmo número de versão. Por exemplo, se você quiser atualizar a versão 1.0.0.0 de um assembly satélite com o nome de assembly totalmente especificado "myApp.resources, Version=1.0.0.0, Culture=de, PublicKeyToken=b03f5f11d50a3a", substitua-o pelo myApp.resources.dll atualizado que foi compilado com o mesmo nome de assembly totalmente especificado "myApp.resources, Version=1.0.0.0, Culture=de, PublicKeyToken=b03f5f11d50a3a". Observe que o uso de atualizações in-loco em arquivos de montagem de satélite torna difícil para um aplicativo determinar com precisão a versão de um assembly de satélite.

Para obter mais informações sobre o controle de versão de assembly, consulte Assembly versioning e How the Runtime locates assemblies.

Recuperar recursos de arquivos .resources

Se você optar por não implantar recursos em assemblies satélite, ainda poderá usar um ResourceManager objeto para acessar recursos de arquivos .resources diretamente. Para fazer isso, você deve implantar os arquivos .resources corretamente. Em seguida, use o ResourceManager.CreateFileBasedResourceManager método para instanciar um ResourceManager objeto e especificar o diretório que contém os arquivos .resources autônomos.

Implantar arquivos .resources

Quando você incorpora arquivos .resources em um assembly de aplicativo e assemblies satélite, cada assembly satélite tem o mesmo nome de arquivo, mas é colocado em um subdiretório que reflete a cultura do assembly satélite. Por outro lado, quando você acessa recursos de arquivos .resources diretamente, você pode colocar todos os arquivos .resources em um único diretório, geralmente um subdiretório do diretório do aplicativo. O nome do arquivo .resources padrão do aplicativo consiste apenas em um nome de raiz, sem indicação de sua cultura (por exemplo, strings.resources). Os recursos para cada cultura localizada são armazenados em um arquivo cujo nome consiste no nome da raiz seguido pela cultura (por exemplo, strings.ja.resources ou strings.de-DE.resources).

A ilustração a seguir mostra onde os arquivos de recursos devem estar localizados na estrutura de diretórios. Ele também fornece as convenções de nomenclatura para arquivos .resource.

Ilustração que mostra o diretório principal do seu aplicativo.

Utilizar o gestor de recursos

Depois de criar seus recursos e colocá-los no diretório apropriado, você cria um ResourceManager objeto para usar os recursos chamando o CreateFileBasedResourceManager(String, String, Type) método. O primeiro parâmetro especifica o nome raiz do arquivo .resources padrão do aplicativo (isso seria "strings" para o exemplo na seção anterior). O segundo parâmetro especifica o local dos recursos ("Resources" para o exemplo anterior). O terceiro parâmetro especifica a ResourceSet implementação a ser usada. Se o terceiro parâmetro for null, o tempo de execução ResourceSet padrão será usado.

Nota

Não implante aplicativos ASP.NET usando arquivos .resources autônomos. Isso pode causar problemas de bloqueio e interromper a implantação do XCOPY. Recomendamos que você implante recursos ASP.NET em assemblies satélites. Para obter mais informações, consulte Visão geral ASP.NET recursos de página da Web.

Depois de instanciar o ResourceManager objeto, use os GetStringmétodos , GetObjecte GetStream conforme discutido anteriormente para recuperar os recursos. No entanto, a recuperação de recursos diretamente de arquivos .resources difere da recuperação de recursos incorporados de assemblies. Quando você recupera recursos de arquivos .resources, os GetString(String)métodos , GetObject(String)e GetStream(String) sempre recuperam os recursos da cultura padrão, independentemente da cultura atual. Para recuperar os recursos da cultura atual do aplicativo ou de uma cultura específica, você deve chamar o GetString(String, CultureInfo)método , GetObject(String, CultureInfo)ou GetStream(String, CultureInfo) e especificar a cultura cujos recursos devem ser recuperados. Para recuperar os recursos da cultura atual, especifique o CultureInfo.CurrentCulture valor da propriedade como o culture argumento. Se o gerenciador de recursos não puder recuperar os recursos do , ele usará as regras de fallback de culturerecursos padrão para recuperar os recursos apropriados.

Um exemplo

O exemplo a seguir ilustra como o gerenciador de recursos recupera recursos diretamente de arquivos .resources. O exemplo consiste em três arquivos de recursos baseados em texto para as culturas inglesa (Estados Unidos), francesa (França) e russa (Rússia). Inglês (Estados Unidos) é a cultura padrão do exemplo. Seus recursos são armazenados no seguinte arquivo chamado Strings.txt:

Greeting=Hello
Prompt=What is your name?

Os recursos para a cultura francesa (França) são armazenados no seguinte arquivo, que é chamado Strings.fr-FR.txt:

Greeting=Bon jour
Prompt=Comment vous appelez-vous?

Os recursos para a cultura russa (Rússia) são armazenados no seguinte arquivo, que é chamado Strings.ru-RU.txt:

Greeting=Здравствуйте
Prompt=Как вас зовут?

A seguir está o código-fonte para o exemplo. O exemplo instancia CultureInfo objetos para as culturas inglesa (Estados Unidos), inglesa (Canadá), francesa (França) e russa (Rússia) e torna cada uma a cultura atual. Em ResourceManager.GetString(String, CultureInfo) seguida, o CultureInfo.CurrentCulture método fornece o valor da propriedade como o culture argumento para recuperar os recursos específicos da cultura apropriados.

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

[assembly: NeutralResourcesLanguage("en-US")]

public class Example
{
   public static void Main()
   {
      string[] cultureNames = { "en-US", "en-CA", "ru-RU", "fr-FR" };
      ResourceManager rm = ResourceManager.CreateFileBasedResourceManager("Strings", "Resources", null);

      foreach (var cultureName in cultureNames) {
         Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureName);
         string greeting = rm.GetString("Greeting", CultureInfo.CurrentCulture);
         Console.WriteLine("\n{0}!", greeting);
         Console.Write(rm.GetString("Prompt", CultureInfo.CurrentCulture));
         string name = Console.ReadLine();
         if (! String.IsNullOrEmpty(name))
            Console.WriteLine("{0}, {1}!", greeting, name);
      }
      Console.WriteLine();
   }
}
// The example displays output like the following:
//       Hello!
//       What is your name? Dakota
//       Hello, Dakota!
//
//       Hello!
//       What is your name? Koani
//       Hello, Koani!
//
//       Здравствуйте!
//       Как вас зовут?Samuel
//       Здравствуйте, Samuel!
//
//       Bon jour!
//       Comment vous appelez-vous?Yiska
//       Bon jour, Yiska!
Imports System.Globalization
Imports System.Resources
Imports System.Threading

<Assembly: NeutralResourcesLanguageAttribute("en-US")>

Module Example
    Public Sub Main()
        Dim cultureNames() As String = {"en-US", "en-CA", "ru-RU", "fr-FR"}
        Dim rm As ResourceManager = ResourceManager.CreateFileBasedResourceManager("Strings", "Resources", Nothing)

        For Each cultureName In cultureNames
            Console.WriteLine()
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureName)
            Dim greeting As String = rm.GetString("Greeting", CultureInfo.CurrentCulture)
            Console.WriteLine("{0}!", greeting)
            Console.Write(rm.GetString("Prompt", CultureInfo.CurrentCulture))
            Dim name As String = Console.ReadLine()
            If Not String.IsNullOrEmpty(name) Then
                Console.WriteLine("{0}, {1}!", greeting, name)
            End If
        Next
        Console.WriteLine()
    End Sub
End Module
' The example displays output like the following:
'       Hello!
'       What is your name? Dakota
'       Hello, Dakota!
'       
'       Hello!
'       What is your name? Koani
'       Hello, Koani!
'       
'       Здравствуйте!
'       Как вас зовут?Samuel
'       Здравствуйте, Samuel!
'       
'       Bon jour!
'       Comment vous appelez-vous?Yiska
'       Bon jour, Yiska!

Você pode compilar a versão C# do exemplo executando o seguinte arquivo em lotes. Se você estiver usando o Visual Basic, substitua csc por vbc, e substitua a .cs extensão por .vb.

md Resources
resgen Strings.txt Resources\Strings.resources
resgen Strings.fr-FR.txt Resources\Strings.fr-FR.resources
resgen Strings.ru-RU.txt Resources\Strings.ru-RU.resources

csc Example.cs

Consulte também