Loop Through All the Resources in a .Resx File

Loop through all the resources in a .resx file

You should always use the resource manager and not read files directly to ensure globalization is taken into account.

using System.Collections;
using System.Globalization;
using System.Resources;

...

/* Reference to your resources class -- may be named differently in your case */
ResourceManager MyResourceClass =
new ResourceManager(typeof(Resources));

ResourceSet resourceSet =
MyResourceClass.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
foreach (DictionaryEntry entry in resourceSet)
{
string resourceKey = entry.Key.ToString();
object resource = entry.Value;
}

How to iterate over Resources.resx in C#?

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.

Loop through all Resources in ResourceManager - C#

Use ResourceManager.GetResourceSet() for a list of all resources for a given culture. The returned ResourceSet implements IEnumerable (you can use foreach).


To answer Nico's question: you can count the elements of an IEnumerable by casting it to the generic IEnumerable<object> and use the Enumerable.Count<T>() extension method, which is new in C# 3.5:

using System.Linq;

...

var resourceSet = resourceManager.GetResourceSet(..);
var count = resSet.Cast<object>().Count();

Looping through RESX file, items not in order

Dictionary/Hashtabels do not preserve order of elements. There also no guarantees that order will be the same between run-time versions, x86/x64/other flavors or even runs of the same binaries (also usually order stays the same).

ResourceSet Class

The ResourceSet class enumerates over an IResourceReader, loading every name and value, and storing them in a Hashtable. A custom IResourceReader can be used.

Looping through a file of resources and loading them into an array

Give this a shot.

var images = Assembly.GetExecutingAssembly()
.GetManifestResourceNames()
.Where(x => x.EndsWith("_GameBoardImage.png"))
.ToList();

foreach (var img in images)
{
// Do stuff...
}

Loop through Embedded Resources and copy to local path

Start by getting all resources embedded in your assembly:

Assembly.GetExecutingAssembly().GetManifestResourceNames()

You can check these names against the name of your desired subfolder to see if they are inside or outside it with a simple call to StartsWith.

Now loop through the names, and get the corresponding resource stream:

const string subfolder = "WINFORMSAPP.Resources.SUBFOLDER.";
var assembly = Assembly.GetExecutingAssembly();
foreach (var name in assembly.GetManifestResourceNames()) {
// Skip names outside of your desired subfolder
if (!name.StartsWith(subfolder)) {
continue;
}
using (Stream input = assembly.GetManifestResourceStream(name))
using (Stream output = File.Create(path + name.Substring(subfolder.Length))) {
input.CopyTo(output);
}
}

Loop through embedded resources of different languages/cultures in C#

Here is a solution I think works for Winforms:

// get cultures for a specific resource info
public static IEnumerable<CultureInfo> EnumSatelliteLanguages(string baseName)
{
if (baseName == null)
throw new ArgumentNullException("baseName");

ResourceManager manager = new ResourceManager(baseName, Assembly.GetExecutingAssembly());
ResourceSet set = manager.GetResourceSet(CultureInfo.InvariantCulture, true, false);
if (set != null)
yield return CultureInfo.InvariantCulture;

foreach (CultureInfo culture in EnumSatelliteLanguages())
{
set = manager.GetResourceSet(culture, true, false);
if (set != null)
yield return culture;
}
}

// determine what assemblies are available
public static IEnumerable<CultureInfo> EnumSatelliteLanguages()
{
foreach (string directory in Directory.GetDirectories(AppDomain.CurrentDomain.BaseDirectory))
{
string name = Path.GetFileNameWithoutExtension(directory); // resource dir don't have an extension...

// format is XX or XX-something, we discard directories that can't match.
// could/should be replaced by a regex but we still need to catch cultures errors...
if (name.Length < 2)
continue;

if (name.Length > 2 && name[2] != '-')
continue;

CultureInfo culture = null;
try
{
culture = CultureInfo.GetCultureInfo(name);
}
catch
{
// not a good directory...
continue;
}

string resName = Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().Location) + ".resources.dll";
if (File.Exists(Path.Combine(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, name), resName)))
yield return culture;
}
}

And here is how you would use it for a WindowsFormsApplication1:

    List<CultureInfo> cultures = new List<CultureInfo>(EnumSatelliteLanguages("WindowsFormsApplication1.GUILanguage"));


Related Topics



Leave a reply



Submit