【问题标题】:How do I get the resource name from the resource object?如何从资源对象中获取资源名称?
【发布时间】:2012-03-04 14:30:29
【问题描述】:

假设我在资源文件夹中添加了一个 exe。现在我怎样才能得到资源的名称(甚至是链接它的完整路径,以便我仍然可以拥有文件名)作为字符串?

我如何从Properties.Resources.myApp 获得string "myApp"。 ToString() 不起作用。如果重要的是嵌入文件以获取名称,我可以。

编辑:我的问题不是专门获取 exe 资源的名称。但这是一种通用方法,它给了我资源的名称!例如,如果我的资源是位图图像怎么办?我需要从Properties.Resources.Lily 打印“Lily”。如何做到这一点? ToString 无论如何都不会工作。

【问题讨论】:

    标签: c# winforms resources .net-2.0


    【解决方案1】:

    使用 Linq 表达式非常简单:

    using System.Linq.Expressions;
    //...
    static string GetNameOf<T>(Expression<Func<T>> property)
    {
      return (property.Body as MemberExpression).Member.Name;
    }
    // Usage:
    var s = GetNameOf(() => Properties.Resources.Lily);
    

    s 应该是Lily

    【讨论】:

    • 当然,如果您使用ResXFileCodeGenerator,这不会返回文件名,而是生成属性的名称(对于您的问题,您似乎这样做了)。如果你想要文件的实际名称,那是不可能的:生成的&lt;resource&gt;Designer.cs 甚至没有对文件名的引用,而.resx 只在编译时有它,而不是在运行时。
    • 非常好。 C# 2.0 的实现会如何?
    • 对不起,我跳过了那个标签......不是以任何简单易用的方式,因为没有 Linq,你不能将属性作为参数传递,它必须通过魔术字符串来完成,并且这意味着您已经有一个具有该名称的字符串。您最好的选择是扩展 ResXFileCodeGenerator 并为每个资源创建一些字符串属性。一种可能的开始方式是this codeproject article(看看底部,它已经为您提供了资源名称作为常量)。
    • This T4 template 作为起点也非常有用,而且比制作自己的自定义工具更容易满足您的需求。
    【解决方案2】:

    我知道这已经很老了,但接受的答案不再一定是最佳答案。从 C# 6.0 开始,您可以使用 nameof(...):

    string resourceName = nameof(Properties.Resources.MyResourceName);
    // resourceName == "MyResourceName"
    

    简单多了!

    【讨论】:

      【解决方案3】:

      使用System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames();,您可以获得项目中所有资源的列表。

      现在如果你想搜索所有的 exe 文件(我猜你只嵌入了一个)使用下面的 sn-p 来获取你的程序集名称。

         var ressourceList = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames();
         var filename = ressourceList.Where(x => x.EndsWith(".exe")).FirstOrDefault();
      

      字符串格式为"YourProgram.YourAssemblyName.exe",因此只需删除该字符串的第一部分,您就有了嵌入的资源文件名。

      编辑:你为什么不枚举你的资源并去掉前导命名空间+尾随文件扩展名?

       // returns just the names
        public static IEnumerable<String> GetEmbeddedResourceNames()
              {
                  var returnList = new List<String>();
                  foreach (var res in Assembly.GetExecutingAssembly().GetManifestResourceNames())
                  {
                      var s = Assembly.GetExecutingAssembly().GetName();
                      returnList.Add(Regex.Replace(res.Replace(s.Name + ".", ""), @"\.[^.]*$", ""));
                  }
                  return returnList;
              }
      

      编辑:

      要按名称获取资源,请使用var prop = Properties.Resources.ResourceManager.GetObject("YourRessourceNameWithoutExtension");

      【讨论】:

      • 这是一种解决方法。不是我所问的解决方案。我将编辑我的问题。
      • 这再次,虽然更接近,但给出了资源名称列表,现在我如何知道哪个文件对应于哪个?如果我嵌入了多个 exe 文件怎么办。我的要求是 C# 2.0。
      • 您不能拥有 2 个同名资源(新资源将取代旧资源) - 现在我应该如何知道您想要哪个资源?如果你有 2 个 exe 文件 App.exe 和 App1.exe,你作为程序员必须以某种方式确定使用哪个,对吧?
      • 这正是我要说的,我将来可能会有 App1 和 App2。作为一名程序员,我知道该使用哪个,这是我的问题。我知道通过调用 GetName(Properties.Resources.App1) 之类的东西来使用哪个。我知道要使用哪个,因为我有 Properties.Resources.App1。函数的定义是我所缺少的:(
      • 检查我的编辑 - 您可以使用 ResourceManager 按名称获取资源。 (不需要文件扩展名,这就是我拒绝编辑的原因)
      【解决方案4】:

      你的意思是你想要组装吗?这里有一个小代码 sn-p 可以让你从一个目录中获取所有 exe 文件:

      foreach (string fileName in Directory.GetFiles("./Files"))
      {
          FileInfo fileInfo = new FileInfo(fileName);
      
          if (fileInfo.Extension.Equals(".exe"))
          {
              Assembly pluginAssembly = Assembly.LoadFrom(fileName);
      
              //...
          }
      }
      

      【讨论】:

      • 这是一种解决方法。不是我所问的解决方案。我将编辑我的问题。
      【解决方案5】:

      当您在项目资源中嵌入一些文件时,它将在构建项目时嵌入到您的可执行文件中,因此它不会与您的项目可执行文件分开存在,它也不存在于您的硬盘驱动器上。 所以如果你想要这个 myApp.exe 在你的项目文件夹中,把它放在项目文件夹中然后去

      • 视觉工作室>>
      • 解决方案浏览器>>
      • 点击左上角显示所有文件>>
      • MyApp.exe 将可见 >>
      • 右键myApp.exe点击包含在项目中>>
      • 按 F4 显示属性页并聚焦 >>
      • 将复制到输出目录设置为“始终复制”

      现在如果您想要 myApp.exe 的路径,请使用:

      System.IO.Path.Combine(Application.StartupPath, "myApp.exe");
      

      更新你应该硬编码“myApp”,因为如果你去定义:

      Properties.Resources.myApp 
      

      你会看到:

      internal static byte[] myApp {
              get {
                  object obj = ResourceManager.GetObject("myApp", resourceCulture);
                  return ((byte[])(obj));
              }
          }
      

      它是硬编码的!!!!

      【讨论】:

      • 这根本不是我的问题,不在任何地方!请参阅我没有将我的 exe 作为单独的项目添加,而是将其添加到资源中,以便将来我可以最终嵌入它。我的问题是如何以编程方式从资源项中获取字符串名称。如何在运行时知道“myApp”的名称是什么?我不能只硬编码“myapp.exe”
      • 当你使用资源时没有 FULLPATH,因为它不在硬盘驱动器中......无论如何都可以解释你想要什么
      • 我只是添加而不是嵌入时它不是在硬盘中吗?我也不需要完整路径。只需文件名即可。
      • 我认为你没有得到它。它可能在内部进行了硬编码,但我如何知道其中的价值是什么?例如,我将设计器的 textbox.AccessibleName 设置为 ABC。现在我可以从文本框的 AccessibleName 属性中获取值 ABC。但它仍然是代码中硬编码的字符串值。如何获得代表字符串但不是编码为“sdsdsd”之类的代码部分??
      • 换句话说,如果明天嵌入的 exe 名称不是 myApp.exe,我该如何打开它?
      猜你喜欢
      • 1970-01-01
      • 2015-10-09
      • 2015-01-30
      • 1970-01-01
      • 2011-03-29
      • 1970-01-01
      • 2012-12-12
      相关资源
      最近更新 更多