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 resources 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 ‘ProjectName.g.Resources
‘.
Embedded Resources
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 MyProject.Texts.Guide.txt.
Embedded resources can be enumerated by calling Assembly.GetManifestResourceNames()
and read via Assembly.GetManifestResourceStream()
.
Resx Files
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 “.resources“.
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.GetString()
, ResourceManager.GetObject()
, or ResourceManager.GetStream()
. You can get an entire dictionary for a particular culture via ResourceManager.GetResourceSet()
.
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.
Project Resources
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.
It has:
- One file with build action
EmbeddedResource
named EmbeddedResourceFile.txt - Two files with BuildAction ‘
Resource
’ named ResourceFile.txt
and ResourceFile2.txt - Standard project resx file Properties\Resources.resx with 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
CodeProject
Conclusion
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.