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 Shared Function MakeResXFile() As String
    Dim resxName As String = "MyResX.resx"
    Using resxWriter As New ResXResourceWriter(resxName)
        resxWriter.AddResource("MyFormTitle", "My Resource List Form")
        resxWriter.AddResource("MyFormIcon", SystemIcons.Warning)
    End Using

    Return resxName
End Function


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 resxReader As New ResXResourceReader(resxFile)
    Dim resItem As ListViewItem
    For Each entry As DictionaryEntry In resxReader
        resItem = new ListViewItem(CType(entry.Key, String))
        resItem.SubItems.Add(entry.Value.GetType().FullName)
        resList.Items.Add(resItem)
    Next entry
End Using


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 resxSet As New ResXResourceSet(resxFile)
    MyClass.Text = resxSet.GetString("MyFormTitle")
    MyClass.Icon = CType(resxSet.GetObject("MyFormIcon"), Icon)
End Using


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.


Imports System
Imports System.Resources
Imports System.Collections
Imports System.Diagnostics
Imports System.Drawing
Imports System.Windows.Forms

Public Class ResXViewForm
    Inherits Form

    Private resxFile As String

    Public Shared Function MakeResXFile() As String
        Dim resxName As String = "MyResX.resx"
        Using resxWriter As New ResXResourceWriter(resxName)
            resxWriter.AddResource("MyFormTitle", "My Resource List Form")
            resxWriter.AddResource("MyFormIcon", SystemIcons.Warning)
        End Using

        Return resxName
    End Function

    Public Sub New(resxFile As String)
        MyClass.resxFile = resxFile

        Using resxSet As New ResXResourceSet(resxFile)
            MyClass.Text = resxSet.GetString("MyFormTitle")
            MyClass.Icon = CType(resxSet.GetObject("MyFormIcon"), Icon)
        End Using

        Dim margin As Integer = 10
		Dim resList As 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 resxReader As New ResXResourceReader(resxFile)
            Dim resItem As ListViewItem
            For Each entry As DictionaryEntry In resxReader
                resItem = new ListViewItem(CType(entry.Key, String))
                resItem.SubItems.Add(entry.Value.GetType().FullName)
                resList.Items.Add(resItem)
            Next entry
        End Using

        Dim resxButton As New Button()
        resxButton.Text = "Show ResX"
        AddHandler resxButton.Click, AddressOf resxButton_Click
        resxButton.Location = New Point(resList.Bounds.Left,
            resList.Bounds.Bottom + margin)

        Dim okButton As New Button()
        okButton.Text = "OK"
        AddHandler okButton.Click, AddressOf okButton_Click
        okButton.Location = new Point(resList.Bounds.Right - okButton.Width,
            resList.Bounds.Bottom + margin)

        MyClass.ClientSize = New Size(resList.Width + margin * 2,
            okButton.Top + okButton.Height + margin)

        MyClass.FormBorderStyle = FormBorderStyle.FixedDialog
        MyClass.MaximizeBox = False
        MyClass.MinimizeBox = False
        MyClass.StartPosition = FormStartPosition.CenterScreen
        MyClass.Controls.Add(resList)
        MyClass.Controls.Add(resxButton)
        MyClass.Controls.Add(okButton)
    End Sub

    Private Sub resxButton_Click(sender As Object, e As EventArgs)
        Process.Start("Notepad.exe", MyClass.resxFile)
    End Sub

    Private Sub okButton_Click(sender As Object, e As EventArgs)
        Application.Exit()
    End Sub

    Public Shared Sub Main()
        Dim resxFile As String = MakeResXFile()

        Application.Run(New ResXViewForm(resxFile))
    End Sub
End Class


Community Additions

Show: