为 .NET 应用创建资源文件Create resource files for .NET apps

可以将字符串、图像或对象数据等资源包含在资源文件中,方便应用程序使用。You can include resources, such as strings, images, or object data, in resources files to make them easily available to your application. .NET Framework 提供了五种创建资源文件的方法:The .NET Framework offers five ways to create resources files:

  • 创建一个包含字符串资源的文本文件。Create a text file that contains string resources. 可以使用资源文件生成器 (Resgen.exe) 将文本文件转换成二进制资源 (.resources) 文件。You can use Resource File Generator (Resgen.exe) to convert the text file into a binary resource (.resources) file. 然后使用语言编译器将这个二进制资源文件嵌入可执行应用程序或应用程序库,或者使用程序集链接器 (Al.exe) 将这个二进制资源文件嵌入附属程序集。You can then embed the binary resource file in an application executable or an application library by using a language compiler, or you can embed it in a satellite assembly by using Assembly Linker (Al.exe). 有关详细信息,请参阅文本文件中的资源部分。For more information, see the Resources in Text Files section.

  • 创建一个包含字符串、图像或对象数据的 XML 资源 (.resx) 文件。Create an XML resource (.resx) file that contains string, image, or object data. 可以使用资源文件生成器 (Resgen.exe) 将 .resx 文件转换成二进制资源 (.resources) 文件。You can use Resource File Generator (Resgen.exe) to convert the .resx file into a binary resource (.resources) file. 然后使用语言编译器将这个二进制资源文件嵌入可执行应用程序或应用程序库,或者使用程序集链接器 (Al.exe) 将这个二进制资源文件嵌入附属程序集。You can then embed the binary resource file in an application executable or an application library by using a language compiler, or you can embed it in a satellite assembly by using Assembly Linker (Al.exe). 有关详细信息,请参阅 .resx 文件中的资源部分。For more information, see the Resources in .resx Files section.

  • 使用 System.Resources 命名空间中的类型以编程方式创建一个 XML 资源 (.resx) 文件。Create an XML resource (.resx) file programmatically by using types in the System.Resources namespace. 可以创建一个 .resx 文件、枚举其资源并按名称检索特定资源。You can create a .resx file, enumerate its resources, and retrieve specific resources by name. 有关详细信息,请参阅主题以编程方式使用 .resx 文件For more information, see the topic Working with .resx Files Programmatically.

  • 以编程方式创建一个二进制资源 (.resources) 文件。Create a binary resource (.resources) file programmatically. 然后使用语言编译器将该文件嵌入可执行应用程序或应用程序库,或者使用程序集链接器 (Al.exe) 将这个二进制资源文件嵌入附属程序集。You can then embed the file in an application executable or an application library by using a language compiler, or you can embed it in a satellite assembly by using Assembly Linker (Al.exe). 有关详细信息,请参阅 .resources 文件中的资源部分。For more information, see the Resources in .resources Files section.

  • 使用 Visual Studio 创建一个资源文件并将其包含在项目中。Use Visual Studio to create a resource file and include it in your project. Visual Studio 提供一个资源编辑器,借助该编辑器,可添加、删除和修改资源。Visual Studio provides a resource editor that lets you add, delete, and modify resources. 编译时,资源文件会自动转换成二进制 .resources 文件,并嵌入应用程序程序集或附属程序集中。At compile time, the resource file is automatically converted to a binary .resources file and embedded in an application assembly or satellite assembly. 有关详细信息,请参阅 Visual Studio 中的资源文件部分。For more information, see the Resource Files in Visual Studio section.

文本文件中的资源Resources in text files

文本(.txt 或 .restext)文件只能用于存储字符串资源。You can use text (.txt or .restext) files to store string resources only. 对于非字符串资源,使用 .resx 文件或以编程方式创建它们。For non-string resources, use .resx files or create them programmatically. 包含字符串资源的文本文件使用以下格式:Text files that contain string resources have the following format:

# 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

.txt 和 .restext 文件的资源文件格式是相同的。The resource file format of .txt and .restext files is identical. .restext 文件扩展名仅用于明确区分文本文件和基于文本的资源文件。The .restext file extension merely serves to make text files immediately identifiable as text-based resource files.

字符串资源显示为名称/值对,其中名称是标识资源的字符串,值是在将名称传递给资源检索方法(例如 ResourceManager.GetString)时返回的资源字符串。String resources appear as name/value pairs, where name is a string that identifies the resource, and value is the resource string that is returned when you pass name to a resource retrieval method such as ResourceManager.GetString. 名称和值必须用等号 (=) 分隔开。name and value must be separated by an equal sign (=). 例如:For example:

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

注意

请勿使用资源文件存储密码、 安全敏感信息或私人数据。Do not use resource files to store passwords, security-sensitive information, or private data.

在文本文件中,允许存在空字符串(即值为 String.Empty 的资源)。Empty strings (that is, a resource whose value is String.Empty) are permitted in text files. 例如:For example:

EmptyString=

从 .NET Framework 4.5 开始并在所有版本的 .NET Core 中,文本文件支持使用 #ifdefsymbol... #endif#if !symbol... #endif 构造的传统编译。Starting with .NET Framework 4.5 and in all versions of .NET Core, text files support conditional compilation with the #ifdefsymbol... #endif and #if !symbol... #endif constructs. 还可以通过资源文件生成器 (resgen.exe) 使用 /define 开关来定义符号。You can then use the /define switch with Resource File Generator (Resgen.exe) to define symbols. 每个资源都需要其自己的 #ifdefsymbol... #endif#if !symbol... #endif 构造。Each resource requires its own #ifdefsymbol... #endif or #if !symbol... #endif construct. 如果使用的是 #ifdef 语句,并且定义了 symbol,则关联的资源将包括在 .resources 文件中;否则,将不包括此资源。If you use an #ifdef statement and symbol is defined, the associated resource is included in the .resources file; otherwise, it is not included. 如果使用的是 #if ! 语句,并且没有定义 symbol,则关联的资源将包括在 .resources 文件中;否则,将不包括此资源。If you use an #if ! statement and symbol is not defined, the associated resource is included in the .resources file; otherwise, it is not included.

注释在文本文件中为可选项,并且在每行开头使用分号 (;) 或者井号 (#) 开头。Comments are optional in text files and are preceded either by a semicolon (;) or by a pound sign (#) at the beginning of a line. 包含注释的行可位于文件中的任何位置。Lines that contain comments can be placed anywhere in the file. 使用资源文件生成器 (Resgen.exe) 创建的已编译 .resources 文件中不包含注释。Comments are not included in a compiled .resources file that is created by using Resource File Generator (Resgen.exe).

文本文件中的所有空白行将视为空格并忽略。Any blank lines in the text files are considered to be white space and are ignored.

下面的示例定义名为 OKButtonCancelButton 的两个字符串资源。The following example defines two string resources named OKButton and CancelButton.

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

如果文本文件包含名称的重复匹配项,资源文件生成器 (Resgen.exe) 将显示一条警告,并忽略第二个名称。If the text file contains duplicate occurrences of name, Resource File Generator (Resgen.exe) displays a warning and ignores the second name.

不能包含新行字符,但是可以使用 C 语言样式的转义符(如 \n)来表示新行,并 \t 以表示制表符。如果转义,还可以包含反斜杠字符(例如,"\\")。value cannot contain new line characters, but you can use C language-style escape characters such as \n to represent a new line and \t to represent a tab. You can also include a backslash character if it is escaped (for example, "\\"). 此外,允许使用空字符串。In addition, an empty string is permitted.

应使用 little-endian 或 big-endian 字节顺序的 UTF-8 编码或 UTF-16 编码以文本文件格式保存资源。You should save resources in text file format by using UTF-8 encoding or UTF-16 encoding in either little-endian or big-endian byte order. 但是在默认情况下,将 .txt 文件转换为 .resources 文件的资源文件生成器 (Resgen.exe) 会将文件默认视为 UTF-8 文件。However, Resource File Generator (Resgen.exe), which converts a .txt file to a .resources file, treats files as UTF-8 by default. 如果希望 Resgen.exe 识别使用 UTF-16 编码的文件,必须在文件开头包含 Unicode 字节顺序标记 (U + FEFF)。If you want Resgen.exe to recognize a file that was encoded using UTF-16, you must include a Unicode byte order mark (U+FEFF) at the beginning of the file.

若要将文本格式的资源文件嵌入到 .NET 程序集,必须使用资源文件生成器 (Resgen.exe) 将文件转换为二进制资源 (.resources) 文件。To embed a resource file in text format into a .NET assembly, you must convert the file to a binary resource (.resources) file by using Resource File Generator (Resgen.exe). 然后可使用语言编译器将 .resources 文件嵌入 .NET 程序集,或者使用程序集链接器 (Al.exe) 将其嵌入附属程序集。You can then embed the .resources file in a .NET assembly by using a language compiler or embed it in a satellite assembly by using Assembly Linker (Al.exe).

下面的示例在简单的“Hello World”控制台应用程序中使用了一个名为 GreetingResources.txt 的文本格式的资源文件。The following example uses a resource file in text format named GreetingResources.txt for a simple "Hello World" console application. 该文本文件定义了 promptgreeting 两个字符串,分别用于提示用户输入其名字和显示一条问候。The text file defines two strings, prompt and greeting, that prompt the user to enter his or her name and display a greeting.

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

使用以下命令可以将该文本文件转换成 .resources 文件:The text file is converted to a .resources file by using the following command:

resgen GreetingResources.txt

下面的示例展示了某控制台应用程序中的源代码,该控制台应用程序使用 .resources 文件向用户显示信息。The following example shows the source code for a console application that uses the .resources file to display messages to the user.

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!

如果使用的是 Visual Basic,且源代码文件名为 Greeting.vb,以下命令将创建一个包含嵌入的 .resources 文件的可执行文件:If you are using Visual Basic, and the source code file is named Greeting.vb, the following command creates an executable file that includes the embedded .resources file:

vbc greeting.vb -resource:GreetingResources.resources

如果使用的是 C#,并且将源代码文件命名为 Greeting.cs,以下命令将创建一个包含嵌入 .resources 文件的可执行文件:If you are using C#, and the source code file is named Greeting.cs, the following command creates an executable file that includes the embedded .resources file:

csc greeting.cs -resource:GreetingResources.resources

.resx 文件中的资源Resources in .resx files

与只能存储字符串资源的文本文件不同,XML 资源 (.resx) 文件可以存储字符串、二进制数据(图像、图标和音频剪辑等)以及编程对象。Unlike text files, which can only store string resources, XML resource (.resx) files can store strings, binary data such as images, icons, and audio clips, and programmatic objects. .resx 文件包含一个标准标头,用以描述资源条目的格式,并指定用于解析数据的 XML 的版本信息。A .resx file contains a standard header, which describes the format of the resource entries and specifies the versioning information for the XML that is used to parse the data. 资源文件数据跟在 XML 标头之后。The resource file data follows the XML header. 每个数据项由包含在 data 标记中的一个名称/值对构成。Each data item consists of a name/value pair that is contained in a data tag. name 属性定义资源名称,而嵌套的 value 标记包含资源值。Its name attribute defines the resource name, and the nested value tag contains the resource value. 对于字符串数据,value 标记包含字符串。For string data, the value tag contains the string.

例如,以下 data 标记定义了一个名为 prompt 且值为“Enter your name”的字符串资源。For example, the following data tag defines a string resource named prompt whose value is "Enter your name:".

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

警告

请勿使用资源文件存储密码、 安全敏感信息或私人数据。Do not use resource files to store passwords, security-sensitive information, or private data.

对于资源对象,data 标记中包含了 type 属性,用于指示资源的数据类型。For resource objects, the data tag includes a type attribute that indicates the data type of the resource. 对于由二进制数据构成的对象,data 标记还包含 mimetype 属性,用以指示二进制数据的 base64 类型。For objects that consist of binary data, the data tag also includes a mimetype attribute, which indicates the base64 type of the binary data.

备注

所有的 .resx 文件都使用二进制序列化格式化程序来生成和分析指定类型的二进制数据。All .resx files use a binary serialization formatter to generate and parse the binary data for a specified type. 因此如果对象的二进制序列化格式以不兼容的方式发生更改,.resx 文件可能失效。As a result, a .resx file can become invalid if the binary serialization format for an object changes in an incompatible way.

以下示例显示了部分包含 Int32 资源和位图图像的 .resx 文件。The following example shows a portion of a .resx file that includes an Int32 resource and a bitmap image.

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

重要

由于 .resx 文件必须由采用预定义格式的格式标准的 XML 构成,不建议手动使用 .resx 文件,尤其是当 .resx 文件包含非字符串资源时。Because .resx files must consist of well-formed XML in a predefined format, we do not recommend working with .resx files manually, particularly when the .resx files contain resources other than strings. 相反,Visual Studio 提供一个用于创建和操作 .resx 文件的透明接口。Instead, Visual Studio provides a transparent interface for creating and manipulating .resx files. 有关详细信息,请参阅 Visual Studio 中的资源文件部分。For more information, see the Resource Files in Visual Studio section. 还可以通过编程方式创建和操作 .resx 文件。You can also create and manipulate .resx files programmatically. 有关详细信息,请参阅以编程方式使用 .resx 文件For more information, see Working with .resx Files Programmatically.

.resources 文件中的资源Resources in .resources files

可以使用 System.Resources.ResourceWriter 类以编程方式从代码中直接创建二进制资源 (.resources) 文件。You can use the System.Resources.ResourceWriter class to programmatically create a binary resource (.resources) file directly from code. 还可以使用资源文件生成器 (Resgen.exe) 从文本文件或 .resx 文件创建 .resources 文件。You can also use Resource File Generator (Resgen.exe) to create a .resources file from a text file or a .resx file. .resources 文件除了可以包含字符串数据之外,还可以包含二进制数据(字节数组)和对象数据。The .resources file can contain binary data (byte arrays) and object data in addition to string data. 以编程方式创建 .resources 文件需要执行下列步骤:Programmatically creating a .resources file requires the following steps:

  1. 创建一个具有唯一文件名的 ResourceWriter 对象。Create a ResourceWriter object with a unique file name. 可以通过将文件名或文件流指定为 ResourceWriter 类构造函数来实现这此操作。You can do this by specifying either a file name or a file stream to a ResourceWriter class constructor.

  2. 调用 ResourceWriter.AddResource 方法的重载之一以便将每个已命名的资源添加到文件。Call one of the overloads of the ResourceWriter.AddResource method for each named resource to add to the file. 该资源可以是字符串、对象或二进制数据(字节数组)集合。The resource can be a string, an object, or a collection of binary data (a byte array).

  3. 通过调用 ResourceWriter.Close 方法将资源写入文件并关闭 ResourceWriter 对象。Call the ResourceWriter.Close method to write the resources to the file and to close the ResourceWriter object.

备注

请勿使用资源文件存储密码、 安全敏感信息或私人数据。Do not use resource files to store passwords, security-sensitive information, or private data.

下面的示例以编程方式创建了一个名为 CarResources.resources 的 .resources 文件,该文件存储了六个字符串、一个图标和两个由应用程序定义的对象(两个 Automobile 对象)。The following example programmatically creates a .resources file named CarResources.resources that stores six strings, an icon, and two application-defined objects (two Automobile objects). 请注意,示例中定义并实例化的 Automobile 类,使用 SerializableAttribute 属性进行标记,这样二进制序列化格式化程序便可持久保留该类。Note that the Automobile class, which is defined and instantiated in the example, is tagged with the SerializableAttribute attribute, which allows it to be persisted by the binary serialization formatter.

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

创建 .resources 文件后,可以通过含入语言编译器的 /resource 开关将其嵌入运行时可执行文件或库中,或者通过使用程序集链接器 (Al.exe) 将其嵌入附属程序集。After you create the .resources file, you can embed it in a run-time executable or library by including the language compiler's /resource switch, or embed it in a satellite assembly by using Assembly Linker (Al.exe).

Visual Studio 中的资源文件Resource files in Visual Studio

将资源文件添加到 Visual Studio 项目时,Visual Studio 会在项目目录中创建一个 .resx 文件。When you add a resource file to your Visual Studio project, Visual Studio creates a .resx file in the project directory. Visual Studio 会提供资源编辑器,可用于添加字符串、图像和二进制对象。Visual Studio provides resource editors that enable you to add strings, images, and binary objects. 编辑器只能用于处理静态数据,因此不能用于储存编程对象;必须以编程方式将对象数据写入 .resx 文件或 .resources 文件。Because the editors are designed to handle static data only, they cannot be used to store programmatic objects; you must write object data to either a .resx file or to a .resources file programmatically. 有关详细信息,请参阅以编程方式使用 .resx 文件.resources 文件中的资源部分。For more information, see Working with .resx Files Programmatically and the Resources in .resources Files section.

如果要添加本地化资源,请为它们提供与主资源文件相同的根文件名称。If you're adding localized resources, give them the same root file name as the main resource file. 还应在文件名中指定其区域性。You should also designate their culture in the file name. 例如,如果要添加一个名为 Resources.resx 的资源文件,或许还需要创建名为 Resources.en-US.resx 和 Resources.fr-fr.resx 的资源文件,分别用以保存英语(美国)和法语(法国)区域性的本地化资源。For example, if you add a resource file named Resources.resx, you might also create resource files named Resources.en-US.resx and Resources.fr-FR.resx to hold localized resources for the English (United States) and French (France) cultures, respectively. 还应该指定应用程序的默认区域性。You should also designate your application's default culture. 找不到特定区域性的本地化资源时,将使用此默认区域性的资源。This is the culture whose resources are used if no localized resources for a particular culture can be found. 若要指定默认区域性,请在 Visual Studio 的解决方案资源管理器中,右键单击项目名称,指向“应用程序”,单击“程序集信息”,然后在“非特定语言”列表中选择合适的语言/区域性。To specify the default culture, in Solution Explorer in Visual Studio, right-click the project name, point to Application, click Assembly Information, and select the appropriate language/culture in the Neutral language list.

编译时,Visual Studio 首先将项目中的 .resx 文件转换为二进制资源 (.resources) 文件,并将其存储在项目 obj 目录的子目录中。At compile time, Visual Studio first converts the .resx files in a project to binary resource (.resources) files and stores them in a subdirectory of the project's obj directory. Visual Studio 会将不包含本地化资源的所有资源文件嵌入项目生成的主程序集中。Visual Studio embeds any resource files that do not contain localized resources in the main assembly that is generated by the project. 如果资源文件包含本地化资源,Visual Studio 会将其嵌入用于每个本地化区域性的单独的附属程序集中。If any resource files contain localized resources, Visual Studio embeds them in separate satellite assemblies for each localized culture. 然后将每个附属程序集存储到名称与本地化区域性相对应的目录中。It then stores each satellite assembly in a directory whose name corresponds to the localized culture. 例如,本地化的英语(美国)资源存储在 en-US 子目录的附属程序集中。For example, localized English (United States) resources are stored in a satellite assembly in the en-US subdirectory.

请参阅See also