开发者

Get PNG Image From Native Win32 Resource In .NET

开发者 https://www.devze.com 2023-04-05 15:26 出处:网络
A DLL file contains some images inside PNG resource type. I can view the PNG images in softwares like Resource Hacker, Anolis Re开发者_运维知识库sourcer & Resource Tuner. Check this screenshot of

A DLL file contains some images inside PNG resource type.

I can view the PNG images in softwares like Resource Hacker, Anolis Re开发者_运维知识库sourcer & Resource Tuner. Check this screenshot of Anolis Resourcer for more details:

Get PNG Image From Native Win32 Resource In .NET

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.


// 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.


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


A PNG image is not one of the standard Win32 resource types. It is usually embedded as a binary blob with the named resource type "PNG", although that's not guaranteed. By far the easiest way to figure this out is by opening the file with Visual Studio's File + Open + File command. You'll see the embedded resources organized in a tree, hopefully with a descriptive name, right-click a candidate and select Export to save it to disk.

Doing this programmatically requires a lot of gritty pinvoke. It is tricky because both the resource type and the resource ID can be either a string or an IntPtr so you'll need 4 overloads for FindResource. In order, you'll need LoadLibraryEx() to load the file without executing any of its code. FindResource to get a handle to the resource. SizeOfResource to know how large it is. LoadResource + LockResource to get a pointer to the resource data. Marshal.Copy() to copy the resource data into a byte[]. Clean up with FreeResource and FreeLibrary.

0

精彩评论

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

关注公众号