Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get PNG Image From Native Win32 Resource In .NET

A DLL file contains some images inside PNG resource type.

I can view the PNG images in softwares like Resource Hacker, Anolis Resourcer & Resource Tuner. Check this screenshot of Anolis Resourcer for more details:

Can someone tell me how do I get the PNG image no. 5220 from the DLL file and put it inside a PictureBox? I don't think APIs like LoadImage or LoadBitmap will work.

like image 947
Elmo Avatar asked Sep 16 '11 17:09

Elmo


2 Answers

// get the assembly containing the image
var assembly = Assembly.GetExecutingAssembly();

// set the picturebox image to read the embedded resource
pictureBox1.Image = Image.FromStream(
    assembly.GetManifestResourceStream("AssemblyName.test.png")
);

where AssemblyName.test.png is the fully qualified name of the embedded resource inside the assembly.


UPDATE:

It seems that you are trying to extract resources from a native assembly. You may take a look at the following article which illustrates how this could be done using P/Invoke.

like image 139
Darin Dimitrov Avatar answered Oct 21 '22 08:10

Darin Dimitrov


The link that Darin posted (which has consequently been marked as the answer) does not contain functional code. I've evaluated the code posted there (http://khason.net/blog/how-to-load-unmanaged-native-resources-from-managed-c-code/) and found that it does not work properly for any Bitmap image embedded in any win32 dll as a bitmap resource.

Additionally, Hans Passant leaves off a myriad of steps effectively rendering his post useless.

The only somewhat close solution that I've been able to find comes from an article written in 2004 for the XP Theme dll junk. You can find the 'GetResourcePNG' method in ThemeManager.cs here http://www.codeproject.com/KB/miscctrl/XPTaskBar.aspx

However, it should be noted that I've been having a lot of difficulty with this method, as the call to bitmap.RotateFlip(RotateFlipType.Rotate180FlipX); causes memory issues when trying to access pngs within authui.dll on my system

Update:

I've found the code listed here (http://www.vbaccelerator.com/home/NET/Code/Controls/Explorer_Bar/ExplorerBar_Control_Source_Code.asp) to be by far the most functional, produce the fewest errors and produces the fastest results. The code is written in c# even though the domain name would indicate otherwise. Using the two classes; ImageUtility and ResourceLibrary, you can easily pull a PNG out of a standard, non-.net resource library/dll:

    public static Bitmap GetStandardResourceBitmap(String dllName, String resourceId) {
        Bitmap result = null;

        using (ResourceLibrary library = new ResourceLibrary() { Filename = dllName }) {
            IntPtr hDib = library.GetResource(resourceId, ResourceLibrary.ImageType.IMAGE_BITMAP, ResourceLibrary.ImageLoadOptions.LR_CREATEDIBSECTION);
            if (!hDib.Equals(IntPtr.Zero)) {
                result = ImageUtility.DibToBitmap(hDib);
                ImageUtility.DeleteObject(hDib);
            }
        }

        return result;
    }

I chose to have resourceId in my method a String, only because it doesn't require an overload and using numbered resource Ids is as simple as prepending a '#'.

GetStandardResourceBitmap("shell32.dll", "#632");

Cheers

like image 22
shellscape Avatar answered Oct 21 '22 06:10

shellscape