Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从运行时可以使用的资源文件中创建和调用类对象?_C#_Resource Files - Fatal编程技术网

C# 如何从运行时可以使用的资源文件中创建和调用类对象?

C# 如何从运行时可以使用的资源文件中创建和调用类对象?,c#,resource-files,C#,Resource Files,我正在尝试创建消息代码的资源文件。我创建了一个小的控制台示例,当我尝试调用对象时失败 我以这个例子为基础,但我不知道在我试图简化它的过程中遗漏了什么 在代码中,我运行它一次以生成资源文件并将该文件添加到项目中。然后我重新编译以运行调用代码 using System; using System.Reflection; using System.Resources; namespace ResourceDemo { internal class Program { private

我正在尝试创建消息代码的资源文件。我创建了一个小的控制台示例,当我尝试调用对象时失败

我以这个例子为基础,但我不知道在我试图简化它的过程中遗漏了什么

在代码中,我运行它一次以生成资源文件并将该文件添加到项目中。然后我重新编译以运行调用代码

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.
        Generate();
      }
      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);
        Console.ReadKey();
      }
    }

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

        rw.Generate();
      }
    }

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

    [Serializable()]
    public class StatusItem
    {
      public StatusItem(int id, string message)
      {
        Id = id;
        Message = message;
      }

      public int Id { get; set; }
      public string Message { get; set; }
    }
  }
}
使用系统;
运用系统反思;
利用系统资源;
命名空间资源演示
{
内部课程计划
{
私有静态void Main(字符串[]args)
{
bool generateMode=false;
如果(生成模式){
//运行一次并将generate mode设置为true后,添加结果
//在。\bin\x86\Debug文件夹中创建的“StatusItem.resource”
//对该项目的支持。
生成();
}
否则{
//运行时,下一行生成异常:
//mscorlib.dll中发生类型为“System.Resources.MissingManifestResourceException”的未处理异常
//
//其他信息:找不到任何适合指定区域性的资源
//或中性区域性。确保“StatusItems.resources”已正确嵌入或链接
//在编译时放入程序集“ResourceDemo”,或者所有附属程序集都需要
//可加载且完全签名。
StatusItem StatusItem=GetResource(“2”);
WriteLine(“Id:{0}消息:{1}”,statusItem.Id.ToString(),statusItem.Message);
Console.ReadKey();
}
}
公共静态void Generate()
{
StatusItem[]StatusItem=新的StatusItem[4];
//实例化状态对象项。
statusItem[0]=新的statusItem(2,“未找到文件”);
statusItem[1]=新的statusItem(3,“未找到路径”);
statusItem[2]=新的statusItem(4,“打开的文件太多”);
statusItem[3]=新的statusItem(5,“文件访问被拒绝”);
//定义名为StatusItems.resx的资源文件。
正在使用(System.Resources.ResourceWriter rw=new ResourceWriter(@“\StatusItems.Resources”)){
对于(int i=0;i<4;i++){
rw.AddResource(statusItem[i].Id.ToString(),statusItem[i]);
}
rw.Generate();
}
}
公共静态状态项GetResource(字符串键)
{
Assembly=System.Reflection.Assembly.GetExecutionGassembly();
System.Resources.ResourceManager rm=新的System.Resources.ResourceManager(“StatusItems”,Assembly.Load(“ResourceDemo”);
返回(StatusItem)rm.GetObject(键);
}
[可序列化()]
公共类状态项
{
公共状态项(整数id、字符串消息)
{
Id=Id;
消息=消息;
}
公共int Id{get;set;}
公共字符串消息{get;set;}
}
}
}
…并将该文件添加到项目中

怎么做?您正在IDE中添加文件吗?如果是这样,那就行不通了……它将文件视为纯二进制数据;它本身并不被解释为资源数据。您需要在命令行上使用
/resource
,或者在事后使用
al.exe
嵌入.resource文件

如果您希望能够简单地将生成的资源输出添加到项目中,那么您可能希望使用
resxresourceswriter
而不是
resourceswriter
。然后您将得到一个.resx文件,您可以直接将其添加到项目中。VisualStudio将把.resx文件编译成.resources文件,并自动将其正确嵌入

这还具有生成一个可读文件的优点,并且该文件也可以在IDE中打开(尽管功能有限,具体取决于您输入的类型)

注意事项:

  • ResXResourceWriter
    类实际上是在
    System.Windows.Forms.dll
    中定义的,因此您需要在项目中包含对该程序集的引用
  • 写入.resx文件的类型需要能够在编译时被引用,这意味着它们不能位于正在编译的同一程序集中。您需要将它们放在程序引用的单独DLL中
  • .resx文件的
    ResourceManager
    名称将在项目上下文中完全限定。因此,例如,假设您将.resx文件作为顶级文件添加到项目中,则需要加载
    “ResourceDemo.StatusItems”
    ,而不仅仅是
    “StatusItems”
    。如果添加.resx文件“作为链接”,默认情况下,它将在与文件系统对应的文件夹中包含的项目中结束,例如“bin\Debug\StatusItems.resx”。在这种情况下,管理器名称将为
    “ResourceDemo.bin.Debug.StatusItems”

关于最后一点,如果您对名称有任何疑问,可以使用
Assembly.GetManifestResourceNames()
检查编译到程序中的名称。

以下代码使用
ResourceWriter
成功创建了非嵌入式资源,并能够使用字典调用数据对象

从IDE来看,它似乎工作得很好。我试图在命令行中编译这个,但遇到了一些其他问题,最好留给另一个问题来解决。我认为它更多地与comand行编译有关,而不是代码

虽然我可能会采纳Peter Duniho的建议,转而使用
ResxResourceWriter
系列,但我想发布一些专门回答这个问题的内容

using System;
using System.Collections;
using System.Collections.Generic;
using System.Resources;

namespace ResourceDemo
{
  internal class Program
  {
    private const string nameSpace = "ResourceDemo";
    private const string resourceExtension = ".resources";
    private const string resourceFilename = "StatusItems";
    private static IDictionary<string, StatusItem> dictionary;

    private static void Main(string[] args)
    {
      bool generateMode = false;

      if (generateMode) {
        // Only run when a new resource is added
        Generate();
      }
      else {
        // Show the contents of the resource
        EnumerateResource();

        // Make a dictionary so it is usable
        BuildDictionary();

        Console.WriteLine("Look-up items 2, 4, 42 and 3 in dictionary");
        WriteStatusItemToConsole(GetResource("2"));
        WriteStatusItemToConsole(GetResource("4"));
        WriteStatusItemToConsole(GetResource("42"));
        WriteStatusItemToConsole(GetResource("3"));
        Console.ReadKey();
      }
    }

    /// <summary>
    /// Build the working dictionary from the resource file
    /// </summary>
    public static void BuildDictionary()
    {
      Console.WriteLine("Building a look-up dictionary");
      StatusItem statusItem;
      dictionary = new Dictionary<string, StatusItem>();
      ResourceReader res = new ResourceReader(@".\" + resourceFilename + resourceExtension);

      IDictionaryEnumerator dict = res.GetEnumerator();
      while (dict.MoveNext()) {
        statusItem = (StatusItem)dict.Value;
        dictionary.Add(dict.Key.ToString(), statusItem);
      }
      res.Close();
      Console.WriteLine("{0} items written to dictionary.", dictionary.Count.ToString());
      Console.WriteLine();
    }

    /// <summary>
    /// List all the items inside the resource file. Assuming that the
    /// </summary>
    public static void EnumerateResource()
    {
      StatusItem statusItem;
      Console.WriteLine("Resources in {0}", resourceFilename + resourceExtension);
      ResourceReader res = new ResourceReader(@".\" + resourceFilename + resourceExtension);
      IDictionaryEnumerator dict = res.GetEnumerator();
      Console.WriteLine("Dictionary Enumeration ready");
      while (dict.MoveNext()) {
        statusItem = (StatusItem)dict.Value;
        Console.WriteLine("   {0}: '{1}, {2}' (Type: {3})", dict.Key, statusItem.Id.ToString(), statusItem.Message, dict.Value.GetType().Name);
      }
      res.Close();
      Console.WriteLine();
    }

    /// <summary>
    /// Called to create the binary resource file. Needs to be called once.
    /// </summary>
    public static void Generate()
    {
      StatusItem[] statusItem = new StatusItem[4];

      // Instantiate some StatusItem objects.
      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(@".\" + resourceFilename + resourceExtension)) {
        for (int i = 0; i < 4; i++) {
          rw.AddResource(statusItem[i].Id.ToString(), statusItem[i]);
        }
        rw.Generate();
      }
    }

    /// <summary>
    /// Look up StatusItem in dictionary with the given key
    /// </summary>
    /// <param name="key"></param>
    /// <returns></returns>
    public static StatusItem GetResource(string key)
    {
      StatusItem result = null;
      if (dictionary != null) {
        dictionary.TryGetValue(key, out result);
      }
      return result;
    }

    /// <summary>
    /// Write the value of the given item to the console
    /// </summary>
    /// <param name="statusItem"></param>
    public static void WriteStatusItemToConsole(StatusItem statusItem)
    {
      if (statusItem != null) {
        Console.WriteLine("   Id: {0}  Message: {1}", statusItem.Id, statusItem.Message);
      }
      else {
        Console.WriteLine("Null Item");
      }
    }

    /// <summary>
    /// This is our sample class
    /// </summary>
    [Serializable()]
    public class StatusItem
    {
      public StatusItem(int id, string message)
      {
        Id = id;
        Message = message;
      }

      public int Id { get; set; }
      public string Message { get; set; }
    }
  }
}
使用系统;
使用系统集合;
使用System.Collections.Generic;
利用系统资源;
命名空间资源演示
{
内部课程计划
{
私有常量字符串nameSpace=“ResourceDemo”;
私有常量字符串resourceExtension=“.resources”;
私有常量字符串resourceFilename=“StatusItems”;
普里瓦