Criar arquivos de recurso para aplicativos .NET

Você pode incluir recursos, como cadeias de caracteres, imagens ou dados de objetos em arquivos de recursos para torná-los facilmente disponíveis no seu aplicativo. O .NET Framework tem cinco maneiras de criar arquivos de recursos:

  • Crie um arquivo de texto que contenha recursos de cadeia de caracteres. Você pode usar o Gerador de Arquivo de Recurso (resgen.exe) para converter o arquivo de texto em um arquivo de recurso binário (.resources). Em seguida, pode inserir o arquivo de recurso binário em um aplicativo executável ou em uma biblioteca de aplicativos usando um compilador de linguagem, ou você pode inseri-la em um assembly satélite usando o Assembly Linker (Al.exe). Para obter mais informações, consulte a seção Recursos em arquivos de texto.

  • Criar um arquivo de recurso XML (.resx) que contenha a cadeia de caracteres, imagens ou dados de objeto. Você pode usar o Gerador de Arquivo de Recurso (resgen.exe) para converter o arquivo .resx em um arquivo de recurso binário (.resources). Em seguida, pode inserir o arquivo de recurso binário em um aplicativo executável ou em uma biblioteca de aplicativos usando um compilador de linguagem, ou você pode inseri-la em um assembly satélite usando o Assembly Linker (Al.exe). Para obter mais informações, confira a secção Recursos em Arquivos .resx.

  • Crie um arquivo de recurso XML (.resx) com programação usando os tipos no namespace System.Resources. Pode criar um arquivo .resx, enumerar os seus recursos e recuperar os recursos específicos pelo seu nome. Para obter mais informações, confira Trabalhando com arquivos .resx de forma programática.

  • Criar um arquivo de recurso binário (.resources) de forma programática. Em seguida, pode inserir o arquivo em um aplicativo executável ou em uma biblioteca de aplicativos usando um compilador de linguagem, ou você pode inseri-la em um assembly satélite usando o Assembly Linker (Al.exe). Para obter mais informações, confira a secção Recursos em Arquivos .resources.

  • Use o Visual Studio para criar um arquivo de recursos e incluí-lo em seu projeto. O Visual Studio fornece um editor de recursos que lhe permite adicionar, excluir e modificar recursos. No momento da compilação, o arquivo de recurso é automaticamente convertido em um arquivo binário .resources e inserido em um assembly de aplicativo ou em um assembly satélite. Para obter mais informações, consulte a seção Arquivos de recurso no Visual Studio.

Recursos em arquivos de texto

Você pode usar arquivos de texto (.txt ou .restext) para armazenar apenas os recursos de cadeia de caracteres. Para recursos que não são cadeia de caracteres, use arquivos .resx ou crie-os por meio de programação. Os arquivos de texto que contêm recursos de cadeia de caracteres têm o seguinte formato:

# This is an optional comment.
name = value

; This is another optional comment.
name = value

; The following supports conditional compilation if X is defined.
#ifdef X
name1=value1
name2=value2
#endif

# The following supports conditional compilation if Y is undefined.
#if !Y
name1=value1
name2=value2
#endif

O formato do arquivo de recursos de .txt e dos arquivos .restext é idêntico. A extensão de arquivo .restext serve apenas para tornar os arquivos de texto imediatamente identificáveis como arquivos de recurso baseados em texto.

Os recursos de cadeia de caracteres são exibidos como pares nome/valor, em que nome é uma cadeia que identifica o recurso e valor é a cadeia de recurso que é retornada quando passa o nome para um método de recuperação de recursos, como ResourceManager.GetString. O nome e o valor devem ser separados por um sinal de igual (=). Por exemplo:

FileMenuName=File
EditMenuName=Edit
ViewMenuName=View
HelpMenuName=Help

Cuidado

Não use arquivos de recurso para armazenar senhas, informações confidenciais ou dados privados.

Cadeias de caracteres vazias (ou seja, um recurso cujo valor é String.Empty) são permitidas em arquivos de texto. Por exemplo:

EmptyString=

A partir do .NET Framework 4.5 e em todas as versões do .NET Core, os arquivos de texto oferecem suporte à compilação condicional com as construções #ifdefsímbolo... #endif e #if !símbolo... #endif. Em seguida, você poderá usar a opção /define com o Gerador de Arquivo de Recurso (resgen.exe) para definir os símbolos. Cada recurso requer a sua própria construção #ifdefsímbolo... #endif ou #if !símbolo... #endif. Se você usar uma instrução #ifdef e estiver definido o símbolo, o recurso associado é incluído no arquivo .resources; caso contrário, ele não será incluído. Se você usar uma instrução #if ! e não estiver definido o símbolo, o recurso associado é incluído no arquivo .resources; caso contrário, ele não será incluído.

Os comentários são opcionais em arquivos de texto e são precedidos por um ponto e vírgula (;) ou por um sinal de cerquilha (#) no início de uma linha. As linhas que contêm comentários podem ser colocadas em qualquer lugar no arquivo. Comentários não serão incluídos em um arquivo .resources compilado que foi criado usando o Gerador de Arquivo de Recurso (resgen.exe).

Todas as linhas em branco nos arquivos de texto são consideradas como espaços em branco e são ignoradas.

O exemplo a seguir define dois recursos de cadeia de caracteres denominados OKButton e CancelButton.

#Define resources for buttons in the user interface.
OKButton=OK
CancelButton=Cancel

Se o arquivo de texto contiver ocorrências de nome duplicadas, o Gerador de Arquivo de Recurso (resgen.exe) exibirá um aviso e ignorará o segundo nome.

O valor não poderá conter novos caracteres de linha, mas você poderá usar caracteres de escape no estilo da linguagem C, como \n para representar uma nova linha e \t para representar uma tabulação. Também poderá incluir um caractere de barra invertida se houver escape (por exemplo, "\\"). Além disso, é permitida uma cadeia de caracteres vazia.

Salve os recursos em formato de arquivo de texto usando a codificação UTF-8 ou a codificação UTF-16 na ordem de byte little-endian ou big-endian. No entanto, o Gerador de Arquivo de Recurso (resgen.exe), que converte um arquivo .txt em um arquivo .resources, trata os arquivos como UTF-8 por padrão. Se quiser que o Resgen.exe reconheça um arquivo codificado com UTF-16, deve incluir uma marca de ordem de byte Unicode (U + FEFF) no início do arquivo.

Para incorporar um arquivo de recurso em formato de texto em um assembly .NET, será necessário converter o arquivo em um arquivo de recurso binário (.resources) usando o Gerador de Arquivo de Recurso (resgen.exe). Em seguida, pode inserir o arquivo .resources em um assembly do .NET usando um compilador de linguagem, ou pode inseri-lo em um assembly satélite, usando o Assembly Linker (Al.exe).

O exemplo seguinte usa um arquivo de recursos no formato de texto chamado GreetingResources.txt para um aplicativo de console simples "Hello World". O arquivo de texto define duas cadeias de caracteres, prompt e greeting, que solicitam que o usuário digite o nome e exiba uma saudação.

# GreetingResources.txt
# A resource file in text format for a "Hello World" application.
#
# Initial prompt to the user.
prompt=Enter your name:
# Format string to display the result.
greeting=Hello, {0}!

O arquivo de texto é convertido em um arquivo .resources usando o seguinte comando:

resgen GreetingResources.txt

O exemplo a seguir mostra o código-fonte para um aplicativo de console que usa o arquivo .resources para exibir mensagens para o usuário.

using System;
using System.Reflection;
using System.Resources;

public class Example
{
   public static void Main()
   {
      ResourceManager rm = new ResourceManager("GreetingResources",
                               typeof(Example).Assembly);
      Console.Write(rm.GetString("prompt"));
      string name = Console.ReadLine();
      Console.WriteLine(rm.GetString("greeting"), name);
   }
}
// The example displays output like the following:
//       Enter your name: Wilberforce
//       Hello, Wilberforce!
Imports System.Reflection
Imports System.Resources

Module Example
    Public Sub Main()
        Dim rm As New ResourceManager("GreetingResources",
                                      GetType(Example).Assembly())
        Console.Write(rm.GetString("prompt"))
        Dim name As String = Console.ReadLine()
        Console.WriteLine(rm.GetString("greeting"), name)
    End Sub
End Module
' The example displays output like the following:
'       Enter your name: Wilberforce
'       Hello, Wilberforce!

Se você estiver usando o Visual Basic e o arquivo de código-fonte se chamar Greeting.vb, o comando a seguir cria um arquivo executável que inclui o arquivo .resources incorporado:

vbc greeting.vb -resource:GreetingResources.resources

Se você estiver usando o C# e o arquivo de código-fonte se chamar Greeting.cs, o comando a seguir cria um arquivo executável que inclui o arquivo .resources incorporado:

csc greeting.cs -resource:GreetingResources.resources

Recursos em arquivos .resx

Ao contrário dos arquivos de texto, que só podem armazenar recursos de cadeia de caracteres, os arquivos de recurso XML (.resx) podem armazenar cadeias de caracteres, dados binários como imagens, ícones e clipes de áudio e objetos de programação. Um arquivo .resx contém um cabeçalho padrão que descrevem o formato das entradas dos recursos e especifica informações de controle de versão para o XML usado para analisar os dados. Os dados do arquivo de recursos seguem o cabeçalho XML. Cada item de dados consiste em um par nome/valor que está contido numa marca data. O seu atributo name define o nome do recurso e a marca value aninhada contém o valor do recurso. Para dados de cadeia de caracteres, a marca value contém a cadeia de caracteres.

Por exemplo, a seguinte marca data define um recurso de cadeia de caracteres chamado prompt, cujo valor é "Digite seu nome:".

<data name="prompt" xml:space="preserve">
  <value>Enter your name:</value>
</data>

Aviso

Não use arquivos de recurso para armazenar senhas, informações confidenciais ou dados privados.

Para objetos de recurso, a marca de dados inclui um atributo type que indica o tipo de dados do recurso. Para os objetos que consistem em dados binários, a marca data também inclui um atributo mimetype, que indica o tipo de dados binários base64.

Observação

Todos os arquivos .resx usam um formatador de serialização binária para gerar e analisar os dados binários de um tipo especificado. Como resultado, um arquivo .resx pode se tornar inválido se formato da serialização binária de um objeto for alterada de um modo incompatível.

O exemplo a seguir mostra uma parte de um arquivo .resx que inclui um recurso Int32 e uma imagem de bitmap.

<data name="i1" type="System.Int32, mscorlib">
  <value>20</value>
</data>

<data name="flag" type="System.Drawing.Bitmap, System.Drawing,
    Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
    mimetype="application/x-microsoft.net.object.bytearray.base64">
  <value>
    AAEAAAD/////AQAAAAAAAAAMAgAAADtTeX…
  </value>
</data>

Importante

Como os arquivos .resx devem consistir em um XML bem formado num formato predefinido, não recomendamos que trabalhe manualmente com arquivos .resx, particularmente quando esses arquivos .resx contêm recursos além de cadeiras de caracteres. Em vez disso, o Visual Studio fornece uma interface transparente para criar e manipular arquivos .resx. Para obter mais informações, consulte a seção Arquivos de recurso no Visual Studio. Também pode criar e manipular arquivos .resx programaticamente. Para obter mais informações, consulte Trabalhar com arquivos .resx programaticamente.

Recursos em arquivos .resources

Você pode usar a classe System.Resources.ResourceWriter para criar um arquivo de recursos binário (.resources) com programação diretamente no código. Você também pode usar o Gerador de Arquivo de Recurso (resgen.exe) para criar um arquivo .resources a partir de um arquivo de texto ou de um arquivo .resx. O arquivo .resources pode conter dados binários (matrizes de bytes) e dados de objeto além dos dados de cadeia de caracteres. Criando um arquivo .resources programaticamente requer as seguintes etapas:

  1. Crie um objeto ResourceWriter com um nome de arquivo exclusivo. Faça isso especificando um nome de arquivo ou um fluxo de arquivos para um construtor da classe ResourceWriter.

  2. Chame uma das sobrecargas do método ResourceWriter.AddResource para cada recursos nomeado a ser adicionado ao arquivo. O recurso pode ser uma cadeia de caracteres, um objeto ou um conjunto de dados binários (uma matriz de bytes).

  3. Chame o método ResourceWriter.Close para gravar os recursos no arquivo e feche o objeto ResourceWriter.

Observação

Não use arquivos de recurso para armazenar senhas, informações confidenciais ou dados privados.

O exemplo a seguir cria um arquivo .resources chamado CarResources.resources que armazena seis cadeias de caracteres, um ícone e dois objetos definidos pelo aplicativo (dois objetos Automobile). A classe Automobile, que é definida e instanciada no exemplo, é marcada com o atributo SerializableAttribute, que permite a persistência por meio do formatador de serialização binária.

using System;
using System.Drawing;
using System.Resources;

[Serializable()] public class Automobile
{
   private string carMake;
   private string carModel;
   private int carYear;
   private int carDoors;
   private int carCylinders;

   public Automobile(string make, string model, int year) :
                     this(make, model, year, 0, 0)
   { }

   public Automobile(string make, string model, int year,
                     int doors, int cylinders)
   {
      this.carMake = make;
      this.carModel = model;
      this.carYear = year;
      this.carDoors = doors;
      this.carCylinders = cylinders;
   }

   public string Make {
      get { return this.carMake; }
   }

   public string Model {
      get { return this.carModel; }
   }

   public int Year {
      get { return this.carYear; }
   }

   public int Doors {
      get {
         return this.carDoors; }
   }

   public int Cylinders {
      get {
         return this.carCylinders; }
   }
}

public class Example
{
   public static void Main()
   {
      // Instantiate an Automobile object.
      Automobile car1 = new Automobile("Ford", "Model N", 1906, 0, 4);
      Automobile car2 = new Automobile("Ford", "Model T", 1909, 2, 4);
      // Define a resource file named CarResources.resx.
      using (ResourceWriter rw = new ResourceWriter(@".\CarResources.resources"))
      {
         rw.AddResource("Title", "Classic American Cars");
         rw.AddResource("HeaderString1", "Make");
         rw.AddResource("HeaderString2", "Model");
         rw.AddResource("HeaderString3", "Year");
         rw.AddResource("HeaderString4", "Doors");
         rw.AddResource("HeaderString5", "Cylinders");
         rw.AddResource("Information", SystemIcons.Information);
         rw.AddResource("EarlyAuto1", car1);
         rw.AddResource("EarlyAuto2", car2);
      }
   }
}
Imports System.Drawing
Imports System.Resources

<Serializable()> Public Class Automobile
    Private carMake As String
    Private carModel As String
    Private carYear As Integer
    Private carDoors AS Integer
    Private carCylinders As Integer

    Public Sub New(make As String, model As String, year As Integer)
        Me.New(make, model, year, 0, 0)
    End Sub

    Public Sub New(make As String, model As String, year As Integer,
                   doors As Integer, cylinders As Integer)
        Me.carMake = make
        Me.carModel = model
        Me.carYear = year
        Me.carDoors = doors
        Me.carCylinders = cylinders
    End Sub

    Public ReadOnly Property Make As String
        Get
            Return Me.carMake
        End Get
    End Property

    Public ReadOnly Property Model As String
        Get
            Return Me.carModel
        End Get
    End Property

    Public ReadOnly Property Year As Integer
        Get
            Return Me.carYear
        End Get
    End Property

    Public ReadOnly Property Doors As Integer
        Get
            Return Me.carDoors
        End Get
    End Property

    Public ReadOnly Property Cylinders As Integer
        Get
            Return Me.carCylinders
        End Get
    End Property
End Class

Module Example
    Public Sub Main()
        ' Instantiate an Automobile object.
        Dim car1 As New Automobile("Ford", "Model N", 1906, 0, 4)
        Dim car2 As New Automobile("Ford", "Model T", 1909, 2, 4)
        ' Define a resource file named CarResources.resx.
        Using rw As New ResourceWriter(".\CarResources.resources")
            rw.AddResource("Title", "Classic American Cars")
            rw.AddResource("HeaderString1", "Make")
            rw.AddResource("HeaderString2", "Model")
            rw.AddResource("HeaderString3", "Year")
            rw.AddResource("HeaderString4", "Doors")
            rw.AddResource("HeaderString5", "Cylinders")
            rw.AddResource("Information", SystemIcons.Information)
            rw.AddResource("EarlyAuto1", car1)
            rw.AddResource("EarlyAuto2", car2)
        End Using
    End Sub
End Module

Depois de criar o arquivo .resources, você pode inseri-lo em um executável ou biblioteca de tempo de execução ao incluir o alternador do compilador de linguagem /resource ou incorporá-lo em um assembly satélite usando o Assembly Linker (Al.exe).

Arquivos de recurso no Visual Studio

Quando você adiciona um arquivo de recurso ao seu projeto do Visual Studio, o Visual Studio cria um arquivo .resx no diretório do projeto. O Visual Studio fornece editores de recursos que permitem adicionar cadeias de caracteres, imagens e objetos binários. Porque os editores são projetados para lidar apenas com dados estáticos, não podem ser usados para armazenar objetos de programação. Você deve gravar os dados de objeto para um arquivo .resx ou para um arquivo .resources por meio de programação. Para obter mais informações, consulte Trabalhar com arquivos .resx programaticamente e a seção Recursos em arquivos .resources.

Se você estiver adicionando recursos localizados, conceda a eles o mesmo nome de arquivo raiz que o arquivo de recurso principal. Você também deve designar a cultura no nome do arquivo. Por exemplo, se adicionar um arquivo de recurso nomeado Resources.resx, você também poderá criar arquivos de recurso nomeados Resources.en-US.resx e Resources.fr-FR.resx para manter os recursos localizados nas culturas inglesa (Estados Unidos) e francesa (França), respectivamente. Também deve designar a cultura padrão do seu aplicativo. Essa é a cultura em que os recursos são usados se não existirem recursos localizados encontrados para uma determinada cultura.

Para especificar a cultura padrão, no Gerenciador de Soluções no Visual Studio:

  • Abra as propriedades do projeto, clique com o botão direito do mouse no projeto e selecione Propriedades (ou Alt + Enter quando o projeto for selecionado).
  • Selecione a guia Pacote.
  • Na área Geral, selecione a cultura/idioma apropriado no controle de Idioma neutro do assembly.
  • Salve suas alterações.

No momento da compilação, o Visual Studio converte primeiro os arquivos .resx em um projeto para os arquivos de recurso binários (.resources) e armazena-os num subdiretório do diretório obj do projeto. O Visual Studio incorpora quaisquer arquivos de recurso que não contenham recursos localizados no assembly principal que é gerado pelo projeto. Se os arquivos de recurso contém os recursos localizados, o Visual Studio insere-os em assemblies satélites separados para cada cultura localizada. Em seguida, ele armazena cada assembly satélite em um diretório cujo nome corresponde à cultura localizada. Por exemplo, os recursos localizados do Inglês (Estados Unidos) são armazenados em um assembly satélite no subdiretório en-US.

Confira também