VB.net or Windows API: How to find out which icons the file explorer uses?

a 夏天 提交于 2019-12-23 05:08:58


I am currently working on a Windows desktop application using VB.net where I would like to have a file and folder browsing interface directly integrated, i.e. the user does not have to open a file browser dialog to select files.

My file browser should resemble the original Windows file explorer at least in that it uses the same icons for the most common locations. For example, I would like to include the "Favorites" folder with the appropriate icon (please note that this is NOT the IE favorites folder, but the folder which comes up when you type shell:links into the address bar of the file explorer).

My problem is fetching the icon. So far, I have written a wrapper class for some functions of the Windows API, notably SHGetKnownFolderPath and SHGetFileInfo. My approach is the following:

1) Use SHGetKnownFolderPath to get the full path to the respective location (which depends on the Windows version and localization). This part works like expected. For example, on my system (W7 Pro x64), SHGetKnownFolderPath returns "C:\Users\Administrator\Links" when queried with the respective rfid.

2) Use SHGetFileInfo to fetch the icon which Windows considers the default icon for the path obtained in 1). This part technically works as well, but the wrong icon is returned - wrong in the sense that it is another icon than Windows file explorer uses for the same location.

I have tried that with four different locations (MyLibraries, MyFavorites (Links), MyComputer, MyNetwork). The icon for MyLibraries was the expected one, the other three were completely different from the icons Windows file explorer uses.

So I have got some questions:

1) Is there any way to detect which icons are used by the standard Windows file explorer for certain folders, e.g. "Favorites" (C:\Users\Administrator\Links on my machine)? I would be interested in a general solution (i.e. a solution which works for all locations described here).

2) If there is no such way, I will find out the number (index) of all icons of interest in shell32.dll (actually, there are only a few at the moment). Can I be sure that those indexes won't change in the future?

3) According to this document, I have to call CoInitialize before using SHGetFileInfo. I believe that the .NET framework automatically does this for the main thread before starting it and thus have not done it on my own yet (the development of the application has just started, and there is only one thread at the moment).

I think that the missing call to CoInitialize can't be the cause for the "wrong" icons. If I'm wrong here, please let me know.

A potential solution could be using a .NET language or the native Windows API / SDK. As long as there is some way (even an extremely complicated one) to use the solution from within VB.net, I will be happy with it.


Explorer uses 2 ways to detect icon of any object, file or folder.

1) call IShellFolder.GetUIObjectOf(IExtractIconA/W) and work with IExtractIcon.

2) query IShellFolder.QueryInterface(IShellIcon) and call IShellIcon.GetIconOf.

You can do the same.