Welcome to Dream.In.Code
Getting C# Help is Easy!

Join 136,585 C# Programmers for FREE! Get instant access to thousands of C# experts, tutorials, code snippets, and more! There are 2,049 people online right now. Registration is fast and FREE... Join Now!




Working with Windows Registry in C#

 
Reply to this topicStart new topic

> Working with Windows Registry in C#

PsychoCoder
Group Icon



post 23 Dec, 2007 - 07:15 PM
Post #1


In todays tutorial we are going to talk a walk-thru of working with the Windows Registry in C#. Working with and manipulating the registry can seem like a daunting task for the first time, but once you dive into it it's not such a scary thing.

NOTE: Manipulating the Windows Registry can have serious adverse affects on your computer. It is always a good idea to backup your registry before making any changes, that way if you do something wrong you have the original to fall back on. To backup your registry follow these steps:

  • Click the Start button
  • Select Run
  • When the Run Dialog opens type regedit and click OK
  • When Regedit opens click on File
  • Then select Export
  • When the Save As dialog opens select where you'd like to save and give it a name
  • Under Export Range select the All radio button
  • Then click Save


Your Registry is now saved (depending on the size of your registry exporting it can take a couple minutes). Before we jump into working with the Windows Registry, lets take a look at what exactly the Windows Registry is and what it consists of.

The Windows Registry is a repository for a computers configuration, it contains information such as:

  • Profiles for each user
  • All programs installed on the computer, and their configuration
  • Property settings for things like icons, folders, programs to start when Windows start, etc.
  • All hardware in the computer
  • All ports and what programs/hardware are using them


The Windows Registry is a hierarchal tree, it consists of Keys, Sub Keys, Predefined Keys, Hives, and Value Entries. Lets take a look at each of these items:
  • Key: A key is a node in the Registry Tree, for example SOFTWARE is a Key of HKEY_LOCAL_MACHINE
  • Sub Key: A Sub Key is a Key within a Key, for example Microsoft is a SubKey of SOFTWARE
  • Predefined Keys: A Key that represents one of the main sections of the Registry. There are 5 Predefined Keys
    • HKEY_CURRENT_USER : Contains the configuration for the currently logged on user
    • HKEY_USERS: Contains all loaded user profiles on the computer
    • HKEY_CLASSES_ROOT: Stores all information necessary to make sure that the correct program executes when you open a file in Windows Explorer
    • HKEY_LOCAL_MACHINE: Contains all configuration information for the computer
    • HKEY_CURRENT_CONFIG: Contains all the configuration information for the computer for the currently logged in user
  • Hive: A group of keys, sub keys and values in the registry. The 5 Predefined keys are each a Registry Hive
  • Value Entries: The value of the sub key in each key


Now that we have a high-level overview of what the registry is, what it contains and it's primary function, lets take a look at some code to manipulate, read from, and write to the Windows Registry. To facilitate working with the Windows Registry I created a Wrapper Class, so I didn't have to retype the same code over and over whenever I needed to work with the Registry. That way all I have to do is add a reference to the DLL and use it in any application I need to (even a C# application).

Unlike the VB.Net version (Version 1.0), this C# version (Version 2.0) uses properties, this allows the users to not have to pass all the parameters in the signature of the method,k simply set the properties needed for that method, then call the method you need. Version 2.0 also has an added method that allows you to retrieve all the child keys for a given subkey.

Before any of these methods will work you will need to add a reference to the Microsoft.Win32 Namespace. To do this add the following line at the top of your class (by the way, this is a Class Library Project, not a Windows Application project)


CODE

using System;
using Microsoft.Win32;
using System.Collections;
using System.Windows.Forms;
using System.Collections.Generic;



NOTE:It is the Microsoft.Win32 is the Namespace that gives us all the Methods, Classes and Events we need for working with the registry.

As I stated before, in Version 2.0 of this wrapper class we have public properties that allows us to not have to pass so many parameters in the signatures of the methods in the new version of my registry wrapper class. Here are the variables for our Version 2.0 of our wrapper class:


CODE

#region Variables
/// <summary>
/// property value to hold the key to look for
/// </summary>
private string _key;

/// <summary>
/// property variable to hold the name of the key
/// </summary>
private string _keyName;

/// <summary>
/// property variable to hold the main
/// registry key to start with
/// </summary>
private RegistryKey _mainKey;

/// <summary>
/// property variable to hold the success value
/// of any of the processes in the wrapper class
/// </summary>
private bool _success;
#endregion



Next we will show the actual properties for our new wrapper class. As you can tell from the variables, we have properties for most things from the registry key we're looking for, to the success of the methods that return a bool(true/false) value, now for the properties for Version 2.0:


CODE

#region Properties
/// <summary>
/// property to hold the key we are looking for
/// </summary>
public string Key
{
    get { return _key; }
    set { _key = value; }
}

/// <summary>
/// property to hold the name of the key we are looking for/deleting
/// </summary>
public string KeyName
{
    get { return _keyName; }
    set { _keyName = value; }
}

/// <summary>
/// property to hold the main registry key
/// we are starting our search in
/// </summary>
public RegistryKey MainKey
{
    get { return _mainKey; }
    set { _mainKey = value; }
}

/// <summary>
/// property to hold the success value (failed/succeeded)
/// of any of the processes on the wrapper class
/// </summary>
public bool IsSuccessful
{
    get { return _success; }
}
#endregion



NOTE: You will notice I use the #region...#endregion for the different sections of any class I write, this allows me to separate the different sections of my code into their own area, making it easier to find something.

Before we look at deleting keys, creating keys and so on, we really need to fid learn how to read to read a Registry key's value, this can be an invaluable action, especially is you modify the registry when installing your application, such as looking at what version is currently installed when doing an upgrade and so on. So first lets look at how to read the value of a registry sub key:


CODE

#region ReadRegistryValue
/// <summary>
/// Function to read a value from the Registry
/// </summary>
/// <param name="oNameValue">Object -> The value to be read</param>
/// <returns>True (Succeeded)/False (Failed)</returns>
/// <remarks>Created 22DEC07 -> Richard L. McCutchen</remarks>
public string ReadRegistryValue(ref object nameValue)
{
    //create a RegistryKey instance
    RegistryKey rkKey;
    //create a string variable to hold the value
    //of the sub key we're reading, we then initialize
    //it to an empty string to prevent a NullReferenceException
    //this variable will be used for returning the value of the
    //subkey we're reading
    string keyValue = string.Empty;
    try
    {
        //open the given subkey
        rkKey = _mainKey.OpenSubKey(_key, true);
        //check to see if the subkey exists
        if (rkKey == null)
        {
            //it doesnt exist
            //throw an exception
            throw new Exception("The Registry SubKey provided doesnt exist!");
        }
        //get the value
        nameValue = rkKey.GetValue(_keyName);
        //set the value of our return value, but
        //we need the ToString value since our
        //variable is a string type
        keyValue = nameValue.ToString();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Error: Reading Registry Value", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    //return the value to the calling method
    return keyValue;
}
#endregion



NOTE: Notice we use the ref reference, this allows us to pass a variable by reference, so if any changes are made during the method, the current value is returned to the calling method.


Another feature that comes in handy, especially when installing your application, is writing values to the registry. With this feature you can write the serial key of your application (if it requires a serial/key), the version, this comes in handy for application upgrades, applications last launch date, and especially for trial versions of software.

For doing this we have 2 methods, one creates the SubKey, which would more than likely be the name of your software or company, the 2nd writes the values to the sub keys, values like we mentioned above. The names of these 2 functions are as follows:

  • CreateRegistrySubKey
  • WriteSubKeyValue


Before we can add any values to our SubKey we need to actually create a sub key. The following method will allow use to create our new SubKey, to do this we use the CreateSubKey Method to write the SubKey. Lets take a look at this method:


CODE

#region CreateRegistrySubKey
/// <summary>
/// Function to create a new SubKey in the Windows Registry
/// </summary>
/// <param name="KeyPermissions">RegistryKepPermissionCheck -> Specifies permissions of the SubKey to be created</param>
/// <returns>True (Succeeded)/False (Failed)</returns>
/// <remarks>Created 22DEC07 -> Richard L. McCutchen</remarks>
public bool CreateRegistrySubKey(RegistryKeyPermissionCheck KeyPermissions)
{
    try
    {
        //use the CreateSubKey Method for creating our
        //new registry SubKey
        _mainKey.CreateSubKey(_key, KeyPermissions);
        //set out success variable to tru since it appears to
        //have gone well, the catch block will catch any Exceptions
        //that may occur
        _success = true;
    }
    catch (Exception ex)
    {
        //since an exception occurred we need to let the user know
        MessageBox.Show(ex.Message, "Error: Creating SubKey", MessageBoxButtons.OK, MessageBoxIcon.Error);
        //set our success variable to false since it failed
        _success = false;
    }
    //return the value to the calling method
    return _success;
}
#endregionregion



Now that you've created your SubKey you can add Value Entries to it using this function.


CODE

#region WriteSubKeyValue
/// <summary>
/// Writes a value in the Registry
/// </summary>
/// <param name="_mainKey">RegistryKey -> One of the 6 main keys that you want to write to</param>
/// <param name="_key">String -> Name of the subkey you want to write to. If the subkey doesnt
/// exist it will be created</param>
/// <param name="_keyName">String -> Name of the value to create</param>
/// <param name="oNameValue">Object -> Value to be stored</param>
/// <param name="RegType">RegistryValueKind -> Data type of the subkey value</param>
/// <returns>True (Succeedeed)/False (Failed)</returns>
/// <remarks>Created 22DEC07 -> Richard L. McCutchen</remarks>
public bool WriteSubKeyValue(object oNameValue, RegistryValueKind RegType)
{
    RegistryKey rkKey;
    try
    {
        //Open the given subkey
        rkKey = _mainKey.OpenSubKey(_key, true);
        //check to see if the subkey exists
        if (rkKey == null)
        {
            //doesnt exist
            //create the subkey
            rkKey = _mainKey.CreateSubKey(_key, RegistryKeyPermissionCheck.Default);
        }
        //set the value of the subkey
        rkKey.SetValue(_keyName, oNameValue, RegType);
        _success = true;
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Error: Writing Registry Value", MessageBoxButtons.OK, MessageBoxIcon.Error);
        _success = false;
    }
    return _success;
}
#endregion



The next aspect of working with the Registry is removing values from the Registry, be careful with this, you really shouldn't be removing values that aren't associated with your application unless you know what you are doing. As dangerous as it can be, it is a necessary evil as you don't want orphan sub keys and values in the registry for software that has been removed.

Before you can delete a SubKey, you need to delete all of its values first, if you try to remove a populated SubKey you will raise an Exception, so this is actually a 2 step process:

  • Delete a SubKey value
  • Delete the SubKey itself


First lets take a look at deleting a Sub Key value. This is one of the areas that the new properties come into play, instead of passing the MainKey, subkey and value you want to delete, simple set those properties and call the method without having to pass any parameters in the signature.

If you provide a Sub Key that doesn't exist it displays this error to you. First lets look at deleting a subkey value, this could be done in a loop, changing the value to delete on each iteration of the loop, thus deleting all the values at one time:


CODE

#region DeleteSubKeyValue
/// <summary>
/// Function to delete a subkey value from the Windows Registry
/// </summary>
/// <param name="_mainKey">RegistryKey -> One of the 6 main keys you want to delete from</param>
/// <param name="_key">String -> Name of the SubKey you want to delete a value from</param>
/// <param name="_keyName">String -> Name of the value to delete</param>
/// <returns>True (Succeeded)/False (Failed)</returns>
/// <remarks>Created 22DEC07 -> Richard L. McCutchen</remarks>
public bool DeleteSubKeyValue()
{
    RegistryKey rkKey;
    try
    {
        //open the given subkey
        rkKey = _mainKey.OpenSubKey(_key, true);
        //check to make sure the subkey exists
        if ((_key != null))
        {
            //subkey exists
            //delete the subkey
            _mainKey.DeleteValue(_keyName, true);
            _success = true;
        }
        else
        {
            _success = false;
            //subkey doesnt exist
            //throw an exception
            throw new Exception("The SubKey provided doesnt exist! Please check your entry and try again");
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Error: Deleting SubKey Value", MessageBoxButtons.OK, MessageBoxIcon.Error);
        _success = false;
    }
    return _success;
}



The next function deletes the Sub Key itself. Remember, when you delete a Sub Key all the Value Entries it contained are deleted as well. This method checks to ensure the SubKey being passed actually exists, if a null value is returned it throws an Exception letting you know that you provided an invalid SubKey value.

So now lets take a look at this method for deleting a SubKey:


CODE

#region DeleteRegistrySubKey
/// <summary>
/// Function to delete a SubKey from the Windows Registry
/// </summary>
/// <returns>True (Succeeded)/False (Failed)</returns>
/// <remarks>Created 22DEC07 -> Richard L. McCutchen</remarks>
public bool DeleteRegistrySubKey()
{
    RegistryKey rkKey;
    try
    {
        //open the given subkey
        rkKey = _mainKey.OpenSubKey(_key, true);
        //check to make sure the subkey exists
        if ((_key != null))
        {
            //subkey exists
            MainKey.DeleteSubKey(_key, true);
            _success = true;
        }
        else
        {
             _success = false;
            //subkey doesnt exist
            //throw an exception letting the user know
            throw new Exception("The SubKey provided doesn't exist. Please check your entry and try again.");
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Error: Deleting SubKey", MessageBoxButtons.OK, MessageBoxIcon.Error);
        _success = false;
    }
    return _success;
}
#endregion


As promised, in Version 2.0 I have added a new method in my wrapper class. This method allows you to retrieve all the value for a provided SubKey, this can come in handt to ensure all you values were entered during the installation. Like the previous method, this method also checks to ensure you have provided a valid SubKey, otherwise an Exception is raised letting you know so you can check the value provided.

This method uses the GetSubKeyNames to return all the names in the provided SubKey. We then loop through all the names returned and add them to our list. For this we use a List<T> Generics list (new to .Net 2.0) of type string to hold the string value of the names returned:


CODE

#region GetAllChildSubKeys
/// <summary>
/// Function to retrieve all the child subkeys of a SubKey in the Windows Registry
/// </summary>
/// <returns>An ArrayList of all the child subkeys</returns>
/// <remarks>Created 22DEC07 -> Richard L. McCutchen</remarks>
public List<string> GetAllChildSubKeys()
{
    RegistryKey rkKey;
    //RegistryKey to work with
    string[] sSubKeys;
    //string array to hold the subkeys
    List<string> arySubKeys = new List<string>();
    //arraylist to return the subkeys in an array
    try
    {
        //open the given subkey
        rkKey = _mainKey.OpenSubKey(_key);
        //check to see if the subkey exists
        if (!(_key == null))
        {
            //subkey exists
            //get all the child subkeys
            sSubKeys = rkKey.GetSubKeyNames();
            //loop through all the child subkeys
            foreach (string sub in sSubKeys)
            {
                //add them to the arraylist
                arySubKeys.Add(sub);
            }
        }
        else
        {
            //subkey doesnt exist
            //throw an exception
            throw new Exception("The SubKey provided doesn't exist. Please check your entry and try again.");
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Error: Retrieving SubKeys", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    //return the subkeys arraylist
    return arySubKeys;
}

#endregion



There you have it, a wrapper class for working with the Windows Registry. It is much easier than expected in .Net, I can remember working with the Windows Registry in VB6 and it was, to say the least, a nightmare. .Net made a programmers life some much easier.

I am providing both the source code and the DLL for this wrapper class, it is under a GNU General Public License so I request you leave the License Header in place. With the GNU General Public License you are free to modify this code, distribute it as you see fut, but the license and license header need to stay in place. Thanks for reading, and I hope you found this tutorial helpful and informative.

Happy Coding!

Attached File  PC_RegistryWrapper.zip ( 45.11k ) Number of downloads: 260
Go to the top of the page
+Quote Post


Register to Make This Ad Go Away!


Fast ReplyReply to this topicStart new topic
2 User(s) are reading this topic (2 Guests and 0 Anonymous Users)
0 Members:

 

Lo-Fi Version Time is now: 12/3/08 01:00AM

Live C# Help!

C# Tutorials

Reference Sheets

C# Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month