Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A Generic Error occurred in GDI+ when calling Bitmap.GetHicon

Tags:

c#

gdi+

Why I'm getting "A Generic Error occurred in GDI+" Exception ?

IntPtr hicon = tempBitmap.GetHicon();             
Icon bitmapIcon = Icon.FromHandle(hicon);            
return bitmapIcon;

The error occurred when my application has been running for more than 30 minutes. (I am converting System.Drawing.Bitmap to System.Drawing.Icon every second)

enter image description here

like image 669
Mohammad Reza Taesiri Avatar asked Aug 19 '12 12:08

Mohammad Reza Taesiri


2 Answers

That's caused by a handle leak. You can diagnose the leak with TaskMgr.exe, Processes tab. View + Select Columns and tick Handles, GDI Objects and USER Objects. Observe these columns while your program is running. If my guess is right, you'll see the GDI Objects value for your process steadily climbing. When it reaches 10,000 then the show is over, Windows refuses to allow you to leak more objects.

The Remarks section for Icon.FromHandle says:

When using this method you must dispose of the resulting icon using the DestroyIcon method in the Win32 API to ensure the resources are released.

That's good advice but usually pretty painful to do. You can find a hack to force the Icon object to own the handle, and automatically release it, in this answer. Relevant code is after the "Invoke private Icon constructor" section.

like image 94
Hans Passant Avatar answered Sep 21 '22 10:09

Hans Passant


You probably need to clean up your icon.

The example for Icon.FromHandle on MSDN shows you how. Unfortunately it requires PInvoke:

[System.Runtime.InteropServices.DllImport("user32.dll", CharSet=CharSet.Auto)]
extern static bool DestroyIcon(IntPtr handle);

And then inside your method:

IntPtr hicon = tempBitmap.GetHicon();             
Icon bitmapIcon = Icon.FromHandle(hicon);        

// And then somewhere later...
DestroyIcon(bitMapIcon.Handle);    

If you call DestoryIcon before you use it, it may not work. For my own particular instance of this problem, I ended up keeping a reference to the last icon I created and then called DestroyIcon on it the next time I generated an icon.

like image 26
Jeff B Avatar answered Sep 19 '22 10:09

Jeff B