This article discusses a simple class that can be used for assigning an icon to a folder that displays in Windows Explorer.
In the course of a discussion I was having with a UI Engineer I work with, he was relating that he discovered how to create an icon for a folder in Windows Explorer (Select Folder: Properties: Customize Tab: Change Icon...), and I got to thinking, "There must be a way to do that programmatically".
It turns out that not only is there a way to do it, but it's also a fairly easy task to handle. The discussion we were having about this topic was one part of a larger endeavor, and that will be the source of a future article. However, to accomplish the final goal, the first problem to solve is that of assigning an icon to a folder - and that seemed to be an interesting enough topic in itself to write an article about.
Using the code
If you wish to just try out the sample application, simply open the FolderIcons.sln solution file and build or run it within the Visual Studio IDE.
There are basically two steps involved in assigning an icon to a folder (or possibly three steps, if you count creating the folder):
- Create a desktop.ini file inside the folder for which to create the icon (the "Target Folder").
- Set the Target Folder's attribute to "System".
To accomplish these steps, I created two classes. The first is called
FolderIcon, which orchestrates the steps. The second one is called
IniWriter, which just has one static method called
WriteValue() that wraps the
WritePrivateProfileString() Win32 API function (for simplicity's sake, of course - if you wish to rewrite the method so that it's pure managed code routines, then be my guest; this was mostly a proof-of-concept project from my perspective, though I probably would re-write the method for production).
As you may have noticed from the screenshot, there is a small dialog which serves as a simple user interface that enables browsing or entering a folder path (the folder is created if it does not currently exist), selecting of an icon (the icon file must exist), and entering a description which will appear in the InfoTip that appears when you hover your mouse pointer over the folder in Windows Explorer. When the user clicks on the "Create Icon" button, a
FolderIcon object is created, passing the folder path into its constructor, after which its
CreateFolderIcon() method is invoked:
private void btnCreateIcon_Click(object sender, System.EventArgs e)
FolderIcon myFolderIcon = new FolderIcon(txtFolderPath.Text);
myFolderIcon = null;
The CreateFolderIcon Method
Drilling down into the
public void CreateFolderIcon( string iconFilePath, string infoTip )
if ( CreateFolder() )
CreateFolderIcon() attempts to create the folder, then it calls the methods to create the desktop.ini file, seta the .ini file's attributes to Hidden and System, and then sets the Target Folder's attributes to System. The individual methods are described in the following sections.
The CreateDesktopIniFile Method
There are two forms of the
CreateDesktopIniFile() method. The one called by
CreateFolderIcon above has two parameters: the path to the icon and the description of the folder to be displayed in an InfoTip (a.k.a. ToolTip). The simple version of
CreateDesktopIniFile() calls another form of
CreateDesktopIniFile() with a slightly more verbose signature:
private bool CreateDesktopIniFile( string iconFilePath,
bool getIconFromDLL, int iconIndex, string infoTip )
this.IniPath = this.FolderPath + "desktop.ini";
CreateDesktopIniFile() uses the
WriteValue() to create the desktop.ini file in the Target Folder, and since the
WriteValu() method is static, it is used without having to instantiate the
IniWriter class. The
WriteValue() method is basically just a wrapper around the
WritePrivateProfileString() Win32 API function, and the parameters correspond directly. All you have to do to use it is to pass the section name, the key name, the value for the key, and the path to the desktop.ini file.
To display an icon for a folder, the desktop.ini must contain a section named "
.ShellClassInfo" that contains two keys: "
IconFile" - the path to the .ico file you wish to assign to this folder, and "
IconIndex" - which should be set to zero for icon files.
InfoTip is optional, but it's an easy way to create a fuller description of the folder's purpose.
After the above three
WriteValue() lines are called, you will end up with something similar to the following:
InfoTip=Test is the greatest folder ever!
The settings listed above are the ones required to display the icon. You can probably deduce from the "
IconIndex" key in the .ini file (as well as the corresponding
iconIndex parameter on the
CreateDesktopIniFile() method) that the method supports setting up the .ini file to work with icons embedded in DLLs and EXEs. You would set
IconFile to point to the DLL in question and the
IconIndex to reference the index of the icon in the DLL. To see how this works, you can play around with the "Change Icon..." functionality in Windows, and then open the resultant desktop.ini file. What this means for your application is that you could provide a set of icons embedded in a DLL which you could assign to folders to indicate various purposes for the folders, which is similar to what Windows does for some of its directories.
The SetIniFileAttributes Method
The next step is to set the attributes of the desktop.ini file to Hidden and System:
private bool SetIniFileAttributes()
if ((File.GetAttributes(this.IniPath) & FileAttributes.Hidden)
if ((File.GetAttributes(this.IniPath) & FileAttributes.System)
As a side note, it is my understanding from preliminary testing I've performed that this step is not entirely necessary - you can create a desktop.ini file without fiddling with its file attributes, and it will work just fine. However, if you follow the steps via the Windows Explorer folder properties, it sets the attributes to Hidden and System, so I just thought it would be good to be consistent with Windows' functionality.
The SetFolderAttributes Method
Not only does the desktop.ini's attributes need to be set to System, but the Target Folder's need to be set as well:
private bool SetFolderAttributes()
if ((File.GetAttributes(this.FolderPath) & FileAttributes.System)
(this.FolderPath) | FileAttributes.System);
Unlike the settings for the desktop.ini file, the System setting for the folder is necessary. It may be interesting to you to note that the class and methods one uses for getting and setting the attributes of the folder are identical to that of a file (i.e., with the
File class' static methods
SetAttributes()). Honestly, it threw me for a bit when I was researching this part of the functionality, since it seemed more natural and straightforward to me to have the
SetAttributes() method in the
Points of Interest
As I mentioned earlier in the article, this project just encapsulates (no pun intended) the first part of a two-part series which will show a semi-practical application of the folder icon assignment functionality. Next time, I'll start from this point and expound a bit on how this can be a very useful feature when you play with some settings in Microsoft Office. Until then, I'll keep it a secret.
The following references proved useful in my creation of this project and article, so I thought it appropriate to give them proper recognition:
- January 15, 2005 - v1.0 by Evan Stone.