Utilisation des fichiers .resx par programmationWorking with .resx files programmatically

Étant donné que les fichiers de ressources XML (.resx) doivent être constitués de code XML bien défini, notamment un en-tête qui doit respecter un schéma spécifique, suivi de données dans des paires nom/valeur, la création manuelle de ces fichiers est sujette aux erreurs.Because XML resource (.resx) files must consist of well-defined XML, including a header that must follow a specific schema followed by data in name/value pairs, you may find that creating these files manually is error-prone. Alternativement, vous pouvez créer des fichiers .resx par programmation à l’aide de types et de membres de la bibliothèque de classes .NET.As an alternative, you can create .resx files programmatically by using types and members in the .NET Class Library. Vous pouvez également utiliser la bibliothèque de classes .NET pour récupérer des ressources stockées dans les fichiers .resx.You can also use the .NET Class Library to retrieve resources that are stored in .resx files. Cette rubrique explique comment utiliser les types et les membres de l’espace de noms System.Resources avec des fichiers .resx.This topic explains how you can use the types and members in the System.Resources namespace to work with .resx files.

Notez que cet article traite de l’utilisation de fichiers XML (.resx) contenant des ressources.Note that this article discusses working with XML (.resx) files that contain resources. Pour plus d’informations sur l’utilisation de fichiers de ressources binaires incorporés dans des assemblys, consultez la rubrique ResourceManager .For information on working with binary resource files that have been embedded in assemblies, see the ResourceManager topic.

Avertissement

Vous pouvez également utiliser les fichiers .resx autrement que par programmation.There are also ways to work with .resx files other than programmatically. Quand vous ajoutez un fichier de ressources à un projet Visual Studio, ce dernier fournit une interface pour la création et la gestion d’un fichier .resx, et convertit automatiquement le fichier .resx en fichier .resources au moment de la compilation.When you add a resource file to a Visual Studio project, Visual Studio provides an interface for creating and maintaining a .resx file, and automatically converts the .resx file to a .resources file at compile time. Vous pouvez également utiliser un éditeur de texte pour manipuler directement un fichier .resx.You can also use a text editor to manipulate a .resx file directly. Toutefois, pour éviter d’endommager le fichier, veillez à ne pas modifier les informations binaires stockées dans le fichier.However, to avoid corrupting the file, be careful not to modify any binary information that is stored in the file.

Créer un fichier .resxCreate a .resx file

Vous pouvez utiliser la classe System.Resources.ResXResourceWriter pour créer un fichier .resx par programmation, en procédant comme suit :You can use the System.Resources.ResXResourceWriter class to create a .resx file programmatically, by following these steps:

  1. Instanciez un objet ResXResourceWriter en appelant la méthode ResXResourceWriter.ResXResourceWriter(String) et en fournissant le nom du fichier .resx.Instantiate a ResXResourceWriter object by calling the ResXResourceWriter.ResXResourceWriter(String) method and supplying the name of the .resx file. Le nom de fichier doit inclure l’extension .resx.The file name must include the .resx extension. Si vous instanciez l’objet ResXResourceWriter dans un bloc using , vous n’avez pas besoin d’appeler explicitement la méthode ResXResourceWriter.Close à l’étape 3.If you instantiate the ResXResourceWriter object in a using block, you do not explicitly have to call the ResXResourceWriter.Close method in step 3.

  2. Appelez la méthode ResXResourceWriter.AddResource pour chaque ressource que vous voulez ajouter au fichier.Call the ResXResourceWriter.AddResource method for each resource you want to add to the file. Utilisez les surcharges de cette méthode pour ajouter la chaîne, l’objet et les données binaires (tableau d’octets).Use the overloads of this method to add string, object, and binary (byte array) data. Si la ressource est un objet, celui-ci doit être sérialisable.If the resource is an object, it must be serializable.

  3. Appelez la méthode ResXResourceWriter.Close pour générer le fichier de ressources et libérer toutes les ressources.Call the ResXResourceWriter.Close method to generate the resource file and to release all resources. Si l’objet ResXResourceWriter a été créé dans un bloc using , les ressources sont écrites dans le fichier .resx et celles qui sont utilisées par l’objet ResXResourceWriter sont libérées à la fin du bloc using .If the ResXResourceWriter object was created within a using block, resources are written to the .resx file and the resources used by the ResXResourceWriter object are released at the end of the using block.

Le fichier .resx résultant possède l’en-tête approprié et une balise data pour chaque ressource ajoutée par la méthode ResXResourceWriter.AddResource .The resulting .resx file has the appropriate header and a data tag for each resource added by the ResXResourceWriter.AddResource method.

Avertissement

N’utilisez pas de fichier de ressources pour stocker des mots de passe, des informations sensibles ou des données privées.Do not use resource files to store passwords, security-sensitive information, or private data.

L’exemple suivant crée un fichier .resx nommé CarResources.resx qui stocke six chaînes, une icône et deux objets définis par l’application (deux objets Automobile ).The following example creates a .resx file named CarResources.resx that stores six strings, an icon, and two application-defined objects (two Automobile objects). Notez que la classe Automobile, qui est définie et instanciée dans l’exemple, est marquée avec l’attribut SerializableAttribute.Note that the Automobile class, which is defined and instantiated in the example, is tagged with the SerializableAttribute attribute.

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 (ResXResourceWriter resx = new ResXResourceWriter(@".\CarResources.resx"))
      {
         resx.AddResource("Title", "Classic American Cars");
         resx.AddResource("HeaderString1", "Make");
         resx.AddResource("HeaderString2", "Model");
         resx.AddResource("HeaderString3", "Year");
         resx.AddResource("HeaderString4", "Doors");
         resx.AddResource("HeaderString5", "Cylinders");
         resx.AddResource("Information", SystemIcons.Information); 
         resx.AddResource("EarlyAuto1", car1);  
         resx.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 resx As New ResXResourceWriter(".\CarResources.resx")
         resx.AddResource("Title", "Classic American Cars")
         resx.AddResource("HeaderString1", "Make")
         resx.AddResource("HeaderString2", "Model")
         resx.AddResource("HeaderString3", "Year")
         resx.AddResource("HeaderString4", "Doors")
         resx.AddResource("HeaderString5", "Cylinders")
         resx.AddResource("Information", SystemIcons.Information) 
         resx.AddResource("EarlyAuto1", car1)
         resx.AddResource("EarlyAuto2", car2)  
      End Using
   End Sub
End Module

Conseil

Vous pouvez également utiliser Visual Studio pour créer des fichiers .resx.You can also use Visual Studio to create .resx files. Au moment de la compilation, Visual Studio utilise l’outil Resource File Generator (Resgen.exe) pour convertir le fichier .resx en fichier de ressources binaires (.resources), et l’incorpore dans un assembly d’application ou un assembly satellite.At compile time, Visual Studio uses the Resource File Generator (Resgen.exe) to convert the .resx file to a binary resource (.resources) file, and also embeds it in either an application assembly or a satellite assembly.

Vous ne pouvez pas incorporer un fichier .resx dans un exécutable du Common Language Runtime ou le compiler dans un assembly satellite.You cannot embed a .resx file in a runtime executable or compile it into a satellite assembly. Vous devez convertir votre fichier .resx en fichier de ressources binaires (.resources) à l’aide de l’outil Resource File Generator (Resgen.exe).You must convert your .resx file into a binary resource (.resources) file by using the Resource File Generator (Resgen.exe). Le fichier .resources résultant peut ensuite être incorporé dans un assembly d’application ou un assembly satellite.The resulting .resources file can then be embedded in an application assembly or a satellite assembly. Pour plus d'informations, consultez Creating Resource Files.For more information, see Creating Resource Files.

Énumérer les ressourcesEnumerate resources

Dans certains cas, vous voulez récupérer toutes les ressources d’un fichier .resx, et pas seulement une ressource spécifique.In some cases, you may want to retrieve all resources, instead of a specific resource, from a .resx file. Pour ce faire, vous pouvez utiliser la classe System.Resources.ResXResourceReader , qui fournit un énumérateur pour toutes les ressources du fichier .resx.To do this, you can use the System.Resources.ResXResourceReader class, which provides an enumerator for all resources in the .resx file. La classe System.Resources.ResXResourceReader implémente IDictionaryEnumerator, qui retourne un objet DictionaryEntry représentant une ressource particulière pour chaque itération de la boucle.The System.Resources.ResXResourceReader class implements IDictionaryEnumerator, which returns a DictionaryEntry object that represents a particular resource for each iteration of the loop. Sa propriété DictionaryEntry.Key retourne la clé de la ressource et sa propriété DictionaryEntry.Value retourne la valeur de la ressource.Its DictionaryEntry.Key property returns the resource's key, and its DictionaryEntry.Value property returns the resource's value.

L’exemple suivant crée un objet ResXResourceReader pour le fichier CarResources.resx créé dans l’exemple précédent et itère au sein du fichier de ressources.The following example creates a ResXResourceReader object for the CarResources.resx file created in the previous example and iterates through the resource file. Il ajoute les deux objets Automobile définis dans le fichier de ressources à un objet System.Collections.Generic.List<T> , et ajoute cinq des six chaînes à un objet SortedList .It adds the two Automobile objects that are defined in the resource file to a System.Collections.Generic.List<T> object, and it adds five of the six strings to a SortedList object. Les valeurs de l’objet SortedList sont converties en tableau de paramètres, utilisé pour afficher des en-têtes de colonne dans la console.The values in the SortedList object are converted to a parameter array, which is used to display column headings to the console. Les valeurs de propriété Automobile sont également affichées dans la console.The Automobile property values are also displayed to the console.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Resources;

public class Example
{
   public static void Main()
   {
      string resxFile = @".\CarResources.resx";
      List<Automobile> autos = new List<Automobile>();
      SortedList headers = new SortedList();
      
      using (ResXResourceReader resxReader = new ResXResourceReader(resxFile))
      {
         foreach (DictionaryEntry entry in resxReader) {
            if (((string) entry.Key).StartsWith("EarlyAuto"))
               autos.Add((Automobile) entry.Value); 
            else if (((string) entry.Key).StartsWith("Header")) 
               headers.Add((string) entry.Key, (string) entry.Value);      
         } 
      }
      string[] headerColumns = new string[headers.Count];
      headers.GetValueList().CopyTo(headerColumns, 0);
      Console.WriteLine("{0,-8} {1,-10} {2,-4}   {3,-5}   {4,-9}\n", 
                        headerColumns);
      foreach (var auto in autos)                        
         Console.WriteLine("{0,-8} {1,-10} {2,4}   {3,5}   {4,9}", 
                           auto.Make, auto.Model, auto.Year, 
                           auto.Doors, auto.Cylinders);
   }
}
// The example displays the following output:
//       Make     Model      Year   Doors   Cylinders
//       
//       Ford     Model N    1906       0           4
//       Ford     Model T    1909       2           4
Imports System.Collections
Imports System.Collections.Generic
Imports System.Resources

Module Example
   Public Sub Main()
      Dim resxFile As String = ".\CarResources.resx"
      Dim autos As New List(Of Automobile)
      Dim headers As New SortedList()
      
      Using resxReader As New ResXResourceReader(resxFile)
         For Each entry As DictionaryEntry In resxReader
            If CType(entry.Key, String).StartsWith("EarlyAuto") Then
               autos.Add(CType(entry.Value, Automobile)) 
            Else If CType(entry.Key, String).StartsWith("Header") Then
               headers.Add(CType(entry.Key, String), CType(entry.Value, String))      
            End If 
         Next 
      End Using
      Dim headerColumns(headers.Count - 1) As String 
      headers.GetValueList().CopyTo(headerColumns, 0)
      Console.WriteLine("{0,-8} {1,-10} {2,-4}   {3,-5}   {4,-9}", 
                        headerColumns)
      Console.WriteLine()
      For Each auto In autos                        
         Console.WriteLine("{0,-8} {1,-10} {2,4}   {3,5}   {4,9}", 
                           auto.Make, auto.Model, auto.Year, 
                           auto.Doors, auto.Cylinders)
      Next
   End Sub
End Module
' The example displays the following output:
'       Make     Model      Year   Doors   Cylinders
'       
'       Ford     Model N    1906       0           4
'       Ford     Model T    1909       2           4

Récupérer une ressource spécifiqueRetrieve a specific resource

Outre l’énumération des éléments d’un fichier .resx, vous pouvez récupérer une ressource spécifique par son nom à l’aide de la classe System.Resources.ResXResourceSet .In addition to enumerating the items in a .resx file, you can retrieve a specific resource by name by using the System.Resources.ResXResourceSet class. La méthode ResourceSet.GetString(String) extrait la valeur d’une ressource de chaîne nommée.The ResourceSet.GetString(String) method retrieves the value of a named string resource. La méthode ResourceSet.GetObject(String) extrait la valeur d’un objet nommé ou des données binaires.The ResourceSet.GetObject(String) method retrieves the value of a named object or binary data. La méthode retourne un objet qui doit être casté (en C#) ou converti (en Visual Basic) en objet de type approprié.The method returns an object that must then be cast (in C#) or converted (in Visual Basic) to an object of the appropriate type.

L’exemple suivant récupère la chaîne et l’icône de la légende d’un formulaire par leur nom de ressources.The following example retrieves a form's caption string and icon by their resource names. Elle récupère également les objets Automobile définis par l’application utilisés dans l’exemple précédent et les affiche dans un contrôle DataGridView.It also retrieves the application-defined Automobile objects used in the previous example and displays them in a DataGridView control.

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Resources;
using System.Windows.Forms;

public class CarDisplayApp : Form
{
   private const string resxFile = @".\CarResources.resx";
   Automobile[] cars;

   public static void Main()
   {
      CarDisplayApp app = new CarDisplayApp();
      Application.Run(app);
   }

   public CarDisplayApp()
   {
      // Instantiate controls.
      PictureBox pictureBox = new PictureBox();
      pictureBox.Location = new Point(10, 10);
      this.Controls.Add(pictureBox);
      DataGridView grid = new DataGridView();
      grid.Location = new Point(10, 60);
      this.Controls.Add(grid);
      
      // Get resources from .resx file.
      using (ResXResourceSet resxSet = new ResXResourceSet(resxFile))
      {
         // Retrieve the string resource for the title.
         this.Text = resxSet.GetString("Title");
         // Retrieve the image.
         Icon image = (Icon) resxSet.GetObject("Information", true);
         if (image != null)
            pictureBox.Image = image.ToBitmap();

         // Retrieve Automobile objects.  
         List<Automobile> carList = new List<Automobile>();
         string resName = "EarlyAuto";
         Automobile auto; 
         int ctr = 1;
         do {
            auto = (Automobile) resxSet.GetObject(resName + ctr.ToString());
            ctr++;
            if (auto != null) 
               carList.Add(auto);
         } while (auto != null);
         cars = carList.ToArray();
         grid.DataSource = cars;
      }
   }
}
Imports System.Collections.Generic
Imports System.Drawing
Imports System.Resources
Imports System.Windows.Forms

Public Class CarDisplayApp : Inherits Form 
   Private Const resxFile As String = ".\CarResources.resx"
   Dim cars() As Automobile
   
   Public Shared Sub Main()
      Dim app As New CarDisplayApp()
      Application.Run(app)
   End Sub
   
   Public Sub New()
      ' Instantiate controls.
      Dim pictureBox As New PictureBox()
      pictureBox.Location = New Point(10, 10)
      Me.Controls.Add(pictureBox)
      Dim grid As New DataGridView()
      grid.Location = New Point(10, 60)
      Me.Controls.Add(grid)
      
      ' Get resources from .resx file.
      Using resxSet As New ResXResourceSet(resxFile)
         ' Retrieve the string resource for the title.
         Me.Text = resxSet.GetString("Title")
         ' Retrieve the image.
         Dim image As Icon = CType(resxSet.GetObject("Information", True), Icon)
         If image IsNot Nothing Then
            pictureBox.Image = image.ToBitmap()
         End If

         ' Retrieve Automobile objects.  
         Dim carList As New List(Of Automobile)
         Dim resName As String = "EarlyAuto"
         Dim auto As Automobile 
         Dim ctr As Integer = 1
         Do
            auto = CType(resxSet.GetObject(resName + ctr.ToString()), Automobile)
            ctr += 1
            If auto IsNot Nothing Then carList.Add(auto)
         Loop While auto IsNot Nothing
         cars = carList.ToArray()
         grid.DataSource = cars
      End Using
   End Sub
End Class

Convertir les fichiers .resx en fichiers binaires .resourcesConvert .resx files to binary .resources files

La conversion de fichiers .resx en fichiers de ressources binaires incorporés (.resources) présente des avantages importants.Converting .resx files to embedded binary resource (.resources) files has significant advantages. Bien que les fichiers .resx soient faciles à lire et à gérer pendant le développement d’applications, ils sont rarement inclus avec les applications finies.Although .resx files are easy to read and maintain during application development, they are rarely included with finished applications. S’ils sont distribués avec une application, ils existent en tant que fichiers séparés de l’exécutable de l’application et des bibliothèques qui l’accompagnent.If they are distributed with an application, they exist as separate files apart from the application executable and its accompanying libraries. En revanche, les fichiers .resources sont incorporés dans l’exécutable d’application ou dans les assemblys qui l’accompagnent.In contrast, .resources files are embedded in the application executable or its accompanying assemblies. Par ailleurs, pour les applications localisées, l’utilisation de fichiers .resx au moment de l’exécution donne au développeur la responsabilité de la gestion des ressources de secours.In addition, for localized applications, relying on .resx files at run time places the responsibility for handling resource fallback on the developer. En revanche, si un ensemble d’assemblys satellites contenant des fichiers .resources incorporés a été créé, le Common Language Runtime gère le processus de secours pour les ressources.In contrast, if a set of satellite assemblies that contain embedded .resources files has been created, the common language runtime handles the resource fallback process.

Pour convertir un fichier .resx en fichier .resources, vous utilisez l’outil Resource File Generator (Resgen.exe), qui présente la syntaxe de base suivante :To convert a .resx file to a .resources file, you use the Resource File Generator (Resgen.exe), which has the following basic syntax:

Resgen.exe .resxFilenameResgen.exe .resxFilename

Le résultat est un fichier de ressources binaires ayant le même nom de fichier racine que celui du fichier .resx et une extension de fichier .resources.The result is a binary resource file that has the same root file name as the .resx file and a .resources file extension. Ce fichier peut ensuite être compilé en exécutable ou bibliothèque au moment de la compilation.This file can then be compiled into an executable or a library at compile time. Si vous utilisez le compilateur Visual Basic, utilisez la syntaxe suivante pour incorporer un fichier .resources dans l’exécutable d’une application :If you are using the Visual Basic compiler, use the following syntax to embed a .resources file in an application's executable:

vbc filename .vb -resource: .resourcesFilenamevbc filename .vb -resource: .resourcesFilename

Si vous utilisez C#, la syntaxe est la suivante :If you are using C#, the syntax is as follows:

csc filename .cs -resource: .resourcesFilenamecsc filename .cs -resource: .resourcesFilename

Le fichier .resources peut également être incorporé dans un assembly satellite à l’aide de l’utilitaire Assembly Linker (AL.exe), qui présente la syntaxe de base suivante :The .resources file can also be embedded in a satellite assembly by using Assembly Linker (AL.exe), which has the following basic syntax:

al resourcesFilename -out: assemblyFilenameal resourcesFilename -out: assemblyFilename

Voir aussiSee also