Master the basics of Windows registry access with .NET

Although .NET makes it easier to access the registry, it's still daunting for the uninitiated. Lamont Adams takes away some of the mystery.

The “old-timers” among us remember the days before the Windows registry, when applications stored configuration information between executions in text-based INI files. A few years ago, things changed (better or worse is a matter of opinion) when Microsoft told us developers that INI files were bad—so bad, in fact, that we should stop using them and start using this new thing called the registry. The registry was complicated, though, especially for VB6 developers, who, being afflicted with the cruel joke known as the SaveSetting and GetSetting functions, often had to resort to Win32 API registry functions to use it effectively.

Now, with the advent of .NET, those of us on planet Microsoft who are interested in using the registry have an easier time of it. The .NET class library includes a set of classes, Microsoft.Win32.Registry and Microsoft.Win32.RegistryKey, that provide intuitive wrappers for the Win32 registry access functions. Before looking at these classes in detail, let’s step back a bit and see how the registry is organized and how you’d typically use it in an application.

Breaking out in hives
If you’ve never worked with the registry before, it's best to think of it as you would the file system on a disk. You have folders, which translate to keys in the registry, subfolders (subkeys), and files (values). Each subkey may contain one or more named values, which are the actual data storage areas of the registry.

This analogy is useful as long as you realize that, while a disk will have a single root directory, the registry has several root keys, which are collectively referred to as hives. The number and names of these root keys will vary somewhat depending on which version of Windows you’re running. The hives found on Windows NT-based OSs are shown in Figure A.
Figure A
Hive name Intended use
HKEY_Local_Machine This stores information about the system’s hardware, security settings, miscellaneous configuration data for both applications and the operating system, startup settings, and services settings.
HKEY_Current_User This stores information pertaining to user-specific settings for the user currently logged in to the system, such as color preferences, environment variables, printer settings, and so on.
HKEY_Classes_Root This holds information useful for COM, OLE, and DDE support, as well as file association information.
HKEY_Users This permanently stores user-specific configuration information for all user accounts. This information is copied into HKEY_Current_User when the user logs in to the system.
HKEY_Performance_Data This is a phantom key not actually stored in the registry database but accessed through the registry API. It provides access to various pieces of performance data about the system and specific applications.
HKEY_Current_Config Actually a subkey of HKEY_Local_Machine, it stores systemwide dynamic configuration information.
Root keys and the data they are meant to contain

Most of the time, your work with the registry will fall into one of three categories:
  • Checking to see whether a specific key exists
  • Retrieving a value under a particular key
  • Saving a value under a particular key for later retrieval

Of these, the final two tasks will usually mean accessing keys located under subkeys of the HKEY_Local_Machine\Software key, which involves first navigating to the appropriate subkey and then locating and manipulating the appropriate value by name. Navigation to a subkey always begins with its root hive. For example, to access a subkey named MyKey found under HKEY_Local_Machine\Software, you’d open the subkey HKEY_Local_Machine\Software\MyKey and then work with any of the values it contains.

Start at the hives to access subkeys
The Registry class serves as the entry point to the registry by providing you with access to the root hives. Registry exposes seven static RegistryKey members, one for each of the hives you met in Figure A, plus one representing a Win9x-only hive: HKEY_Dyn_Data, which holds dynamic registry data not stored on disk. See Figure B for a look at how these static members map to the registry hives.
Figure B
Registry member Associated hive
LocalMachine HKEY_Local_Machine
CurrentUser HKEY_Current_User
ClassesRoot HKEY_Classes_Root
Users HKEY_Users
PerformanceData HKEY_Performance_Data
CurrentConfig HKEY_Current_Config
DynData HKEY_Dyn_Data
Hive to Registry member mapping

The RegistryKey class provides the methods you’ll use to navigate in the registry and access named values. The class’s OpenSubKey method accepts the case-insensitive name of a subkey, along with a Boolean value indicating whether the key should be opened for read-write access. It returns a new RegistryKey object representing the opened subkey. OpenSubKey also works when given a relative path to the subkey. (Just remember to properly escape backslashes as \\.) If the subkey doesn’t exist, OpenSubKey returns null/Nothing. Always remember to close an open subkey using the Close method.

To extend the above example, the VB.NET code to open HKEY_Local_Machine\Software\MyKey for read/write access would look like this:
Dim k as RegistryKey
k = Registry.LocalMachine.OpenSubKey(“Software\\MyKey”
, true)

Reading and storing values
The GetValue and SetValue methods provide access to any named values found under a key. Although registry values are strongly typed, the .NET runtime does all the conversions for you, so you really don’t have to worry about type matching. GetValue is overloaded to allow you to specify a default value to return should the named value not exist, and it should go without saying that SetValue will fail if a key is opened without write access. Extending the above example a little further, suppose we want to retrieve the numeric “ValueA” and save a string as “ValueB” under the MyKey subkey I opened above:
Dim j as Integer
k.SetValue(“ValueB”, “String Value”)
j = k.GetValue(“ValueA”)

Here’s the code to accomplish the same thing in C#:
RegistryKey k = Registry.LocalMachine.OpenSubKey(
“Software\\MyKey”, true);
k.SetValue(“ValueB”,”String Value”);
int j = k.GetValue(“ValueA”);

Easy access
Unless you’ve had the…pleasure…of using the Win32 API to access the registry, you’ll likely not be able to truly appreciate how easy .NET makes it. In any event, you should have no excuses left for not using the registry to store your application’s configuration information.

Suggest additional topics
What other aspects of using the registry would you like to see explored on Send us an e-mail with your suggestions, or post them to the discussion below.


Editor's Picks