Skip to content

Instantly share code, notes, and snippets.

@xv
Created November 6, 2020 10:52
Show Gist options
  • Save xv/c97cbc8778dffc4ebefffd9b86b78795 to your computer and use it in GitHub Desktop.
Save xv/c97cbc8778dffc4ebefffd9b86b78795 to your computer and use it in GitHub Desktop.
Simple method to retrieve the 16x16 shell file icon using SHFILEINFO structure.
internal const uint FILE_ATTRIBUTE_NORMAL = 0x80;
[Flags]
internal enum SHGetFileInfoFlags
{
SHGFI_LARGEICON = 0x0,
SHGFI_SMALLICON = 0x1,
SHGFI_OPENICON = 0x2,
SHGFI_SHELLICONSIZE = 0x4,
SHGFI_PIDL = 0x8,
SHGFI_USEFILEATTRIBUTES = 0x10,
SHGFI_ADDOVERLAYS = 0x20,
SHGFI_OVERLAYINDEX = 0x40,
SHGFI_ICON = 0x100,
SHGFI_DISPLAYNAME = 0x200,
SHGFI_TYPENAME = 0x400,
SHGFI_ATTRIBUTES = 0x800,
SHGFI_ICONLOCATION = 1000,
SHGFI_EXETYPE = 0x2000,
SHGFI_SYSICONINDEX = 0x4000,
SHGFI_LINKOVERLAY = 0x8000,
SHGFI_SELECTED = 0x10000,
SHGFI_ATTR_SPECIFIED = 0x20000
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal struct SHFILEINFO
{
private const int MAX_PATH = 256, FTYPE_SIZE = 80;
internal IntPtr hIcon;
internal int iIcon;
internal uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
internal string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = FTYPE_SIZE)]
internal string szTypeName;
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DestroyIcon(IntPtr hIcon);
[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
internal static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes,
ref SHFILEINFO psfi, uint cbFileInfo,
SHGetFileInfoFlags uFlags);
public static Icon GetShellFileIcon(string filename, bool linkOverlay)
{
var sfi = new SHFILEINFO();
var flags = SHGetFileInfoFlags.SHGFI_ICON |
SHGetFileInfoFlags.SHGFI_SMALLICON |
SHGetFileInfoFlags.SHGFI_USEFILEATTRIBUTES;
if (linkOverlay)
flags |= SHGetFileInfoFlags.SHGFI_LINKOVERLAY;
Icon ico;
try
{
SHGetFileInfo(filename, FILE_ATTRIBUTE_NORMAL, ref sfi, (uint)Marshal.SizeOf(sfi), flags);
ico = (Icon)Icon.FromHandle(sfi.hIcon).Clone();
}
finally
{
DestroyIcon(sfi.hIcon);
}
return ico;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment