How to extract overlay icon or its path from file in windows
See the question and my original answer on StackOverflowYou can use IImageList::GetOverlayImage method, here is a full sample:
static void Main()
{
var info = new SHFILEINFO();
SHGetFileInfo(@"c:\temp\my.lnk", FileAttributes.Normal, ref info, Marshal.SizeOf(info), SHGFI.SHGFI_ICON | SHGFI.SHGFI_OVERLAYINDEX);
DestroyIcon(info.hIcon); // file + overlay, we don't need it
// per doc: upper eight bits of the iIcon member
var overlayIndex = info.iIcon >> 24; // overlayIndex >= 1 and <= 15 (system limit)
if (overlayIndex > 0)
{
// change size of required icon with SHIL parameter (JUMBO is 256x256)
SHGetImageList(SHIL.SHIL_LARGE, typeof(IImageList).GUID, out var list);
if (list != null)
{
list.GetOverlayImage(overlayIndex, out var imageIndex);
if (imageIndex >= 0)
{
list.GetIcon(imageIndex, ILD.ILD_NORMAL, out var hicon);
if (hicon != IntPtr.Zero)
{
using (var bmp = Bitmap.FromHicon(hicon))
{
bmp.Save("Overlay" + overlayIndex + ".png");
DestroyIcon(hicon);
}
}
}
}
}
}
[DllImport("shell32", CharSet = CharSet.Unicode)]
public static extern IntPtr SHGetFileInfo(string pszPath, FileAttributes dwFileAttributes, ref SHFILEINFO psfi, int cbSizeFileInfo, SHGFI uFlags);
[DllImport("shell32")]
private static extern int SHGetImageList(SHIL iImageList, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IImageList ppv);
[DllImport("user32")]
public static extern bool DestroyIcon(IntPtr handle);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SHFILEINFO
{
public IntPtr hIcon;
public int iIcon;
public int dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
}
public enum SHIL
{
SHIL_LARGE = 0,
SHIL_SMALL = 1,
SHIL_EXTRALARGE = 2,
SHIL_SYSSMALL = 3,
SHIL_JUMBO = 4,
}
[Flags]
public enum ILD
{
ILD_NORMAL = 0x00000000,
ILD_TRANSPARENT = 0x00000001,
ILD_MASK = 0x00000010,
ILD_IMAGE = 0x00000020,
ILD_ROP = 0x00000040,
ILD_BLEND25 = 0x00000002,
ILD_BLEND50 = 0x00000004,
ILD_OVERLAYMASK = 0x00000F00,
ILD_PRESERVEALPHA = 0x00001000,
ILD_SCALE = 0x00002000,
ILD_DPISCALE = 0x00004000,
ILD_ASYNC = 0x00008000,
ILD_SELECTED = ILD_BLEND50,
ILD_FOCUS = ILD_BLEND25,
ILD_BLEND = ILD_BLEND50,
}
[ComImport, Guid("46eb5926-582e-4017-9fdf-e8998daa0950"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public partial interface IImageList
{
[PreserveSig]
int Add(IntPtr hbmImage, IntPtr hbmMask, out int pi);
[PreserveSig]
int ReplaceIcon(int i, IntPtr hicon, out int pi);
[PreserveSig]
int SetOverlayImage(int iImage, int iOverlay);
[PreserveSig]
int Replace(int i, IntPtr hbmImage, IntPtr hbmMask);
[PreserveSig]
int AddMasked(IntPtr hbmImage, uint crMask, out int pi);
[PreserveSig]
int Draw(ref int pimldp);
[PreserveSig]
int Remove(int i);
[PreserveSig]
int GetIcon(int i, ILD flags, out IntPtr picon);
[PreserveSig]
int GetImageInfo(int i, out int pImageInfo);
[PreserveSig]
int Copy(int iDst, [MarshalAs(UnmanagedType.IUnknown)] object punkSrc, int iSrc, uint uFlags);
[PreserveSig]
int Merge(int i1, [MarshalAs(UnmanagedType.IUnknown)] object punk2, int i2, int dx, int dy, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);
[PreserveSig]
int Clone([MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);
[PreserveSig]
int GetImageRect(int i, IntPtr prc);
[PreserveSig]
int GetIconSize(out int cx, out int cy);
[PreserveSig]
int SetIconSize(int cx, int cy);
[PreserveSig]
int GetImageCount(out int pi);
[PreserveSig]
int SetImageCount(uint uNewCount);
[PreserveSig]
int SetBkColor(uint clrBk, out uint pclr);
[PreserveSig]
int GetBkColor(out uint pclr);
[PreserveSig]
int BeginDrag(int iTrack, int dxHotspot, int dyHotspot);
[PreserveSig]
int EndDrag();
[PreserveSig]
int DragEnter(IntPtr hwndLock, int x, int y);
[PreserveSig]
int DragLeave(IntPtr hwndLock);
[PreserveSig]
int DragMove(int x, int y);
[PreserveSig]
int SetDragCursorImage([MarshalAs(UnmanagedType.IUnknown)] object punk, int iDrag, int dxHotspot, int dyHotspot);
[PreserveSig]
int DragShowNolock(bool fShow);
[PreserveSig]
int GetDragImage(IntPtr ppt, IntPtr pptHotspot, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);
[PreserveSig]
int GetItemFlags(int i, out uint dwFlags);
[PreserveSig]
int GetOverlayImage(int iOverlay, out int piIndex);
}
[Flags]
public enum SHGFI
{
SHGFI_ICON = 0x000000100,
SHGFI_DISPLAYNAME = 0x000000200,
SHGFI_TYPENAME = 0x000000400,
SHGFI_ATTRIBUTES = 0x000000800,
SHGFI_ICONLOCATION = 0x000001000,
SHGFI_EXETYPE = 0x000002000,
SHGFI_SYSICONINDEX = 0x000004000,
SHGFI_LINKOVERLAY = 0x000008000,
SHGFI_SELECTED = 0x000010000,
SHGFI_ATTR_SPECIFIED = 0x000020000,
SHGFI_LARGEICON = 0x000000000,
SHGFI_SMALLICON = 0x000000001,
SHGFI_OPENICON = 0x000000002,
SHGFI_SHELLICONSIZE = 0x000000004,
SHGFI_PIDL = 0x000000008,
SHGFI_USEFILEATTRIBUTES = 0x000000010,
SHGFI_ADDOVERLAYS = 0x000000020,
SHGFI_OVERLAYINDEX = 0x000000040,
}