Click here to Skip to main content
Click here to Skip to main content

Customizing Folders in C#

, 15 May 2007 CPOL
Rate this:
Please Sign up or sign in to vote.
By now, many of us have seen customized folders in Windows XP and earlier, i.e. folders like My Documents, My Pictures and so on. I intend to show you how to create these customized folder views using C#.
Screenshot - application.png

Contents

Introduction

By now, many of us have seen customized folders in Windows XP and earlier, i.e. folders like My Documents, My Pictures and so on. Well this is accomplished by setting the folder as a System folder and placing a file named desktop.ini into the same folder.

I intend to show you how to create these customized folder views using C#.

  • Step 1: Make a folder a system folder. This is as easy as setting the system attribute on the folder. This can be done in DOS with a attrib +s folderName, or through the properties of the folder in Explorer, or through the System.File namespace.
  • Step 2: Create the desktop.ini file. This is relatively easy too, all you need is Notepad or the System.IO namespace.

Desktop.ini

The desktop.ini file is an old school INI file. It is essentially a text file with a special syntax.

[section1]
parameter1=value1
parameter2=value2
parameter3=value3
[section2]
parameter1=value1
parameter2=value2
parameter3=value3    

The desktop.ini file requires a section of [.ShellClassInfo] and a minimum of two attributes/parameters, IconFile and IconIndex. There are two ways that an icon can be specified for a folder. The first is through a Win32 resource file (note: this is not the same as a .NET resource file) or through a file.

INI Entries

These are the valid entries and values for the [.ShellClassInfo] section.

Entry Value
ConfirmFileOp Set this entry to 0 to avoid a "You Are Deleting a System Folder" warning when deleting or moving the folder.
NoSharing Set this entry to 1 to prevent the folder from being shared.
IconFile If you want to specify a custom icon for the folder, set this entry to the icon's file name. The ICO file extension is preferred, but it is also possible to specify *.bmp files, or *.exe and *.dll files that contain icons. If you use a relative path, the icon will be available to people who view the folder over the network. You must also set the IconIndex entry.
IconIndex Set this entry to specify the index for a custom icon. If the file assigned to IconFile only contains a single icon, set IconIndex to 0.
InfoTip Set this entry to an informational text string. It will be displayed as an infotip when the cursor hovers over the folder. If the user clicks the folder in a Web view, the information text will be displayed in the folder's information block, below the standard information.

Using a DLL for the Icon

Use this method when the icon exists in a Win32 DLL like SHELL32.DLL. In the example below, you will see that the InfoTip value is "pulled" from the Shell32.dll resource section as well as the IconFile.

[.ShellClassInfo]
InfoTip=@Shell32.dll,-12690
IconFile=%SystemRoot%\system32\SHELL32.dll
IconIndex=-238    

Using an Icon File for the Icons

Use this method when you will provide a physical file like Folder_Blue_Software_1.ico.

[.ShellClassInfo]
IconFile=Folder_Blue_Software_1.ico
IconIndex=0
InfoTip=Sample tooltip for this folder.
ConfirmFileOp=0
NoSharing=0

The Code

Now the fun part, the code.

Here I provide two methods CreateIconFolder and UndoIconFolder.

CreateIconFolder

The CreateIconFolder method provides a helper function to create the "iconed" folder. This method is overloaded.

The first overload ...

CreateIconFolder(string folderName, string iconFile)

... uses the following defaults for the desktop.ini creation: IconIndex = 0, InfoTip="", ConfirmFileOp=0, and NoSharing = 0.

The second overload provides more control over the creation of the desktop.ini file.

CreateIconFolder(string folderName, string iconFile, int iconIndex, 
            string toolTip, bool preventSharing, bool confirmDelete)

The code...

/// <span class="code-SummaryComment"><summary></span>
/// Turns a folder into a "Special" folder, at least one that contains 
/// an icon and custom tooltip
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><remarks></span>
/// The default for iconIndex is 0.
/// The default for toolTip is "".
/// The default for preventSharing is false.
/// The default for confirmDelete is true.
/// <span class="code-SummaryComment"></remarks></span>
/// <span class="code-SummaryComment"><param name="folderName">The fully qualified path to the file.</param></span>
/// <span class="code-SummaryComment"><param name="iconFile">The Icon File to use.</param></span>
/// <span class="code-SummaryComment"><returns>True upon success, otherwise false.</returns></span>
private bool CreateIconedFolder (string folderName, string iconFile)
{
   return CreateIconedFolder(folderName, iconFile, 0, "", false, true);
}

/// <span class="code-SummaryComment"><summary></span>
/// Turns a folder into a "Special" folder, at least one that contains an icon 
/// and custom tooltip
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="folderName">The fully qualified path to the file.</param></span>
/// <span class="code-SummaryComment"><param name="iconFile">The Icon File to use.</param></span>
/// <span class="code-SummaryComment"><param name="iconIndex">The index of the icon to use.</param></span>
/// <span class="code-SummaryComment"><param name="toolTip">The tooltip or "InfoTip" to use.</param></span>
/// <span class="code-SummaryComment"><param name="preventSharing">True indicates the folder cannot be shared. </span>
/// False indicates sharing is allowed.<span class="code-SummaryComment"></param></span>
/// <span class="code-SummaryComment"><param name="confirmDelete">True indicates the use will receive a message </span>
/// "You are deleting a system" when attempting
/// to delete the folder.  False indicates that the operating system 
/// will not raise this warning.<span class="code-SummaryComment"></param></span>
/// <span class="code-SummaryComment"><returns>True upon success, otherwise false.</returns></span>
private bool CreateIconedFolder 
    (string folderName, string iconFile, int iconIndex, string toolTip,
      bool preventSharing, bool confirmDelete)
{
   #region Private Variables
   DirectoryInfo folder;
   string fileName = "desktop.ini";
   #endregion Private Variables

   #region Data Validation

   if (Directory.Exists(folderName) == false)
   {
      return false;
   }

   #endregion Data Validation

   try
   {
      folder = new DirectoryInfo(folderName);
      fileName = Path.Combine(folderName, fileName);

      // Create the file
      using (StreamWriter sw = new StreamWriter(fileName))
      {
         sw.WriteLine("[.ShellClassInfo]");
         sw.WriteLine("ConfirmFileOp={0}", confirmDelete);
         sw.WriteLine("NoSharing={0}", preventSharing);
         sw.WriteLine("IconFile={0}", iconFile);
         sw.WriteLine("IconIndex={0}", iconIndex);
         sw.WriteLine("InfoTip={0}", toolTip);
         sw.Close();
      }

      // Update the folder attributes
      folder.Attributes = folder.Attributes | FileAttributes.System;

      // "Hide" the desktop.ini
      File.SetAttributes(fileName, File.GetAttributes(fileName) | FileAttributes.Hidden);
   }
   catch
   {
      return false;
   }

   return true;
}

UndoIconFolder

The UndoIconFolder utility function will revert a file back to a "normal" folder. This function deletes the desktop.ini and removes the system attribute from the folder.

/// <span class="code-SummaryComment"><summary></span>
/// Turns a "Special" folder back into a normal folder.
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="folderName">The folder to revert back.</param></span>
/// <span class="code-SummaryComment"><returns>True upon success otherwise false.</returns></span>
private bool UndoIconedFolder (string folderName)
{
   #region Private Variables
   DirectoryInfo folder;
   #endregion Private Variables

   #region Data Validation
   if (Directory.Exists(folderName) == false)
   {
      return false;
   }
   #endregion Data Validation

   try
   {
      folder = new DirectoryInfo(folderName);

      // Remove the file [Desktop.ini]
      FileInfo file = new FileInfo(Path.Combine(folderName, "desktop.ini"));
      if (file.Exists)
      {
         file.Delete();
      }

      folder.Attributes = (folder.Attributes | FileAttributes.System);
   }
   catch
   {
      return false;
   }

   return true;
}

Next Steps / Future Features

  • I don't plan on adding anything to this, but let me know if I need to add anything.

History

Version Date What was done
1.0.0.0 5/14/07 Created the article

References

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Joseph Guadagno
Web Developer
United States United States
I have been in software development for about 15 years or so. I started out with a small book on QuickBASIC, then moved the Visual Basic for DOS, then Visual Basic for Windows, then Visual Basic .NET and eventually Visual C#. When I am not working at my full time job I donate my time to several community efforts like:
 
Former President of INETA North America, currently Vice President.
President of the Southeast Valley .NET User Group (SEVDNUG) in Chandler, AZ.
Serving on my City's Parks and Recreation board.
 
I have or have had the following "MVP" awards:
  • Visual Basic MVP in 1996
  • C# MVP since 2009
  • Telerik MVP since 2010
I maintain a Open Source project on CodePlex which wraps the Bing API called BingSharp.
 
I also help / organize or participate in several community events:
  • Desert Code Camp
  • AZGiveCamp
  • Organizer for the 1st Time MVP event at the MVP Summit
  • MVP 2 MVP Sessions at MVP Summit.
  • Awesome bean pusher at GeekGive at the MVP Summit.
Follow on   Twitter

Comments and Discussions

 
QuestionHow to make it work in Win7 PinmemberMember 420253530-Jun-11 17:37 
GeneralThank you Pinmembermerlin98116-May-07 4:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.1411023.1 | Last Updated 15 May 2007
Article Copyright 2007 by Joseph Guadagno
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid