In Visual Studio you can set “Build Action” for a project item to ‘Resource’ or ‘Embedded Resource’, among other things. The difference between the two is confusing, and exact up-to-date documentation is hard to find. (This StackOverflow post is probably the best, but not 100% accurate.) Today I became confused one more time, so I decided to clear up the matter and put an end to the confusion.
First of all, both kinds of resource are actually embedded in the executable. ‘EmbeddedResource’ files are placed directly into the executable as manifest resources. All ‘Resource’ files are put in a special structured manifest resource named ‘
Embedded resources are the same as manifest resources. You can see them as
.mresource records in ILDASM. If in a project named
MyProject you create a file named
Texts\Guide.txt and mark it as EmbeddedResource, the project output will have a manifest resource named
Embedded resources can be enumerated by calling
Assembly.GetManifestResourceNames() and read via
Embedded resource has no predefined structure: it is just a named blob of bytes. So called “.resx” file is a special kind of embedded resource. It is a string-to-object dictionary that maps a name to an object. The object may be a string, an image, an icon, or a blob of bytes. Resx files can be used for localization: in addition to the name each object may have a culture, e.g. “Neutral”, or “English (UK)”.
You can add resx file to your project by right clicking on the project name, choosing
Add->New Item... and then selecting
Visual C# Items->General->Resource file. The entire resx file is placed into the executable as a single manifest resource. In the name of the manifest resource “
.resx” extension is replaced with “
Resx files are accessed via the
System.Resources.ResourceManager class. Note that the “base name” supplied to the constructor is the file name without extension. You can retrieve a particular resource by calling
ResourceManager.GetStream(). You can get an entire dictionary for a particular culture via
Resource Build Action
Files marked with build action of “Resource” are added to a special resx file called
ProjectName.g.resx. This file is generated during the build, it is not part of the project. You can access content of the ‘Resource’ files by creating an instance of
ResourceManager and calling
GetStream(filename). Additionally, in WPF applications you can access these resources via
Application.GetResourceStream() in C# and via things like
<Image Source="filepath" /> in XAML.
When you edit project resources on the Resources tab of the project property pages, Visual Studio creates another special resx file named
Properties\Resources.resx. Corresponding manifest resource name is
ProjectName.Properties.Resources.resources (yes, “resources” is repeated twice, one comes from the file name, and the other from the “.resx” extension being replaced with “.resources”). Visual Studio also creates a file called
Resources.Designer.cs that contains code for easy access to the dictionary items. E.g. a string named “WindowHeader” may be accessed simply as
Properties.Resource.WindowHeader, which will call
ResourceManager behind the scenes.
Putting it all together
A sample program (ResourceTypes.zip) demonstrates different kinds of resources and how to access them.
- One file with build action EmbeddedResource named
- Two files with BuildAction ‘Resource’ named
- Standard project resx file
Properties\Resources.resxwith some key-value pairs.
The output shows that there are three manifest resources, one of which is a simple file, and two others are resx resources with additional internal structure:
Manifest resources ResourceTypes.g.resources: '???☺ ? lSystem.Resources.ResourceRea...' ResourceTypes.Properties.Resources.resources: '???☺ ? lSystem.Resources.ResourceRea...' ResourceTypes.EmbeddedResourceFile.txt: 'EmbeddedResourceFile.txt: it is compiled...' Items in ResourceTypes.g: resourcefile2.txt: Stream: ResourceFile2.txt: it is compiled as 'Re... resourcefile.txt: Stream: ResourceFile.txt: it is compiled as 'Res... Items in ResourceTypes.Properties.Resources: MyKey: MyValue Key2: Value2
It would not hurt if the names were less confusing and the documentation were clearer and easier to find. Yet, the “resources” topic has a pretty long history, so I guess this is the best we could get for the money.