2

I'm trying to get the icon out of a .lnk file without the .lnk overlay appearing. The documentation has information about a flag SHGFI_ADDOVERLAYS which can be set to add an overlay, but I am looking to remove the overlay.

I have read this question, as well as the links inside of it, but I am still unable to get it working in c#.

Here is the code I have tried:

SHFILEINFO shFileInfo = new SHFILEINFO();

SHGetFileInfo(
    pathToLnk,
    0,
    ref shFileInfo,
    (uint)Marshal.SizeOf(shFileInfo),
    SHGFI_ICON & ~SHGFI_LINKOVERLAY);

As well as some other configurations of the flags.

Thanks in advance for the help.

Community
  • 1
  • 1
xandermonkey
  • 4,054
  • 2
  • 31
  • 53
  • Erm, wait, there is an extra level of indirection here. Do you try to get the icon for the .lnk file or the icon that is stored in the lnk file? Presumably the latter, use the ShellLinkObject helper. It won't have an overlay.. – Hans Passant Apr 21 '17 at 16:17
  • I'm looking for the icon stored in the lnk, the one without the arrow overlay. – xandermonkey Apr 21 '17 at 16:20
  • As the name implies, the **overlay** is never stored in an icon. You seem to be under the impression, that the overlay were part of any of the icon. This is not the case. The visual appearance is the result of compositing an icon and an overlay. – IInspectable Apr 21 '17 at 18:26
  • Ok, well I was using Icon.ExtractAssociatedIcon() and getting an arrow in the bottom left corner. – xandermonkey Apr 21 '17 at 18:28
  • The `uFlags` parameter is a bitmask. Passing `SHGFI_ICON & ~SHGFI_LINKOVERLAY` is the same as passing `SHGFI_ICON` by itself, because the bits used by `SHGFI_LINKOVERLAY` are not used by `SHGFI_ICON`. When specifying flags, you usually use the bitwise `OR` operator to combine bits, not the bitwise `AND NOT` operators to remove bits. – Remy Lebeau Apr 21 '17 at 22:23
  • Yeah I was just experimenting and trying to get things working. I have solved this, when I return to work I'll post a solution. – xandermonkey Apr 21 '17 at 22:31

1 Answers1

0

The solution is as follows:

[DllImport("Comctl32.dll")]
public static extern IntPtr ImageList_GetIcon(IntPtr himl, int i, uint flags);


SHFILEINFO fileInfo = new SHFILEINFO();
        IntPtr list = SHGetFileInfo(
            pathToLnk,
            FileAttributes,
            ref fileInfo,
            (uint)Marshal.SizeOf(fileInfo),
            SHGFI_SYSICONINDEX);
        var iconHandle = ImageList_GetIcon(list, fileInfo.iIcon.ToInt32(), FileFlags);
        Icon icn = Icon.FromHandle(iconHandle);
xandermonkey
  • 4,054
  • 2
  • 31
  • 53