using SHFILEINFO to get file icons

Viewed 2927

I've been searching for a c# library that gets the icon of a given path with many sizes, finally when I got exactly the class that I need, It has a problem:

This method gets icon of a given path:

public static BitmapSource GetIcon(string FileName, bool small, bool checkDisk, bool addOverlay)
    {
        SHFILEINFO shinfo = new SHFILEINFO();

        uint SHGFI_USEFILEATTRIBUTES = 0x000000010;
        uint SHGFI_LINKOVERLAY = 0x000008000;

        uint flags;
        if (small)
        {
            flags = SHGFI_ICON | SHGFI_SMALLICON;
        }
        else
        {
            flags = SHGFI_ICON | SHGFI_LARGEICON;
        }
        if (!checkDisk)
            flags |= SHGFI_USEFILEATTRIBUTES;
        if (addOverlay)
            flags |= SHGFI_LINKOVERLAY;

        var res = SHGetFileInfo(FileName, 0, ref shinfo, Marshal.SizeOf(shinfo), flags);
        if (res == 0)
        {
            throw (new System.IO.FileNotFoundException());
        }

        var ico = System.Drawing.Icon.FromHandle(shinfo.hIcon); //**Here**

        var bs = BitmapFromIcon(ico);
        ico.Dispose();
        bs.Freeze();
        DestroyIcon(shinfo.hIcon);

        //   CloseHandle(shinfo.hIcon);  it always give exception
        return bs;

    }

public static extern Boolean CloseHandle(IntPtr handle);

The previous code as it is in this question works as it suppose to, however AFTER getting the icons of file paths in a directory successfully, it gives an exception on this line :
var ico = System.Drawing.Icon.FromHandle(shinfo.hIcon);

An exception of type 'System.IO.FileNotFoundException' occurred in WPF_REMOTE.exe but was not handled in user code

Additional information: Unable to find the specified file.

So Why is this happening? Update: I found out that it happened because there were a path that contains unicode characters and i need to use SHFILEINFOW instead, still can't figure how to change SHFILEINFO to SHFILEINFOW

another question about the line CloseHandle(shinfo.hIcon); always give an exception :

An exception of type 'System.Runtime.InteropServices.SEHException' occurred in WPF_REMOTE.exe but was not handled in user code

Additional information: External component has thrown an exception.

I'm wondering why it's not working! and why should I use it if the method is already working without it.

also if you have any improvement I could use in this class tell me, Thanks in Advance.

1 Answers
Related