Resources in .resx File Format

The .resx resource file format consists of XML entries, which specify objects and strings inside XML tags. One advantage of a .resx file is that when you open the file with a text editor (such as Notepad or Microsoft Word), you can write to it, parse it, and manipulate it. When viewing a .resx file, you can actually see the binary form of an embedded object (for example, a picture) when this binary information is a part of the resource manifest. Apart from this binary information, a .resx file is completely readable and maintainable.

NoteNote

Do not use resource files to store passwords, security-sensitive information, or private data.

A .resx file contains a standard set of header information, which describes the format of the resource entries and specifies the versioning information for the XML used to parse the data. The following example shows what a typical set of header statements in a .resx file might look like.

<?xml version="1.0" encoding="utf-8"?>
<root>
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
  <xsd:element name="data">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="value" type="xsd:string" minOccurs="0"                     msdata:Ordinal="2" />
      </xsd:sequence>
      <xsd:attribute name="name" type="xsd:string" />
      <xsd:attribute name="type" type="xsd:string" />
      <xsd:attribute name="mimetype" type="xsd:string" />
    </xsd:complexType>
  </xsd:element>

Following the header information, each entry is described as a name/value pair, very similar to the way in which strings are specified in a .txt file. A name/value pair in the .resx format is wrapped in XML code, which describes string or object values. When a string is added to a .resx file, the name of the string is embedded in a <data> tag, and the value is enclosed in a <value> tag, as in the following example.

    <data name="string1">
      <value>hello</value>
    </data>

When an object is inserted into a .resx file, the same <data> and <value> tags are used to describe the entry, but the <data> tag includes either a type or MIME type specifier. The type specifier holds the data type of the object being saved. The MIME type specifier holds the base type (Base64) of the binary information stored, if the object consists of binary data.

NoteNote

All .resx files use a binary serialization formatter to generate and parse the binary data for a specified type. As a result, a .resx file can become invalid if the binary serialization format for an object changes in an incompatible way.

The following example shows an Int32 object saved in a .resx file, and the beginning of a bitmap object, which holds the binary information from an actual .gif file.

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

You can use the System.Resources.ResXResourceWriter class to create a .resx file directly from code. The following example illustrates how to create a .resx file that stores an icon and a string as resources inside the file. Create a ResXResourceWriter with a unique file name. Call the ResXResourceWriter.AddResource method for each resource to add to the file. Finally, call the ResXResourceWriter.Close method, or create a ResXResourceWriter within a using statement, to write the resource information to the resource file.


public static string MakeResXFile()
{
    string resxName = "MyResX.resx";
    using (ResXResourceWriter resxWriter = new ResXResourceWriter(resxName))
    {
        resxWriter.AddResource("MyFormTitle", "My Resource List Form");
        resxWriter.AddResource("MyFormIcon", SystemIcons.Warning);
    }

    return resxName;
}


You can also manipulate a .resx file directly. However, to avoid corrupting the file, be careful not to modify any binary information that is stored in the file.

You cannot embed a .resx file in a runtime executable or compile it into a satellite assembly. You must convert your .resx file into a .resources file by using Resgen.exe (Resource File Generator). For more information, see Resources in .Resources File Format.

If you want to retrieve the names and values of the resources in a .resx file, use the System.Resources.ResXResourceReader class. This class provides an enumerator for all the resources in the .resx file. The following example demonstrates how to create a ResXResourceReader for a specified file, iterate through the file, and add the names and values of resources to a list in a form.


using (ResXResourceReader resxReader = new ResXResourceReader(resxFile))
{
    ListViewItem resItem;
    foreach (DictionaryEntry entry in resxReader)
    {
        resItem = new ListViewItem((string)entry.Key);
        resItem.SubItems.Add(entry.Value.GetType().FullName);
        resList.Items.Add(resItem);
    }
}


To retrieve a resource explicitly by name, use the System.Resources.ResXResourceSet class. The GetObject and GetString methods are used to get the value of a named resource. The following example retrieves both a form title string and a form icon by their resource names.


using (ResXResourceSet resxSet = new ResXResourceSet(resxFile))
{
    this.Text = resxSet.GetString("MyFormTitle");
    this.Icon = (Icon)resxSet.GetObject("MyFormIcon");
}


The following example illustrates the use of all the .resx manipulation classes mentioned in the previous sections. Before constructing and displaying the form, a .resx file is created with two resource items: a form title string and an icon to set as the form icon. In the constructor, the title string and icon are retrieved by using the ResXResourceSet class. Finally, the resources in the .resx file are enumerated and added to a list shown in the form's body. The text of the .resx file that was created is viewed by pressing the Show ResX button in the form.


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

public class ResXViewForm : Form
{
    private string resxFile;

    public static string MakeResXFile()
    {
        string resxName = "MyResX.resx";
        using (ResXResourceWriter resxWriter = new ResXResourceWriter(resxName))
        {
            resxWriter.AddResource("MyFormTitle", "My Resource List Form");
            resxWriter.AddResource("MyFormIcon", SystemIcons.Warning);
        }

        return resxName;
    }

    public ResXViewForm(string resxFile)
    {
        this.resxFile = resxFile;

        using (ResXResourceSet resxSet = new ResXResourceSet(resxFile))
        {
            this.Text = resxSet.GetString("MyFormTitle");
            this.Icon = (Icon)resxSet.GetObject("MyFormIcon");
        }

        int margin = 10;
		ListView resList = new ListView();
		resList.Bounds = new Rectangle(new Point(margin, margin), new Size(300, 60));
        resList.View = View.Details;
        resList.GridLines = true;
        resList.Columns.Add("Resource Name", resList.ClientSize.Width / 2);
        resList.Columns.Add("Type", resList.ClientSize.Width / 2);
        using (ResXResourceReader resxReader = new ResXResourceReader(resxFile))
        {
            ListViewItem resItem;
            foreach (DictionaryEntry entry in resxReader)
            {
                resItem = new ListViewItem((string)entry.Key);
                resItem.SubItems.Add(entry.Value.GetType().FullName);
                resList.Items.Add(resItem);
            }
        }

        Button resxButton = new Button();
        resxButton.Text = "Show ResX";
        resxButton.Click += new EventHandler(resxButton_Click);
        resxButton.Location = new Point(resList.Bounds.Left,
            resList.Bounds.Bottom + margin);

        Button okButton = new Button();
        okButton.Text = "OK";
        okButton.Click += new EventHandler(okButton_Click);
        okButton.Location = new Point(resList.Bounds.Right - okButton.Width,
            resList.Bounds.Bottom + margin);

        this.ClientSize = new Size(resList.Width + margin * 2,
            okButton.Top + okButton.Height + margin);

        this.FormBorderStyle = FormBorderStyle.FixedDialog;
        this.MaximizeBox = false;
        this.MinimizeBox = false;
        this.StartPosition = FormStartPosition.CenterScreen;
        this.Controls.Add(resList);
        this.Controls.Add(resxButton);
        this.Controls.Add(okButton);
    }

    private void resxButton_Click(object sender, EventArgs e)
    {
        Process.Start("Notepad.exe", this.resxFile);
    }

    private void okButton_Click(object sender, EventArgs e)
    {
        Application.Exit();
    }

    public static void Main()
    {
        string resxFile = MakeResXFile();

        Application.Run(new ResXViewForm(resxFile));
    }
}


Was this page helpful?
(1500 characters remaining)
Thank you for your feedback

Community Additions

Show:
© 2014 Microsoft