I have found various articles on getting the system images for a file or even file extension. I have the belows methods which are working for obtaining small 16x16 and large 32x32 images.
// DLL Import
[DllImport("shell32")]
private static extern IntPtr SHGetFileInfo(
string pszPath,
uint dwFileAttributes,
ref SHFILEINFO psfi,
uint cbFileInfo,
uint uFlags);
// Constants/Enums
private const int FILE_ATTRIBUTE_NORMAL = 0x80;
private enum SHGetFileInfoConstants : int
{
SHGFI_ICON = 0x100, // get icon
SHGFI_DISPLAYNAME = 0x200, // get display name
SHGFI_TYPENAME = 0x400, // get type name
SHGFI_ATTRIBUTES = 0x800, // get attributes
SHGFI_ICONLOCATION = 0x1000, // get icon location
SHGFI_EXETYPE = 0x2000, // return exe type
SHGFI_SYSICONINDEX = 0x4000, // get system icon index
SHGFI_LINKOVERLAY = 0x8000, // put a link overlay on icon
SHGFI_SELECTED = 0x10000, // show icon in selected state
SHGFI_ATTR_SPECIFIED = 0x20000, // get only specified attributes
SHGFI_LARGEICON = 0x0, // get large icon
SHGFI_SMALLICON = 0x1, // get small icon
SHGFI_OPENICON = 0x2, // get open icon
SHGFI_SHELLICONSIZE = 0x4, // get shell size icon
SHGFI_PIDL = 0x8, // pszPath is a pidl
SHGFI_USEFILEATTRIBUTES = 0x10, // use passed dwFileAttribute
SHGFI_ADDOVERLAYS = 0x000000020, // apply the appropriate overlays
SHGFI_OVERLAYINDEX = 0x000000040 // Get the index of the overlay
}
public static Icon GetSmallIconForExtension(string extension)
{
// Get the small icon and clone it, as we MUST destroy the handle when we are done.
SHFILEINFO shinfo = new SHFILEINFO();
IntPtr ptr = SHGetFileInfo(
extension,
FILE_ATTRIBUTE_NORMAL,
ref shinfo, (uint)Marshal.SizeOf(shinfo),
(int)(SHGetFileInfoConstants.SHGFI_ICON |
SHGetFileInfoConstants.SHGFI_SMALLICON |
SHGetFileInfoConstants.SHGFI_USEFILEATTRIBUTES |
SHGetFileInfoConstants.SHGFI_TYPENAME));
Icon icon = Icon.FromHandle(shinfo.hIcon).Clone() as Icon;
DestroyIcon(shinfo.hIcon);
return icon;
}
public static Icon GetLargeIconForExtension(string extension)
{
// Get the small icon and clone it, as we MUST destroy the handle when we are done.
SHFILEINFO shinfo = new SHFILEINFO();
IntPtr ptr = SHGetFileInfo(
extension,
FILE_ATTRIBUTE_NORMAL,
ref shinfo, (uint)Marshal.SizeOf(shinfo),
(int)(
SHGetFileInfoConstants.SHGFI_ICON |
SHGetFileInfoConstants.SHGFI_LARGEICON |
SHGetFileInfoConstants.SHGFI_USEFILEATTRIBUTES |
SHGetFileInfoConstants.SHGFI_TYPENAME
));
Icon icon = Icon.FromHandle(shinfo.hIcon).Clone() as Icon;
DestroyIcon(shinfo.hIcon);
return icon;
}
After getting the icon from one of the above methods, I then convert it to a bitmap as follows:
Image image = icon.ToBitmap();
I am getting 32x32 size bitmap images when specifying SHGetFileInfoConstants.SHGFI_LARGEICON
above. Yet, in Windows Explorer you get 48x48 sized icons when you choose to view Medium Icons
.
I would like the 48x48 sized icons (not 32x32). What do I need to do?
The sizes for shell icons are given in the documentation for
SHGetImageList
:So it is expected that when you ask for the "large" icons, you get 32x32. If you want the extralarge icon, you need to get them from the
SHIL_EXTRALARGE
image list.