Rich Shealer Rich Shealer - 2 months ago 5x
C# Question

How do I create and recall class objects from a resource file that I can use at runtime?

I am trying to create a resource file of message codes. I've created a small console example that fails when I try to recall the object.

I based this on this MSDN -Creating Resource Files example, but I don't know what I've missed while I tried to simplify it.

In the code I run it once to generate the resource file and add that file to the project. Then I recompile to run the recall code.

using System;
using System.Reflection;
using System.Resources;

namespace ResourceDemo
internal class Program
private static void Main(string[] args)
bool generateMode = false;

if (generateMode) {
// After running once with generate mode set to true, add the resulting
// "StatusItem.resource" that was created in the .\bin\x86\Debug folder
// to the project.
else {
// When run the next line generates an exception:
// An unhandled exception of type 'System.Resources.MissingManifestResourceException' occurred in mscorlib.dll
// Additional information: Could not find any resources appropriate for the specified culture
// or the neutral culture. Make sure "StatusItems.resources" was correctly embedded or linked
// into assembly "ResourceDemo" at compile time, or that all the satellite assemblies required
// are loadable and fully signed.

StatusItem statusItem = GetResource("2");
Console.WriteLine("Id: {0} Message: {1}", statusItem.Id.ToString(), statusItem.Message);

public static void Generate()
StatusItem[] statusItem = new StatusItem[4];

// Instantiate an Status object items.
statusItem[0] = new StatusItem(2, "File not found");
statusItem[1] = new StatusItem(3, "Path not found");
statusItem[2] = new StatusItem(4, "Too many open files");
statusItem[3] = new StatusItem(5, "File access denied");

// Define a resource file named StatusItems.resx.
using (System.Resources.ResourceWriter rw = new ResourceWriter(@".\StatusItems.resources")) {
for (int i = 0; i < 4; i++) {
rw.AddResource(statusItem[i].Id.ToString(), statusItem[i]);


public static StatusItem GetResource(string key)
Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
System.Resources.ResourceManager rm = new System.Resources.ResourceManager("StatusItems", Assembly.Load("ResourceDemo"));

return (StatusItem)rm.GetObject(key);

public class StatusItem
public StatusItem(int id, string message)
Id = id;
Message = message;

public int Id { get; set; }
public string Message { get; set; }


…and add that file to the project

How? Are you adding the file in the IDE? If so, that won't work...that treats the file as plain binary data; it's not interpreted as resource data itself. You need to use /resource on the command line or use al.exe to embed the .resource file after the fact.

If you want to be able to simply add the generated resources output to your project, you probably want to use ResXResourceWriter instead of ResourceWriter. Then you'll get a .resx file, which you can add to the project directly. Visual Studio will compile the .resx file into a .resources file and embed it correctly automatically.

This also has the advantage of producing a human-readable file, and one that can also be opened within the IDE (albeit with limited functionality, depending on the types you put into it).


  • The ResXResourceWriter class is actually defined in System.Windows.Forms.dll, so you'll need to include a reference to that assembly in your project.
  • Types you write to the .resx file will need to be able to be referenced at compile time, which means they can't be in the same assembly you're compiling. You'll need to put them in a separate DLL that is referenced by your program.
  • The ResourceManager name for the .resx file will be fully-qualified in the context of your project. So for example, assuming you add the .resx file as a top-level file in your project, you'll need to load "ResourceDemo.StatusItems" instead of just "StatusItems". If you add the .resx file "As a link", it will by default wind up in your project contained in folders corresponding to the file system, e.g. "bin\Debug\StatusItems.resx". In that case, the manager name will be "ResourceDemo.bin.Debug.StatusItems".

Regarding that last point, if you ever have any question about the name, you can use Assembly.GetManifestResourceNames() to inspect what the names that have been compiled into your program are.