Home About

November 24th, 2008

Modifying the Windows Registry in C# - 0

One wrong move and your dead, or at least your computer. Nothing is more nerve wracking than manipulating the Windows Registry. In the following example we show how you can (safely!) create your own little part of the registry and store and retrieve your applications configuration. Which is a nice way to store user names, passwords and anything else that you fancy.

The registry is Windows central database of information on all its settings, stored there by applications, drivers and system software. If you have never worked with the registry before then start the “regedit” program on your computer — just be careful not to change anything!

As you can see from the image above, the registry is a tree structure. There are nodes, and each can have sets of names/values and further sub-nodes.

Why would you want to access the registry?

  1. To look up system configuration information stored by Windows (there are thousands of these)
  2. To store your applications configuration

In this example we will only be looking at the second reason, storing your applications information. The example will shows you how to create your own sub tree. As one computer can have more than one user using it your application will typically store its settings separately for each user.

The registry is accessed in C# through the Microsoft.Win32 namespace. The most important classes are:

  • Microsoft.Win32.Registry – this class provides access to the registry
  • Microsoft.Win32.RegistryKey – this class represents a key in the registry

Creating our own keys

We are looking to store our applications data for the current user only. Microsoft.Win32.Registry.CurrentUser provides us with a RegistryKey to the root of the CurrentUser tree in the Registry. As can be seen in the above graphic, the “Software” section of CurrentUser is where programs store their information:

To create our own little section (called “ourapp”) we need to create a sub-key here:


string OurAppKeyStr = @”SOFTWARE\OurApp”;
RegistryKey OurAppRootKey = CurrentUserKey.CreateSubKey (OurAppKeyStr);

To keep it interesting we create the following structure:


[HKEY_CURRENT_USER\software\ourapp]
[HKEY_CURRENT_USER\software\ourapp\config]:X
[HKEY_CURRENT_USER\software\ourapp\config]:Y
[HKEY_CURRENT_USER\software\ourapp\users]:Name
[HKEY_CURRENT_USER\software\ourapp\users]:Password

So below our Applications key, we need two more sub-keys: config & users. These are created in the same fashion as our applications key:


RegistryKey ConfigKey = OurAppRootKey.CreateSubKey(“config”);
RegistryKey UsersKey = OurAppRootKey.CreateSubKey(“users”);

To add values to the registry, we simply add them to the keys we have created. The SetValue() function takes a name/value pair. It defaults to “String” , but for the example we are a little more explicit. The RegistryValueKind enum provides us with the types possible:

RegistryValueKind.Binary Binary data
RegistryValueKind.DWord 32-bit number
RegistryValueKind.QWord 64-bit number
RegistryValueKind.ExpandString “This is a string with %PATH%” in it, the %PATH% is expanded on query
RegistryValueKind.MultiString An Array of String[]
RegistryValueKind.String A regular string

To set a value we simple call:


ConfigKey.SetValue(“X”,12,RegistryValueKind.DWord);
UsersKey.SetValue(“Password”,”35a6a$”,RegistryValueKind.String);

We need to ensure that the data is writing to the registry:


ConfigKey.Flush();
UsersKey.Flush();

The PrintTree() function in the example shows how we can travel through and explore through the tree recursively. For a given key, we can query GetSubKeynames which returns an string array of names. Using the name a call to OpenSubKey returns a new RegistryKey. In turn we can then call GetSubKeyNames on that key again.


foreach (string SubKeyName in Root.GetSubKeyNames())
PrintTree(Root.OpenSubKey(SubKeyName));

Because your windows registry is probably already crowded with information we will clean up at the end of the example by removing our created tree. We do not have to step through the tree and delete each sub-tree individually. Instead DeleteSubKeyTree removes an entire sub tree (and as this function is quite dangerous, use it with care!)


// Remove the “OurApp” subtree from the Registry
CurrentUserKey.DeleteSubKeyTree(OurAppKeyStr);

The Example Code

using System;
using Microsoft.Win32;

namespace RegistryTest
{
    class MainClass
    {

        // PrintTree
        //
        // This routine recursively steps through the registry
        // and prints each sub tree and its values
       
        public static void PrintTree(RegistryKey Root)
        {
            // Print the name of the current key
            Console.WriteLine("{0}",Root.Name);
           
            // Check if this key has any other subkeys
            // If so, travel deeper into the tree
            foreach (string SubKeyName in Root.GetSubKeyNames())
             PrintTree(Root.OpenSubKey(SubKeyName));

            // Print each of the values for this key
            foreach(string RootName in Root.GetValueNames())
                Console.WriteLine("{0}={1}",RootName,
                                            Root.GetValue(RootName) );
        }
       
        public static void Main(string[] args)
        {
            // Obtain a link to the current users registry entries
            RegistryKey CurrentUserKey = Microsoft.Win32.Registry.CurrentUser;
            RegistryKey OurAppRootKey = null;
            RegistryKey ConfigKey = null;
            RegistryKey UsersKey = null;
                       
            // Create a section for our application
            // Note: The @ in front of the string ensures that the compiler ignores the slash
            string OurAppKeyStr = @"SOFTWARE\OurApp";
            OurAppRootKey = CurrentUserKey.CreateSubKey (OurAppKeyStr);
           
            // Save the X,Y values
            ConfigKey = OurAppRootKey.CreateSubKey("config");
            ConfigKey.SetValue("X",12,RegistryValueKind.DWord);
            ConfigKey.SetValue("Y",20,RegistryValueKind.DWord);
           
            // Save the username , password values
            UsersKey = OurAppRootKey.CreateSubKey("users");
            UsersKey.SetValue("Name","Martijn",RegistryValueKind.String);
            UsersKey.SetValue("Password","35a6a$",RegistryValueKind.String);           
           
            // Flush all the changes
            ConfigKey.Flush();
            UsersKey.Flush();
           
            // Print a tree of our applications keys
            PrintTree(OurAppRootKey);
           
            // Remove the "OurApp" subtree from the Registry
            CurrentUserKey.DeleteSubKeyTree(OurAppKeyStr);

        }
    }
}

Using the Registry with Mono

Although Unix does not have a registry as such it is still possible to use the above code under Mono. If you are looking in the registry for Windows specific configuration values — or those stored by other Windows only applications — you will come up empty. This registry is just a shell. It however provides a good cross-platform method of storing your own configuration values.

Mono will create a tree of small XML files under the users home directory. So for example, in our example we created the key “HKEY_CURRENT_USER\software\ourapp\config” which is stored in an XML file. This XML file is located in the following directory:

~/.mono/registry/CurrentUser/software/ourapp/config

The values we stored are kept in a file called values.xml:

<values>
<value name="X" type="int">12</value>
<value name="Y" type="int">20</value>
</values>

Image credit: Florian

Be Sociable, Share!

Tags: , ,

Comments are closed.


Most popular
Recent Comments
  • ARS: great plugin! I love it! but, it will be so nice if you can add attribute ‘title’ as one of...
  • Nelson: Saved me from doing it myself. Good article.
  • andy: i am currently playing taiwanese server wow in 奈辛瓦里(PVP) and i would like to realm transfer to somewhere there...
  • berties: any english speaking playing on a taiwanese server?
  • web application development: has C# search volume really so constant over the years? really surprising.