开发者

Where are my resources hidden?

I have a program that contains a number of icons in an "Icons" folder (which are included in the project with Build Act开发者_如何转开发ion=Resource).

In XAML I can access these icons with code such as <Image Source="../Icons/name.png"/> (".." because the XAML is in a different subfolder); however I want to use the same image in some WinForms code in the same project. Unfortunately,

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

returns null and

GetType().Assembly.GetManifestResourceNames()

only lists a bunch of *.resources files (one for each .resx and one called *.g.resources). So how am I supposed to get the image stream?


I assumed that since I included the images directly in my project that I could directly read them. But thanks to Jack's answer I was able to figure out that they are hidden inside a "resource file" named "ProgramName.g.resources" inside the assembly. To read the image it is necessary to load the resource file first, then search for the image file within the resource file.

ResourceSet.GetObject is case-sensitive, but the image path and filename were converted to lowercase for some reason, so I call ToLowerInvariant on the path name. Here's my solution:

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

I'm not sure how expensive it is to construct a ResourceSet. If it's expensive, and you want to retrieve multiple resources, then you should cache and re-use the ResourceSet object.

Please leave a message if you know why the images end up inside the *.g.resources file. Did Visual Studio choose this name? Is it theoretically possible to put images directly in an assembly, or can assemblies only contain "ResourceSets"?


you can find some help from:

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

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

In the first link, you can find a way to get the resource that is type of UnmanagedMemoryStream, then you should find a way to convert the stream to the type you want.

Hope it helps you!


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜