I use Win32 SHGetFileInfo to get a handle to the icon belonging to a certain file. There are a lot of descriptions how to do this, also on stackoverflow, for instance: Get i
Addition by OP. There is an error in this answer. Because of all the comments it became harsh to see the forest through the trees. Hence I decided to edit this answer. (Sorry if I offended someone)
The .net source code is online: http://referencesource.microsoft.com/#System.Drawing/commonui/System/Drawing/Icon.cs,81a28d20524554ae
Take a look at Icon.FromHandle:
public static Icon FromHandle(IntPtr handle)
{
IntSecurity.ObjectFromWin32Handle.Demand();
return new Icon(handle);
}
internal Icon(IntPtr handle) : this(handle, false)
{
}
internal Icon(IntPtr handle, bool takeOwnership)
{
if (handle == IntPtr.Zero)
{
throw new ArgumentException(SR.GetString(SR.InvalidGDIHandle,
(typeof(Icon)).Name));
}
this.handle = handle;
this.ownHandle = takeOwnership;
}
Note that after Icon.FromHandle ownHandle is false.
Let's look at Dispose:
void Dispose(bool disposing)
{
if (handle != IntPtr.Zero)
{
DestroyHandle();
}
}
internal void DestroyHandle()
{
if (ownHandle)
{
SafeNativeMethods.DestroyIcon(new HandleRef(this, handle));
handle = IntPtr.Zero;
}
}
Conclusion: After Icon.FromHandle, the field ownHandle is false, and thus Dispose / FromHandle won't call DestroyIcon
Therefore: if you create an Icon using Icon.FromHandle you'll have to Dispose() the Icon as well as call DestroyIcon, just as the remarks section says