Why doesn’t SHGetFileInfo give me customized folder icons?

Raymond Chen

A customer reported that they were unable to obtain cutomized folder icons. Whenever they asked for the icon for a folder, they always got a plain folder icon, Even if they asked for folders like My Documents, which come with their own custom icons. The customer says that they are using the code from this Web site:

public static System.Drawing.Icon GetFileIcon(string name, IconSize size, 
                                              bool linkOverlay)
{
    Shell32.SHFILEINFO shfi = new Shell32.SHFILEINFO();
    uint flags = Shell32.SHGFI_ICON | Shell32.SHGFI_USEFILEATTRIBUTES;
    
    if (true == linkOverlay) flags += Shell32.SHGFI_LINKOVERLAY;


    /* Check the size specified for return. */
    if (IconSize.Small == size)
    {
        flags += Shell32.SHGFI_SMALLICON ; // include the small icon flag
    } 
    else 
    {
        flags += Shell32.SHGFI_LARGEICON ;  // include the large icon flag
    }
    
    Shell32.SHGetFileInfo( name, 
        Shell32.FILE_ATTRIBUTE_NORMAL, 
        ref shfi, 
        (uint) System.Runtime.InteropServices.Marshal.SizeOf(shfi), 
        flags );


    // Copy (clone) the returned icon to a new object, thus allowing us 
    // to call DestroyIcon immediately
    System.Drawing.Icon icon = (System.Drawing.Icon)
                         System.Drawing.Icon.FromHandle(shfi.hIcon).Clone();
    User32.DestroyIcon( shfi.hIcon ); // Cleanup
    return icon;
}

As I noted some time ago, the SHGFI_USE­FILE­ATTRIBUTES flag means “Pretend that the file/directory exists, and that its file attributes are what I passed as the dwFileAttributes parameter. Do this regardless of whether it actually exists or not.”

Since you’re passing the flag, and you say “Trust me, it’s a directory,” the shell says, “Okay, then here’s the icon for a standard directory. I can’t give you anything better than that because you told me not to access the disk.”

If you want to get the icon for a live file or directory, then remove the SHGFI_USE­FILE­ATTRIBUTES flag.

Bonus chatter: Yes, somebody posted a comment on that Web site asking how to get the function to work for special folders, and somebody else posted the same answer (namely, remove the SHGFI_USE­FILE­ATTRIBUTES flag). But that question/answer was posted long after our customer asked the question.

0 comments

Discussion is closed.

Feedback usabilla icon