Find an application’s icon with WinAPI
December 18, 2007 – 12:47 am Tags: C#I was working on some C# code today, and had to figure out how to find a specific application’s icon.
There’s a lot of basic information on this, including messages like WM_GETICON in MSDN, but it just wouldn’t work.
One of the reasons I like C# is how it makes doing things easy, and it’s also very easy to figure out how to do something that you haven’t done before with it.
The thing I dislike in C/C++ is that it’s so damn difficult to figure out at times, especially some things, such as this one. Sure, there’s a lot of documentation available about the Windows API, but how do I know where to look?
I did eventually figure out how to do this, so here’s the solution for anyone else who might be struggling with the same
public Icon GetAppIcon(IntPtr hwnd) { IntPtr iconHandle = SendMessage(hwnd,WM_GETICON,ICON_SMALL2,0); if(iconHandle == IntPtr.Zero) iconHandle = SendMessage(hwnd,WM_GETICON,ICON_SMALL,0); if(iconHandle == IntPtr.Zero) iconHandle = SendMessage(hwnd,WM_GETICON,ICON_BIG,0); if (iconHandle == IntPtr.Zero) iconHandle = GetClassLongPtr(hwnd, GCL_HICON); if (iconHandle == IntPtr.Zero) iconHandle = GetClassLongPtr(hwnd, GCL_HICONSM); if(iconHandle == IntPtr.Zero) return null; Icon icn = Icon.FromHandle(iconHandle); return icn; }
The constants and other methods used:
public const int GCL_HICONSM = -34; public const int GCL_HICON = -14; public const int ICON_SMALL = 0; public const int ICON_BIG = 1; public const int ICON_SMALL2 = 2; public const int WM_GETICON = 0x7F; public static IntPtr GetClassLongPtr(IntPtr hWnd, int nIndex) { if (IntPtr.Size > 4) return GetClassLongPtr64(hWnd, nIndex); else return new IntPtr(GetClassLongPtr32(hWnd, nIndex)); } [DllImport("user32.dll", EntryPoint = "GetClassLong")] public static extern uint GetClassLongPtr32(IntPtr hWnd, int nIndex); [DllImport("user32.dll", EntryPoint = "GetClassLongPtr")] public static extern IntPtr GetClassLongPtr64(IntPtr hWnd, int nIndex); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);

3 Responses to “Find an application’s icon with WinAPI”
Thanks for this, was just looking into doing it myself and was trying out the GetClass based methods. Is there a particular reason for the order of those methods to get the iconHandle in GetAppIcon?
By James on Jan 24, 2008
No particular reason there. It might be possible to optimize it a bit if you were to test which call returns the icon with the highest likelihood and moved that as the first.
By Jani Hartikainen on Jan 24, 2008
Awesome tip. Thanks! Now I can’t figure out why the icon keeps saving in black and white, but I’ll keep working on that…
By Jon on Jun 30, 2008