【问题标题】:How can I discover the "path" of an embedded resource?如何发现嵌入式资源的“路径”?
【发布时间】:2010-09-06 20:46:09
【问题描述】:

我将 PNG 作为嵌入资源存储在程序集中。在同一个程序集中,我有一些这样的代码:

Bitmap image = new Bitmap(typeof(MyClass), "Resources.file.png");

名为“file.png”的文件存储在“Resources”文件夹中(在 Visual Studio 中),并被标记为嵌入式资源。

代码失败,异常提示:

在 MyNamespace.MyClass 类中找不到资源 MyNamespace.Resources.file.png

我有相同的代码(在不同的程序集中,加载不同的资源)可以工作。所以我知道这项技术是合理的。我的问题是我最终花了很多时间试图找出正确的路径是什么。如果我可以简单地查询(例如,在调试器中)程序集以找到正确的路径,那会省去很多麻烦。

【问题讨论】:

    标签: c# .net resources


    【解决方案1】:

    这将为您提供所有资源的字符串数组:

    System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames();
    

    【讨论】:

    • 嘿,我怎样才能获得资源文件夹路径以将其分配为我的嵌入式 http 服务器的根目录?
    【解决方案2】:

    我发现自己每次都忘记如何执行此操作,所以我只是将我需要的两个单行代码包装在一个小课堂中:

    public class Utility
    {
        /// <summary>
        /// Takes the full name of a resource and loads it in to a stream.
        /// </summary>
        /// <param name="resourceName">Assuming an embedded resource is a file
        /// called info.png and is located in a folder called Resources, it
        /// will be compiled in to the assembly with this fully qualified
        /// name: Full.Assembly.Name.Resources.info.png. That is the string
        /// that you should pass to this method.</param>
        /// <returns></returns>
        public static Stream GetEmbeddedResourceStream(string resourceName)
        {
            return Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
        }
    
        /// <summary>
        /// Get the list of all emdedded resources in the assembly.
        /// </summary>
        /// <returns>An array of fully qualified resource names</returns>
        public static string[] GetEmbeddedResourceNames()
        {
            return Assembly.GetExecutingAssembly().GetManifestResourceNames();
        }
    }
    

    【讨论】:

      【解决方案3】:

      我猜你的类在不同的命名空间中。解决这个问题的规范方法是使用资源类和强类型资源:

      ProjectNamespace.Properties.Resources.file
      

      使用 IDE 的资源管理器添加资源。

      【讨论】:

      • 你说得对,我的班级在不同的命名空间中。似乎 Resources 文件夹位于项目配置中指定为默认命名空间的命名空间下,由于各种原因,它不是此类所属的命名空间。我怀疑您完全使用不同的方法也是正确的,但由于我需要与遗留代码保持一致,这超出了我的控制范围。
      • 这会抓取资源 - 而不是文件路径。
      • @UchihaItachi 这就是为什么我明确提供这个答案作为解决潜在问题的另一种(并且可以说是规范的)方法,而不是逐字回答问题(已经有答案无论如何)。
      • @UchihaItachi 这个问题还讲述了提问者面临的问题,他的方法是什么以及他到目前为止是如何尝试的。尽管鲁道夫没有直接回答这个问题,但他提出了另一种解决问题的方法。在大多数情况下,这种方法更方便、更安全、更常见。这个答案很有帮助。我只是不明白为什么你必须试图关闭人们的答案。投票赞成/反对投票按钮是有原因的。
      【解决方案4】:

      我使用以下方法抓取嵌入资源:

      protected static Stream GetResourceStream(string resourcePath)
      {
          Assembly assembly = Assembly.GetExecutingAssembly();
          List<string> resourceNames = new List<string>(assembly.GetManifestResourceNames());
      
          resourcePath = resourcePath.Replace(@"/", ".");
          resourcePath = resourceNames.FirstOrDefault(r => r.Contains(resourcePath));
      
          if (resourcePath == null)
              throw new FileNotFoundException("Resource not found");
      
          return assembly.GetManifestResourceStream(resourcePath);
      }
      

      然后我用项目中的路径调用它:

      GetResourceStream(@"DirectoryPathInLibrary/Filename");
      

      【讨论】:

        【解决方案5】:

        资源的名称是名称空间加上文件路径的“伪”名称空间。 “伪”名称空间由子文件夹结构使用 \(反斜杠)而不是 . (点)。

        public static Stream GetResourceFileStream(String nameSpace, String filePath)
        {
            String pseduoName = filePath.Replace('\\', '.');
            Assembly assembly = Assembly.GetExecutingAssembly();
            return assembly.GetManifestResourceStream(nameSpace + "." + pseduoName);
        }
        

        以下调用:

        GetResourceFileStream("my.namespace", "resources\\xml\\my.xml")
        

        将返回位于命名空间中文件夹结构 resources\xml 中的 my.xml 流:my.namespace。

        【讨论】:

        • 文件夹中的破折号 ('-') 也替换为下划线 ('_')。可能还有其他符号。我想看看编译器是怎么做的,所以我们可以使用相同的方法。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-02
        • 1970-01-01
        • 2011-10-30
        • 1970-01-01
        • 2013-08-02
        相关资源
        最近更新 更多