循环遍历 .resx 文件中的所有资源

Posted

技术标签:

【中文标题】循环遍历 .resx 文件中的所有资源【英文标题】:Loop through all the resources in a .resx file 【发布时间】:2010-01-11 09:53:56 【问题描述】:

有没有办法在 C# 中循环遍历 .resx 文件中的所有资源?

【问题讨论】:

您能否详细说明 RESX 文件是否在您的项目内部,或者您是否想要(或需要)读取单独的 RESX 文件或从另一个程序集读取 RESX? 【参考方案1】:

您应该始终使用资源管理器而不是直接读取文件,以确保将全球化考虑在内。

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;

【讨论】:

我花了一点时间才发现您需要这一行来声明 MyResourceClass。 ResourceManager MyResourceClass = new ResourceManager("Resources.ResourceFileName", System.Reflection.Assembly.Load("App_GlobalResources")); @JoeFletch:它不需要这条线。代码直接调用资源文件。示例:我有一个名为 PageList.resx 的文件,然后我会调用:ResourceSet resourceSet = PageList.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true); @Gabriel,感谢您的更新!我将不得不返回我的代码来检查这一点。 JoeFletch 的台词实际上帮助了我。我在另一个 C# 项目中有一个 resx,所以他的行允许我调用该 dll 程序集并以这种方式加载资源。此外,当我尝试在我的代码中包含 PageList 时,它为 PageList.ResourceManager 引发了一个错误。说“PageList 不包含 ResourceManager 的定义”。最后,string resourceKey = entry.Key 报错了,我改用“object resourceKey = entry.Key” 根据您的资源中是否确实定义了文化,您必须切换到 CultureInfo.InvariantCulture。这里我使用的是库中的资源,而不是 WinForms 应用程序。【参考方案2】:

关于它的博客on my blog :) 简短版本是,查找资源的全名(除非你已经知道它们):

var assembly = Assembly.GetExecutingAssembly();

foreach (var resourceName in assembly.GetManifestResourceNames())
    System.Console.WriteLine(resourceName);

将它们全部用于某事:

foreach (var resourceName in assembly.GetManifestResourceNames())

    using(var stream = assembly.GetManifestResourceStream(resourceName))
    
        // Do something with stream
    

要在执行程序集以外的其他程序集中使用资源,您只需使用Assembly 类的其他一些静态方法即可获得不同的程序集对象。希望对你有帮助:)

【讨论】:

你能列举not位于名为“Resource”的文件夹中的资源吗?我想在一个名为“Images”的文件夹中枚举位于我的项目中的所有资源图像。 很确定它不关心它的位置?测试一下? 我在一个文件夹中有用于导入 sql 文件的文件,这非常有效。我添加了从流到字符串的转换,因此我可以读取文件并且没有问题。【参考方案3】:

使用ResXResourceReader Class

ResXResourceReader rsxr = new ResXResourceReader("your resource file path");

// Iterate through the resources and display the contents to the console.
foreach (DictionaryEntry d in rsxr)

    Console.WriteLine(d.Key.ToString() + ":\t" + d.Value.ToString());

【讨论】:

【参考方案4】:

在您将资源 .RESX 文件添加到项目的那一刻,Visual Studio 将创建一个同名的 Designer.cs,为您创建一个将资源的所有项作为静态属性的类。输入资源文件名后,在编辑器中输入圆点即可看到资源的所有名称。

或者,您可以使用反射来遍历这些名称。

Type resourceType = Type.GetType("AssemblyName.Resource1");
PropertyInfo[] resourceProps = resourceType.GetProperties(
    BindingFlags.NonPublic | 
    BindingFlags.Static | 
    BindingFlags.GetProperty);

foreach (PropertyInfo info in resourceProps)

    string name = info.Name;
    object value = info.GetValue(null, null);  // object can be an image, a string whatever
    // do something with name and value

这种方法显然只在RESX文件在当前程序集或项目范围内时可用。否则,使用“脉冲”提供的方法。

此方法的优点是您可以调用为您提供的实际属性,如果您愿意,可以考虑任何本地化。但是,它相当多余,因为通常您应该使用类型安全的直接方法来调用资源的属性。

【讨论】:

当有 ResourceSet 可用时为什么要使用反射? 这也是我想知道的(见最后一段)。只是想展示一种替代方法,但更重要的是,想展示该类是完全可访问的,并且您不需要手动做任何魔术(第一段)。【参考方案5】:
  // Create a ResXResourceReader for the file items.resx.
  ResXResourceReader rsxr = new ResXResourceReader("items.resx");

  // Create an IDictionaryEnumerator to iterate through the resources.
  IDictionaryEnumerator id = rsxr.GetEnumerator();       

  // Iterate through the resources and display the contents to the console.
  foreach (DictionaryEntry d in rsxr) 
  
Console.WriteLine(d.Key.ToString() + ":\t" + d.Value.ToString());
  

 //Close the reader.
 rsxr.Close();

查看链接:microsoft example

【讨论】:

请注意,此类在 System.Windows.Forms 程序集中,如果您使用的是 MVC 应用程序,则不会自动添加【参考方案6】:

您可以使用ResourceManager.GetResourceSet。

【讨论】:

【参考方案7】:

如果您想使用 LINQ,请使用 resourceSet.OfType<DictionaryEntry>()。例如,使用 LINQ 可以让您根据索引 (int) 而不是键 (string) 来选择资源:

ResourceSet resourceSet = Resources.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
foreach (var entry in resourceSet.OfType<DictionaryEntry>().Select((item, i) => new  Index = i, Key = item.Key, Value = item.Value ))

    Console.WriteLine(@"[0] 1", entry.Index, entry.Key);

【讨论】:

【参考方案8】:

对于 nuget 包 System.Resources.ResourceManager (v4.3.0),ResourceSetResourceManager.GetResourceSet 不可用。

使用ResourceReader,正如这篇文章所建议的那样:“C# - Cannot getting a string from ResourceManager (from satellite assembly)”

仍然可以读取资源文件的键/值。

System.Reflection.Assembly resourceAssembly = System.Reflection.Assembly.Load(new System.Reflection.AssemblyName("YourAssemblyName"));
String[] manifests = resourceAssembly.GetManifestResourceNames(); 
using (ResourceReader reader = new ResourceReader(resourceAssembly.GetManifestResourceStream(manifests[0])))

   System.Collections.IDictionaryEnumerator dict = reader.GetEnumerator();
   while (dict.MoveNext())
   
      String key = dict.Key as String;
      String value = dict.Value as String;
   

【讨论】:

【参考方案9】:

简单的读取循环使用此代码

var resx = ResourcesName.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, false, false);

foreach (DictionaryEntry dictionaryEntry in resx)

    Console.WriteLine("Key: " + dictionaryEntry.Key);
    Console.WriteLine("Val: " + dictionaryEntry.Value);

【讨论】:

【参考方案10】:

使用LINQ to SQL:

XDocument
        .Load(resxFileName)
        .Descendants()
        .Where(_ => _.Name == "data")
        .Select(_ => $" _.Attributes().First(a => a.Name == "name").Value - _.Value");

【讨论】:

以上是关于循环遍历 .resx 文件中的所有资源的主要内容,如果未能解决你的问题,请参考以下文章

html 循环遍历文件夹中的所有图像

PHP脚本循环遍历目录中的所有文件?

R:循环遍历目录中的所有文件,应用列替换命令

C语言遍历目录中的文件

访问中的 Vba 代码循环遍历文件夹中的所有 excel 文件,打开、保存和关闭它们

winform中在遍历子文件夹下,循环遍历子文件夹中的文件时提示该子文件夹没有访问权限!怎么解决?