Page 1 of 1

Working with Windows Registry in C#

#1 PsychoCoder  Icon User is offline

  • Google.Sucks.Init(true);
  • member icon

Reputation: 1639
  • View blog
  • Posts: 19,853
  • Joined: 26-July 07

Posted 23 December 2007 - 08:15 PM

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)


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:


#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:


#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:


#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:


#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.


#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:


#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:


#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:


#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: 2656

Is This A Good Question/Topic? 3
  • +

Replies To: Working with Windows Registry in C#

#2 Guest_nethsu*


Reputation:

Posted 17 August 2010 - 10:31 PM

Hey can u add another class to run this dll??? as im really new to c sharp
Was This Post Helpful? 0

#3 aaron1178  Icon User is offline

  • Dovakiin, Dragonborn
  • member icon

Reputation: 169
  • View blog
  • Posts: 1,298
  • Joined: 22-October 08

Posted 15 November 2010 - 04:34 PM

Nice Tutorial PsychoCoder, i was searching the MSDN for this and could not find such detail. I have a question. Im making an installer right? to add registry values, would this make it an Installed program? like say i run the installer for a game, once its installer, i go to the start menu and it says a new program is installed, is this done VIA Registry?

Thanks Aaron1178
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1