We have an icon overlay extension which displays different overlays depending on the file status. For automated tests, i am searching for a to check if the correct overlay is displayed. Therefore, i ask if it is possible to extract the overlay icon itself or maybe get the path to the icon for comparing.
I tried following code:
SHFILEINFO shfi = new SHFILEINFO();
IntPtr result = SHGetFileInfo(filePath, 0, ref shfi, (uint)Marshal.SizeOf(shfi), SHGFI_ICON | SHGFI_SMALLICON | SHGFI_OVERLAYINDEX);
if (result != IntPtr.Zero)
{
int overlayIndex = shfi.iIcon >> 24;
Console.WriteLine($"Overlay Index: {overlayIndex}");
DestroyIcon(shfi.hIcon);
}
Despite the overlayIndex is 0 every time, is there a way to get the overlay icon without the main icon to compare or check?
EDIT: I tried following method after Jimi's comment:
private static Icon GetOverlay(string filePath)
{
var imageListGuid = new Guid("46EB5926-582E-4017-9FDF-E8998DAA0950");
IMAGELIST sysImageList;
var result = SHGetImageList(SHIL_SMALL, ref imageListGuid, out sysImageList);
if (result == 0)
{
var shfi = new SHFILEINFO();
var hSuccess = SHGetFileInfo(filePath, 0, ref shfi, (uint)Marshal.SizeOf(shfi), SHGFI_ICON | SHGFI_OVERLAYINDEX | SHGFI_SMALLICON);
if (hSuccess != IntPtr.Zero)
{
var iconIndex = shfi.iIcon;
var overlayIndex = iconIndex & 0xF;
var hOverlayIcon = ImageList_GetIcon(sysImageList.handle, overlayIndex, 0);
var overlay = Icon.FromHandle(hOverlayIcon);
return overlay;
}
}
return null;
}
Unfortunately i never get the overlay icon, it is some kind of standard icon.
You can use IImageList::GetOverlayImage method, here is a full sample: