.resxファイル内のすべてのリソースをループする


125

.resxC#でファイル内のすべてのリソースをループする方法はありますか?


2
RESXファイルがプロジェクトの内部にあるのか、別のRESXファイルを読み取るのか(または必要にするのか)、別のアセンブリからRESXを読み取るのかについて詳しく説明できますか?
Abel

回答:


243

グローバリゼーションが考慮されるようにするには、常にリソースマネージャーを使用し、ファイルを直接読み取らないでください。

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;
}

12
MyResourceClassを宣言するためにこの行が必要であることを理解するのに少し時間がかかりました。ResourceManager MyResourceClass = new ResourceManager("Resources.ResourceFileName", System.Reflection.Assembly.Load("App_GlobalResources"));
JoeFletch 2012

6
@JoeFletch:この行は必要ありません。コードはリソースファイルを直接呼び出します。例:PageList.resxという名前のファイルがあり、次のように呼び出します。ResourceSet resourceSet = PageList.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture、true、true);
ガブリエル

@Gabriel、更新ありがとうございます!これを確認するには、コードに戻る必要があります。
JoeFletch 2013

3
ジョーフレッチのラインは実際に私を助けました。私は別のC#プロジェクトにあるresxを持っていたので、彼のラインにより、そのdllアセンブリを呼び出して、その方法でリソースを読み込むことができました。また、コードにPageListを含めようとすると、PageList.ResourceManagerに対して「PageListにはResourceManagerの定義が含まれていない」というエラーがスローされました。そして最後に、string resourceKey = entry.Keyがエラーをスローし、代わりに「object resourceKey = entry.Key」を使用しました
sksallaj

2
リソースで実際にカルチャが定義されているかどうかに応じて、CultureInfo.InvariantCultureに切り替える必要があります。ここでは、WinFormsアプリではなく、ライブラリのリソースを使用していました。
イスラエルロペス

26

私のブログでそれについてブログに書いてあります :)ショートバージョンは、リソースの完全な名前を見つけることです(あなたがすでにそれらを知っているのでない限り):

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クラスの他の静的メソッドのいくつかを使用して、別のアセンブリオブジェクトを取得します。それが役に立てば幸い :)


「Resource」というフォルダにないリソースを列挙できますか?プロジェクトにあるすべてのリソースイメージを「イメージ」というフォルダーに列挙したいと思います。
Simon Bosley

それがどこにあるかは気にしないでしょうか?試して?
Svish

1
SQLファイルをインポートするためのフォルダーにファイルがあり、これは完全に機能しました。ファイルを読み取れるようにストリームから文字列への変換を追加しましたが、問題はありませんでした。
ErocM 2016

9

ResXResourceReaderクラスを使用

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());
}

7
  // 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();

リンクを参照してください:マイクロソフトの例


4
このクラスはSystem.Windows.Formsアセンブリ内にあり、MVCアプリを使用している場合は自動的に追加されないことに注意してください
Rob Scott

6

リソース.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ファイルが現在のアセンブリまたはプロジェクトのスコープ内にある場合にのみ使用できます。それ以外の場合は、「pulse」によって提供されるメソッドを使用します。

このメソッドの利点は、必要に応じてローカリゼーションを考慮して、提供されている実際のプロパティを呼び出すことです。ただし、通常はリソースのプロパティを呼び出すタイプセーフなダイレクトメソッドを使用する必要があるため、かなり冗長です。


2
利用可能なResourceSetがあるときにリフレクションを使用する理由
Oundless

それも私が不思議に思うことです(最後の段落を参照)。代わりのメソッドを示したかっただけですが、さらに重要なのは、クラスが完全にアクセス可能になり、手作業でマジックを行う必要がないことを示したかったことです(最初の段落)。
Abel


1

LINQを使用する場合は、を使用しますresourceSet.OfType<DictionaryEntry>()。LINQを使用すると、たとえば、キー(文字列)ではなくインデックス(int)に基づいてリソースを選択できます。

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);
}

1

nugetパッケージSystem.Resources.ResourceManager(v4.3.0)では、ResourceSetおよびResourceManager.GetResourceSetは使用できません。

ResourceReaderこの投稿で提案されているように、「C#-ResourceManagerから(サテライトアセンブリから)文字列を取得できません

リソースファイルのキー/値を読み取ることは引き続き可能です。

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;
   }
}


0

単純な読み取りループはこのコードを使用します

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

foreach (DictionaryEntry dictionaryEntry in resx)
{
    Console.WriteLine("Key: " + dictionaryEntry.Key);
    Console.WriteLine("Val: " + dictionaryEntry.Value);
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.