【问题标题】:Where are my resources hidden?我的资源隐藏在哪里?
【发布时间】:2011-07-16 04:27:36
【问题描述】:

我有一个程序,它在“图标”文件夹中包含许多图标(这些图标包含在 Build Action=Resource 的项目中)。

在 XAML 中,我可以使用 <Image Source="../Icons/name.png"/> 等代码访问这些图标(“..”,因为 XAML 位于不同的子文件夹中);但是我想在同一个项目的一些 WinForms 代码中使用相同的图像。不幸的是,

GetType().Assembly.GetManifestResourceStream("Icons/name.png");

返回null

GetType().Assembly.GetManifestResourceNames()

只列出一堆 *.resources 文件(每个 .resx 一个,一个称为 *.g.resources)。那么我应该如何获取图像流呢?

【问题讨论】:

    标签: .net resources


    【解决方案1】:

    我认为由于我在项目中直接包含了图像,因此我可以直接阅读它们。但是由于杰克的回答,我能够弄清楚它们隐藏在程序集中名为“ProgramName.g.resources”的“资源文件”中。读取图片需要先加载资源文件,然后在资源文件中搜索图片文件。

    ResourceSet.GetObject 区分大小写,但是由于某种原因,图像路径和文件名被转换为小写,所以我在路径名上调用ToLowerInvariant。这是我的解决方案:

    private Stream GetGlobalResourceByPath(Assembly assembly, string path)
    {
        string name = assembly.GetManifestResourceNames().Where(n => n.EndsWith(".g.resources")).First();
        Stream outerStream = assembly.GetManifestResourceStream(name);
        ResourceSet resources = new ResourceSet(outerStream);
        return resources.GetObject(path.ToLowerInvariant()) as UnmanagedMemoryStream;
    }
    

    我不确定构建ResourceSet 的成本有多大。如果它很昂贵,并且您想要检索多个资源,那么您应该缓存并重用 ResourceSet 对象。

    如果您知道为什么图片会出现在 *.g.resources 文件中,请留言。 Visual Studio 是否选择了这个名称?理论上可以直接把图片放到一个程序集中,还是程序集只能包含“ResourceSets”?

    【讨论】:

    • 当我想包含图像、javascript、css 等时,我没有为资源文件烦恼。我将它们直接放在项目中,构建操作为Embedded Resource,因此不必乱搞资源集。
    【解决方案2】:

    您可以通过以下方式获得帮助:

    http://blog.devarchive.net/2007/12/net-assembly-resource-browser-test.html

    http://msdn.microsoft.com/en-us/library/system.io.unmanagedmemorystream.aspx

    在第一个链接中,您可以找到一种方法来获取类型为 UnmanagedMemoryStream 的资源,然后您应该找到一种方法将流转换为您想要的类型。

    希望对你有帮助!

    
    foreach (var resourceName in ThemeList.Current.GetType().Assembly.GetManifestResourceNames())
    {
                    var resourceStream = GetType().Assembly.GetManifestResourceStream(resourceName);
                    ResourceSet resources = new ResourceSet(resourceStream);
                    IDictionaryEnumerator enu = resources.GetEnumerator();
                    while (enu.MoveNext())
                    {
                        Console.WriteLine(enu.Key); // Key is the resource name and Value is UnmanagedMemoryStream
                    }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-04-26
      • 2021-02-21
      • 2015-11-07
      • 2019-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-21
      • 2010-11-17
      相关资源
      最近更新 更多