Search code examples
c#resx

How to iterate over Resources.resx in C#?


I want to access a number of files in C#, and I haven't been able to succeed in doing so without hard-coding a path. I do not want to specify an exact path, as the program should work independent of its location.
I figured I should do this by adding the files to Resources, but I can't find how to iterate over those. I found several pages about reading .resx, but it seemed like all either only addressed accessing one specific resource by name, or used a hard-coded path.
The code I have currently is as follows:

ResXResourceReader resourcesreader = new ResXResourceReader(Properties.Resources);

This gives the compiler error "'Resources' is a type, which is not valid in the given context".

When I do hard-code a path, curiously, I get an error at runtime.

ResXResourceReader resourcesreader = new ResXResourceReader(@"G:\Programming\C#\Contest Judging\Contest Judging\Properties\Resources.resx");
foreach (DictionaryEntry image in resourcesreader)

At the bottom line, an exception is raised:

System.ArgumentException
  ResX file Could not find a part of the path 'G:\Programming\C#\Contest Judging\Contest Judging\bin\Resources\BugsyWPfeiffer 1.png'. Line 123, position 5. cannot be parsed.

Inner Exception 1:
XmlException: Could not find a part of the path 'G:\Programming\C#\Contest Judging\Contest Judging\bin\Resources\BugsyWPfeiffer 1.png'. Line 123, position 5.

Inner Exception 2:
DirectoryNotFoundException: Could not find a part of the path 'G:\Programming\C#\Contest Judging\Contest Judging\bin\Resources\BugsyWPfeiffer 1.png'.

I wonder why it starts looking in bin\, as I did a Ctrl + F through Resources.resx and it does not occur.


Solution

  • You can do this by fetching the ResourceManager from the generated Resources class:

    // Change this if you want to use fetch the resources for a specific culture
    var culture = CultureInfo.InvariantCulture;
    
    var resourceManager = Properties.Resources.ResourceManager;
    var resourceSet = resourceManager.GetResourceSet(culture, createIfNotExists: true, tryParents: true);
    foreach (DictionaryEntry entry in resourceSet)
    {
        Console.WriteLine($"{entry.Key}: {entry.Value}");
    }
    

    The resources are compiled into your application (or into satellite assemblies), so there's no resx file for you to load.