- Windows Registry
- Using the Registry to Store Information for Your .NET Application
Using the Registry to Store Information for Your .NET Application
As Figure 1 illustrates, an application can create one or more Registry keys as a collection point for all the information it stores. The application then reads and writes Registry values containing the desired data. By convention, application programs will normally use subkeys relative to \HKEY_LOCAL_MACHINE\SOFTWARE for storing their data.
In the Microsoft .NET Framework, the Registry class provides complete access to the Windows Registry. The Registry hives are exposed as seven read-only root RegistryKey instances: CurrentUser, LocalMachine, ClassesRoot, Users, PerformanceData, CurrentConfig, and DynData. Include a reference to the Microsoft.Win32 namespace to instantiate these classes.
Getting a Registry Key Reference
Listing 1 illustrates a method for creating or opening a specified Registry key. The method accepts two string arguments: a base key name, followed by a subkey name. It will return an instance of the RegistryKey class, which will be null if an exception occurs.
First, the OpenSubKey method of the Registry.LocalMachine instance is used to attempt to get a reference to the specified base key. The second argument of this method is a Boolean value that specifies whether or not write access to the key is required. If the desired base key cannot be found, then the method will attempt to create one.
Next, the CreateSubKey method of Registry.LocalMachine is used to get a reference to the desired subkey. CreateSubKey will return a reference to a specified key if it already exists or to a newly created one if it does not. Finally, the method returns the reference to the key, which can be checked against null for success.
Listing 1Method for Creating or Opening a Registry Key
public static RegistryKey GetKey(string baseKey, string subKey) { RegistryKey key; /* --- Resolve (create or open) Base Key --- */ try { key = Registry.LocalMachine.OpenSubKey(baseKey, true); if (key == null) { key = Registry.LocalMachine.CreateSubKey(baseKey); } else { Console.WriteLine("Base key resolved"); } } catch (Exception e) { // Exception logging omitted for brevity return null; } /* --- Resolve (create or open) Sub Key --- */ try { key = Registry.LocalMachine.CreateSubKey(baseKey + "\\" + subKey); if (key == null) { throw(new Exception("Error creating SubKey")); } else { Console.WriteLine("Subkey resolved"); } } catch (Exception e) { // Exception logging omitted for brevity return null; } return key; }
Storing Registry Values
Storing and retrieving Registry values is quite simple. Listing 2 illustrates the syntax for writing a value to the Registry using the SetValue method of the RegistryKey class. There is no separate method for creating a value. If the value already exists, then SetValue will update it. If it does not already exist, it will automatically be created.
Listing 2Example of Creating or Setting a Registry Value
public static void SetValue(RegistryKey key, string valueName, object valueValue) { try { // In production code, you would validate the arguments key.SetValue(valueName, valueValue); Console.WriteLine("Key value set OK"); } catch (Exception e) { Console.WriteLine("Error setting key value: {0}", e.ToString()); } }
The valueName argument can be set either to null or to an empty string to set the default value for the specified key.
As far as I know, there is currently no way to specify the Registry data type of the value being passed. The argument is apparently interpreted when passed and classified as either numeric, binary, or string. All string arguments are interpreted to be of the type REG_SZ, so parsing and evaluating REG_MULTI_SZ and REG_EXPAND_SZ data on Registry reads must be done manually (see the ExpandEnvironmentVariables method of the Environment class for additional information).
Retrieving Registry Values
Use the GetValue method of the RegistryKey class to read a value from the Registry. GetValue is an overloaded method with two forms. The simplest is
public object GetValue(string name);
This method accepts a string parameter that specifies the name of the Registry value to read. It returns an object containing the requested value or null if the value does not exist. Listing 3 is an example of how to use GetValue to return a string containing a specified value.
Listing 3Example of Reading a Known Registry Value
public static string GetTest(string SubKey, string Name) { string ds = null; RegistryKey key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\HSL\\" + SubKey); if (key != null) { ds = key.GetValue(Name).ToString(); } return ds; }
The other form of the GetValue method is
public object GetValue(string name, object defaultValue);
This form of the method allows you to pass a second argument containing an object that specifies a default value to return if name does not exist.
Note that the Windows Registry is not, by itself, a secure storage mechanism. Information stored in the Registry is available to other applications and through user identities other than the ones used to store it. Sensitive information, such as passwords, must be encrypted before being written to the Registry.
This article has introduced only the basics of storing and retrieving runtime information in the Windows Registry. A future article will discuss more advanced Registry topics, such as reading and writing the Windows Registry on remote machines, as well as storing and retrieving encrypted data.