Windows Special Folders
We were watching a Microsoft Web Seminar yesterday on Windows Vista User Account Controls, and one of the code samples referenced the users LocalApp directory. This led to a discussion of where to store things like binary files, config files, and .ini files. In the past, you may have stored this in the Program Files directory. This is not a good practice, because there is no guarantee that this is where the user installed the software. Fortunately, in .NET, you can get the installed directory from an Assembly object, but this is still not a good practice
because if the software is uninstalled and reinstalled, you could lose those files, frustrating your users.
To compound this problem, in Vista the Program Files directory requires Administrator priveleges. The whole point of UAC, of course, is to limit potentially dangerous code from executing and to allow users to truly operate in a “Standard User” account environment. Even a user with Administrator priveleges executes programs with Standard User access [NOTE: this behaviour can be overridden by manually assigning a manifest to the assembly instructing it to run as Administrator]. This means that in order to access a config or binary file stored in Program Files requires the user to bump up their security by responding to a Dialog Box. One of the Vista goals that Microsoft has set forth for ISVs is that our software should run as Standard User. That and the user being constantly prompted to upgrade their security level are reasons enough not to rely on Program Files for storage in Vista.
Another typical solution is to simply create your own directory structure in C:\, but I find that unrealiable as well. Some users like to “clean up” their C:\ drive on occassion, and your application may all of a sudden not work anymore. Plus, it makes curious users into dangerous users if they can directly access config files or who knows what: I meant, these are users we’re talking about, and you just never know what they might do.
So the question becomes “Is there a safe, reliable directory we can use to store and retrieve such files from?” The answer is yes! .NET provides access to a series of special folders, enumerated in Environment.SpecialFolder. (The Environment namespace is part of System, so does not need to be referenced, it is always just accessible) Following the link will show you the list of Special Folders, most of which are pretty straight forward, like My Computer, My Documents, etc. There is one in particular, though, that is not so straight forward, but is exactly what we need: LocalApplicationData. This is a directory buried within the User structure. On my XP box, the path looks like this: C:\Documents and Settings\Joel\Local Settings\Application Data. Underneath this directory are a listing of other directories, usually company names (Microsoft has one, as does Google), and inside those directories are directories for specific Applications.
This is where we want to store our persistant data. It is safe from being overwritten, does not require Administrator priveleges, and most curious users aren’t going to go tampering with it. Another good thing about this approach is that we are going to use a system name to get the path: we are not going to hard code this path structure! I don’t have a Vista machine yet, but there is no guarantee that Microsoft kept the same structure. What they will keep, however, is .NET’s ability to find the path of this folder on any given system.
To get the path, you need to pass the SpecialFolder enumeration value you want to the Environment.GetFolderPath method:
// Get Special Folder path string myLocalAppPath = Environment.GetFolderPath( Environment.SpecialFolder.LocalApplicationData );
Your application directory will not be automatically created beneath this path. You will need to check for the existence of it and create it if necessary. This would be an ideal task for a Custom Action in the Installer.
This should provide the ideal location for your application settings and persistent configuration files.