by Charlie Calvert
A common need for programmers is to get the users home directory and
other commonly used directories. In .NET, this involves using a
combination of the Environment.SpecialFolders enumeration, and
the Environment.GetEnvironmentVariable() function.
The code in this article is written in C#, but it should be easy to
translate it into Pascal code.
Special Folders
Here is the Environment.SpecialFolder enumeration:
Environment.SpecialFolder.ApplicationData
Environment.SpecialFolder.System
Environment.SpecialFolder.CommonApplicationData
Environment.SpecialFolder.CommonProgramFiles
Environment.SpecialFolder.Cookies
Environment.SpecialFolder.Desktop
Environment.SpecialFolder.DesktopDirectory
Environment.SpecialFolder.Favorites
Environment.SpecialFolder.History
Environment.SpecialFolder.InternetCache
Environment.SpecialFolder.LocalApplicationData
Environment.SpecialFolder.MyComputer
Environment.SpecialFolder.MyMusic
Environment.SpecialFolder.MyPictures
Environment.SpecialFolder.Personal
Environment.SpecialFolder.ProgramFiles
Environment.SpecialFolder.Programs
Environment.SpecialFolder.Recent
Environment.SpecialFolder.SendTo
Environment.SpecialFolder.StartMenu
Here is how to use this enumeration:
String PersonalFolder =
Environment.GetFolderPath(Environment.SpecialFolder.Personal);
After executing this code, the variable PersonalFolder should
contain the value of your My Documents directory.
Special Folders, Integer value of Enum, Dir on My System
In Listing 1 you see the values of all the special folders on my
system.
Note that this enumeration is not sequential. In particular, the
integer value for the first member of the enumeration in .NET 1.1 is 0,
the next is 2, then 5, then 6, etc. I got these values by writing this
code: int i = (int)sp. If
someone sees a pattern here,
let me know!
Listing 1: The values of the
SpecialFolder enumeration on my system. The number in the first column
is the integer value of the particular SpecialFolder member shown in
the second column.
0 Desktop C:\Documents and Settings\Charlie\Desktop
2 Programs C:\Documents and Settings\Charlie\Start Menu\Programs
5 Personal D:\documents
6 Favorites C:\Documents and Settings\Charlie\Favorites
8 Recent C:\Documents and Settings\Charlie\Recent
9 SendTo C:\Documents and Settings\Charlie\SendTo
11 StartMenu C:\Documents and Settings\Charlie\Start Menu
13 MyMusic D:\documents\My Music
16 DesktopDirectory C:\Documents and Settings\Charlie\Desktop
17 MyComputer
26 ApplicationData C:\Documents and Settings\Charlie\Application Data
28 LocalApplicationData C:\Documents and Settings\Charlie\Local Settings\Application Data
32 InternetCache C:\Documents and Settings\Charlie\Local Settings\Temporary Internet Files
33 Cookies C:\Documents and Settings\Charlie\Cookies
34 History C:\Documents and Settings\Charlie\Local Settings\History
35 CommonApplicationData C:\Documents and Settings\All Users\Application Data
37 System C:\WINDOWS\System32
38 ProgramFiles C:\Program Files
39 MyPictures D:\documents\My Pictures
43 CommonProgramFiles C:\Program FilesCommon Files
Listing 2 shows the code for getting the values found in the
previous listing. Note the use of the IList
interface to access the list of strings stored in a ListBox. Becoming
comfortable with interfaces is one of the core tasks for programmers
migrating from Win32 to .NET. Java programmers should already be
familiar with this paradigm.
Listing 2: The code for retrieving
the values displayed in Listing 1.
private static void ShowSpecialFolder(Environment.SpecialFolder sp, IList list)
{
int i = (int)sp;
String S1 = String.Format("{1} {0} {2} {0}{0}{0} {3}", '\t', i,
sp.ToString(), Environment.GetFolderPath(sp));
list.Add(S1);
}
public static IList GetAllSpecialFolders(IList list)
{
ShowSpecialFolder(Environment.SpecialFolder.ApplicationData, list);
ShowSpecialFolder(Environment.SpecialFolder.System, list);
ShowSpecialFolder(Environment.SpecialFolder.CommonApplicationData, list);
ShowSpecialFolder(Environment.SpecialFolder.CommonProgramFiles, list);
ShowSpecialFolder(Environment.SpecialFolder.Cookies, list);
ShowSpecialFolder(Environment.SpecialFolder.Desktop, list);
ShowSpecialFolder(Environment.SpecialFolder.DesktopDirectory, list);
ShowSpecialFolder(Environment.SpecialFolder.Favorites, list);
ShowSpecialFolder(Environment.SpecialFolder.History, list);
ShowSpecialFolder(Environment.SpecialFolder.InternetCache, list);
ShowSpecialFolder(Environment.SpecialFolder.LocalApplicationData, list);
ShowSpecialFolder(Environment.SpecialFolder.MyComputer, list);
ShowSpecialFolder(Environment.SpecialFolder.MyMusic, list);
ShowSpecialFolder(Environment.SpecialFolder.MyPictures, list);
ShowSpecialFolder(Environment.SpecialFolder.Personal, list);
ShowSpecialFolder(Environment.SpecialFolder.ProgramFiles, list);
ShowSpecialFolder(Environment.SpecialFolder.Programs, list);
ShowSpecialFolder(Environment.SpecialFolder.Recent, list);
ShowSpecialFolder(Environment.SpecialFolder.SendTo, list);
ShowSpecialFolder(Environment.SpecialFolder.StartMenu, list);
return list;
}
private void button1_Click_1(object sender, System.EventArgs e)
{
GetAllSpecialFolders(listBox1.Items);
}
This code begins with the last method,
button1_Click_1, which will be called when the user
clicks on a button. The button click method calls the
GetAllSpecialFolders() method.
GetAllSpecialFolders() has one call to
ShowSpecialFolders for each of the special folders that
the C# API tracks for you. Each call to
ShowSpecialFolders creates one of the strings shown in
Listing 1:
0 Desktop C:\Documents and Settings\Charlie\Desktop
The ShowSpecialFolders method begins by getting the integer value of the member of the SpecialFolders enumeration that is passed in as a parameter:
int i = (int)sp;
This integer value appears at the beginning of the strings shown in Listing 1. For instance, it is the 0 before the word Desktop. This value is normally not important to developers, but I am showing it to you in case you are curious about the declaration of the SpecialFolders enumeration.In Microsoft's implementation of C#, we never see the source, so it is interesting to guess how it must be declared. For instance, in this case, the enumeration might look something like this:
enum SpecialFolder {Desktop=0, Programs=2, Personal=5, Favorites=6, Recent=8, etc);
The next line of my ShowSpecialFolders method begins with a call to String.Format. The String.Format() method has a peculiar, but useful,
syntax I have only seen in C#. Each of the instances of code that appears
in curly braces is replaced by one of the latter parameters passed to the
method. For instance {0}, {1} and {2} get replaced with one of the
parameters such as '\t' or
sp.ToString() which is passed to
String.Format. Note that '\t;' is the second
parameter. It is the tab character, and will replace all instances of
{0}. The variable i is the third parameter, and the
value stored in that variable will replace each instance of {1}.
The code {2} is replaced by each instance of
sp.ToString(). sp is a member of the
SpecialFolder enumeration, and the
ToString() method conveniently converts sp
into a string representation of the enumeration member. That
is, it converts sp into a string such as "Desktop",
"Programs", "Personal", etc. In the String shown above, the value of
i appears as 0, and
sp.ToString() appears as Desktop. Again,
programmers don't normally need to make a call to find out the string value
of an enumeration, but it is interesting to know that you can do it
if you so desire.
The last parameter, the one that goes into {3}, is the
path, such as C:\Documents and
Settings\Charlie\Desktop. I retrieved the path string by
making the following call:
Environment.GetFolderPath(sp). Note that I place three tabs in
front of the path, to separate it from the rest of the code:
String S1 = String.Format("{1} {0} {2} {0}{0}{0} {3}", 't', i,
sp.ToString(), Environment.GetFolderPath(sp));
I still had
to manually edit some of the tabbing to make it come out as evenly as it
appears in Listing 1.
Useful Methods
Listing 3 shows some other useful methods. Note that I use the GetEnvironmentVariable call to
retrieve the Home Directory and in the call to GetEnvTempDir(). Since environment
variables are mutable, these calls are probably less reliable than
other calls. Also, they may be OS dependant. In particular, I have only
tested them on XP. Note, however, the GetTempDir()
call, which uses what should be a more reliable method of retreiving
the temporary directory. In particular, it uses the Path object. The GetMyDocumentsDir()
method is a wrapper around the Environment.SpecialFolder enumeration.
Listing 3: Routines for getting the
users home directory, their My Documents directory, and the temp
directory.
public static String GetHomeDir()
{
return Environment.GetEnvironmentVariable("USERPROFILE");
}
public static String GetMyDocumentsDir()
{
return Environment.GetFolderPath(Environment.SpecialFolder.Personal);
}
public static String GetEnvTempDir()
{
return Environment.GetEnvironmentVariable("TEMP");
}
public static String GetTempDir()
{
return System.IO.Path.GetTempPath();
}
Summary
In this article you have learned a few simple tricks for getting
system
dependant information while using .NET. In particular, you learned
about the Environment.SpecialFolder enumeration, and
about the Environment.GetEnvironmentVariable
method. The Environment class
is part of the System namespace,
so you should not have to add any special Using statements to your code
other than the default Using System
reference which should appear at
the top of all C# files.