Créer des fichiers de ressources pour les applications .NET

Vous pouvez inclure des ressources, telles que des chaînes, des images ou des données d’objet, dans les fichiers de ressources pour les rendre facilement accessibles à votre application. Le .NET Framework propose cinq façons de créer des fichiers de ressources :

  • Créez un fichier texte qui contient des ressources de type chaîne. Vous pouvez utiliser le Générateur de fichiers de ressources (resgen.exe) pour convertir le fichier texte en un fichier de ressources binaire (.resources). Vous pouvez ensuite incorporer le fichier de ressources binaire dans un exécutable d’application ou une bibliothèque d’applications en utilisant un compilateur de langage, ou l’incorporer dans un assembly satellite avec Assembly Linker (Al.exe). Pour plus d’informations, consultez la section Ressources dans les fichiers texte.

  • Créez un fichier de ressources XML (.resx) qui contient des données de chaîne, d’image ou d’objet. Vous pouvez utiliser le Générateur de fichiers de ressources (resgen.exe) pour convertir le fichier .resx en un fichier de ressources binaire (.resources). Vous pouvez ensuite incorporer le fichier de ressources binaire dans un exécutable d’application ou une bibliothèque d’applications en utilisant un compilateur de langage, ou l’incorporer dans un assembly satellite avec Assembly Linker (Al.exe). Pour plus d’informations, consultez la section Ressources dans les fichiers .resx.

  • Créez un fichier de ressources XML (.resx) par programmation en utilisant des types dans l’espace de noms System.Resources. Vous pouvez créer un fichier .resx, énumérer ses ressources et récupérer des ressources spécifiques par nom. Pour plus d’informations, consultez Utilisation des fichiers .resx par programmation.

  • Créez un fichier de ressources binaire (.resources) par programmation. Vous pouvez ensuite incorporer le fichier dans un exécutable d’application ou une bibliothèque d’applications en utilisant un compilateur de langage, ou l’incorporer dans un assembly satellite avec Assembly Linker (Al.exe). Pour plus d’informations, consultez la section Ressources dans les fichiers .resources.

  • Utilisez Visual Studio pour créer un fichier de ressources et l’inclure dans votre projet. Visual Studio fournit un éditeur de ressources qui vous permet d’ajouter, de supprimer et de modifier des ressources. Au moment de la compilation, le fichier de ressources est automatiquement converti en un fichier .resources binaire et incorporé dans un assembly d’application ou un assembly satellite. Pour plus d’informations, consultez la section Fichiers de ressources dans Visual Studio.

Ressources dans les fichiers texte

Vous pouvez utiliser des fichiers texte (.txt ou .restext) pour stocker uniquement les ressources de chaîne. Pour les ressources autres que les ressources de chaîne, utilisez des fichiers .resx ou créez-les programmatiquement. Les fichiers texte qui contiennent des ressources de type chaîne ont le format suivant :

# 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

Le format de fichier de ressources des fichiers .txt et .restext est identique. L’extension de fichier .restext sert uniquement à rendre des fichiers texte immédiatement identifiables comme fichiers de ressources textuelles.

Les ressources de type chaîne s’affichent sous forme de paires nom/valeur, où nom est une chaîne qui identifie la ressource, et valeur est la chaîne de ressource retournée quand vous passez nom à une méthode de récupération de la ressource telle que ResourceManager.GetString. nom et valeur doivent être séparés par un signe égal (=). Par exemple :

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

Attention

N’utilisez pas de fichier de ressources pour stocker des mots de passe, des informations sensibles ou des données privées.

Les chaînes vides (autrement dit, une ressource dont la valeur est String.Empty) sont autorisées dans les fichiers texte. Par exemple :

EmptyString=

Depuis .NET Framework 4.5 et dans toutes les versions de .NET Core, les fichiers texte prennent en charge la compilation conditionnelle avec les constructions #ifdefsymbole... #endif et #if !symbole... #endif. Vous pouvez ensuite utiliser le commutateur /define avec le Générateur de fichiers de ressources (resgen.exe) pour définir les symboles. Chaque ressource requiert sa propre construction #ifdefsymbole... #endif ou #if !symbole... #endif. Si vous utilisez une instruction #ifdef et que symbole est défini, la ressource associée est incluse dans le fichier .resources ; sinon, elle n’est pas incluse. Si vous utilisez une instruction #if ! et que symbole n’est pas défini, la ressource associée est incluse dans le fichier .resources ; sinon, elle n’est pas incluse.

Les commentaires sont facultatifs dans les fichiers texte et sont précédés d’un point-virgule (;) ou d’un signe dièse (#) au début d’une ligne. Les lignes qui contiennent des commentaires peuvent être placées n’importe où dans le fichier. Les commentaires ne sont pas inclus dans un fichier .resources compilé créé avec le Générateur de fichiers de ressources (resgen.exe).

Les lignes vides dans les fichiers texte sont considérées comme des espaces blancs et sont ignorées.

L’exemple suivant définit deux ressources de type chaîne nommées OKButton et CancelButton.

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

Si le fichier texte contient des occurrences en double de nom, le Générateur de fichiers de ressources (resgen.exe) affiche un avertissement et ignore le deuxième nom.

La valeur ne peut pas contenir de nouveaux caractères de ligne, mais vous pouvez utiliser des caractères d’échappement de style C, comme exemple \n pour représenter une nouvelle ligne et \t pour représenter un onglet. Vous pouvez également inclure un caractère de barre oblique inverse s’il est dans une séquence d’échappement (par exemple, « \\ »). En outre, une chaîne vide est autorisée.

Enregistrez des ressources au format de fichier texte en utilisant l'encodage UTF-8 ou UTF-16 dans un ordre d'octet little-endian ou big-endian. Toutefois, le Générateur de fichiers de ressources (resgen.exe), qui convertit un fichier .txt en fichier .resources, traite les fichiers au format UTF-8 par défaut. Si vous souhaitez que Resgen.exe reconnaisse un fichier encodé à l’aide d’UTF-16, vous devez inclure une marque d’ordre d’octet Unicode (U+FEFF) au début du fichier.

Pour incorporer un fichier de ressources au format de fichier texte dans un assembly .NET, vous devez convertir le fichier en un fichier de ressources binaire (.resources) à l’aide duGénérateur de fichiers de ressources (resgen.exe). Vous pouvez ensuite incorporer le fichier .resources dans un assembly .NET en utilisant un compilateur de langage, ou l’incorporer dans un assembly satellite avec Assembly Linker (Al.exe).

L’exemple suivant utilise un fichier de ressources au format texte nommé GreetingResources.txt pour une application console « Hello World » simple. Le fichier texte définit deux chaînes, prompt et greeting, qui invitent l’utilisateur à entrer son nom et affichent un message d’accueil.

# 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}!

Le fichier texte est converti en un fichier .resources à l’aide de la commande suivante :

resgen GreetingResources.txt

L’exemple suivant affiche le code source pour une application console qui utilise le fichier .resources pour afficher des messages à l’intention de l’utilisateur.

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!

Si vous utilisez Visual Basic et que le fichier de code source est nommé Greeting.vb, la commande suivante crée un fichier exécutable qui inclut le fichier .resources incorporé :

vbc greeting.vb -resource:GreetingResources.resources

Si vous utilisez C# et que le fichier de code source est nommé Greeting.cs, la commande suivante crée un fichier exécutable qui inclut le fichier .resources incorporé :

csc greeting.cs -resource:GreetingResources.resources

Ressources dans les fichiers .resx

Contrairement aux fichiers texte, qui peuvent stocker des ressources de type chaîne uniquement, les fichiers de ressources XML (.resx) peuvent stocker des chaînes, des données binaires telles que les images, les icônes et les clips audio, et des objets de programmation. Un fichier .resx contient un en-tête standard, qui décrit le format des entrées de ressources et spécifie les informations de contrôle de version pour le XML utilisé pour analyser les données. Les données de fichier de ressources suivent l’en-tête XML. Chaque élément de données se compose d’une paire nom/valeur contenue dans une balise data. Son attribut name définit le nom de ressource et la balise value imbriquée contient la valeur de ressource. Pour les données de type chaîne, la balise value contient la chaîne.

Par exemple, la balise data suivante définit une ressource de type chaîne nommée prompt dont la valeur est « Entrez votre nom : ».

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

Avertissement

N’utilisez pas de fichier de ressources pour stocker des mots de passe, des informations sensibles ou des données privées.

Pour les objets de ressource, la balise data inclut un attribut type qui indique le type de données de la ressource. Pour les objets qui se composent de données binaires, la balise data inclut également un attribut mimetype qui indique le type base64 des données binaires.

Notes

Tous les fichiers .resx utilisent un formateur de sérialisation binaire pour générer et analyser les données binaires d’un type spécifié. Par conséquent, un fichier .resx peut devenir non valide si le format de sérialisation binaire d’un objet change de manière incompatible.

L’exemple suivant affiche une partie d’un fichier .resx qui inclut une ressource Int32 et une image 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>

Important

Comme les fichiers .resx doivent se composer de code XML bien formé dans un format prédéfini, nous déconseillons d’utiliser des fichiers .resx manuellement, en particulier quand les fichiers .resx contiennent des ressources autres que des chaînes. Au lieu de cela, Visual Studio fournit une interface transparente pour créer et manipuler les fichiers .resx. Pour plus d’informations, consultez la section Fichiers de ressources dans Visual Studio. Vous pouvez également créer et manipuler des fichiers .resx par programmation. Pour plus d’informations, consultez Utilisation des fichiers .resx par programmation.

Ressources dans les fichiers .resources

Vous pouvez utiliser la classe System.Resources.ResourceWriter pour créer par programmation un fichier de ressources binaire (.resources) directement à partir du code. Vous pouvez également utiliser le Générateur de fichiers de ressources (resgen.exe) pour créer un fichier .resources à partir d’un fichier texte ou d’un fichier .resx. Le fichier .resources peut contenir des données binaires (tableaux d’octets) et des données d’objet en plus des données de type chaîne. La création d’un fichier .resources par programmation nécessite les étapes suivantes :

  1. Créez un objet ResourceWriter avec un nom de fichier unique. Vous pouvez le faire en spécifiant un nom de fichier ou un flux de fichiers pour un constructeur de classe ResourceWriter.

  2. Appelez une des surcharges de la méthode ResourceWriter.AddResource pour chaque ressource nommée à ajouter au fichier. La ressource peut être une chaîne, un objet ou une collection de données binaires (tableau d’octets).

  3. Appelez la méthode ResourceWriter.Close pour écrire les ressources dans le fichier et fermer l’objet ResourceWriter.

Notes

N’utilisez pas de fichier de ressources pour stocker des mots de passe, des informations sensibles ou des données privées.

L’exemple suivant crée par programmation un fichier .resources nommé CarResources.resources qui stocke six chaînes, une icône et deux objets définis par l’application (deux objets Automobile). La classe Automobile, définie et instanciée dans l’exemple, est marquée avec l’attribut SerializableAttribute, qui lui permet d’être rendue persistante par le formateur de sérialisation binaire.

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

Une fois que vous avez créé le fichier .resources, vous pouvez l’incorporer dans un fichier exécutable à l’exécution ou une bibliothèque en incluant le commutateur /resource du compilateur de langage, ou l’incorporer dans un assembly satellite avec Assembly Linker (Al.exe).

Fichiers de ressources dans Visual Studio

Quand vous ajoutez un fichier de ressources à votre projet Visual Studio, Visual Studio crée un fichier .resx dans le répertoire de projet. Visual Studio fournit des éditeurs de ressources qui vous permettent d’ajouter des chaînes, des images et des objets binaires. Comme les éditeurs sont conçus pour gérer des données statiques uniquement, ils ne peuvent pas être utilisés pour stocker des objets de programmation. Vous devez écrire par programmation les données d’objet dans un fichier .resx ou .resources. Consultez Utilisation des fichiers .resx par programmation et la section Ressources dans les fichiers .resources pour plus d’informations.

Si vous ajoutez des ressources localisées, donnez-leur le même nom de fichier racine que le fichier de ressources principal. Vous devez également désigner leur culture dans le nom de fichier. Par exemple, si vous ajoutez un fichier de ressources nommé Resources.resx, vous pouvez également créer les fichiers de ressources nommés Resources.en-US.resx et Resources.fr-FR.resx pour y stocker des ressources localisées pour les cultures Anglais (États-Unis) et Français (France), respectivement. Vous devez également désigner la culture par défaut de votre application. Il s’agit de la culture dont les ressources sont utilisées si aucune ressource localisée pour une culture particulière ne peut être trouvée.

Spécifier la culture par défaut, dans Explorateur de solutions dans Visual Studio :

  • Ouvrez les propriétés du projet, cliquez avec le bouton droit sur le projet et sélectionnez Propriétés (ou Alt + Entrée une fois que le projet est sélectionné).
  • Sélectionnez l’onglet Package.
  • Dans la zone Général , sélectionnez le langage/la culture approprié(e) dans le contrôle de langage neutre de l’assembly.
  • Enregistrez vos modifications.

Au moment de la compilation, Visual Studio convertit en premier les fichiers .resx dans un projet en fichiers de ressources binaires (.resources) et les stocke dans un sous-répertoire du répertoire obj du projet. Visual Studio incorpore tous les fichiers de ressources qui ne contiennent pas de ressources localisées dans l’assembly principal qui est généré par le projet. Si des fichiers de ressources contiennent des ressources localisées, Visual Studio les incorpore dans des assemblys satellites séparés pour chaque culture localisée. Il stocke ensuite chaque assembly satellite dans un répertoire dont le nom correspond à la culture localisée. Par exemple, les ressources Anglais (États-Unis) localisées sont stockées dans un assembly satellite dans le sous-répertoire en-US.

Voir aussi