Thursday, May 14, 2009

Read and Write Regedit Win32 by C#

From: http://www.codeproject.com/KB/system/registry1.aspx

- Only backup this aritcle for me ^^'

Issues covered

This article is the first part of a 2-part article. This part explains how to:

  • Access registry keys
  • Create new subkeys
  • Get or set an existing value's data
  • Delete subkeys
  • Get a list of subkeys
  • Close a subkey

Table of contents

Introduction

The registry is a Windows� specific storage repository where you store information about applications, users, and default system settings. The registry comes handy when your application is being closed, and you want to store data somewhere until your application is re-opened.

Since the registry is Windows� specific, it uses an exclusive namespace: Microsoft.Win32.

A bit of theory

The registry is something like a big database. All data are stored in a format similar to the key-value pair model, which means that you will have some key (something like a variable) and an associated value for it. For example:

Collapse
Key: "ForeColor"
Value: "Red"

implies that we have a key ForeColor, whose value is Red. The difference in the format used in the registry is that, instead of a key-value pair, it uses a value-data pair; hence in this example, ForeColor is the value for which the data is Red.

To understand the structure of the registry, take a look at your own machine's registry. Run the Registry Editor by executing regedit.exe in the Start->Run dialog box. A new window opens up similar to Windows Explorer. Collapse all branches in the left if they aren't already. What you see is a hierarchical collection of folders below My Computer, each defined for one unique purpose and better organization. Go to any folder. On the right, you will see a detailed view of some value(s) along with their respective data.

Windows stores quite a huge amount of data in the registry. In addition, most of the installed applications in a user's machine stores their own settings in the registry too. For being the repository of such a mammoth collection of data, the registry requires to be organized well. It's for that reason the registry is divided into a clean set of hierarchical folders you just saw.

Now it's time you geared up for some code.

The code explained

The naming convention

One problem you will probably encounter when you deal with the registry is the mix up between the different names used to represent the various elements of the registry. So, before we continue on to the code, we will get this right. There are basically four elements in the registry: root key, subkey, value and data. Refer to the screenshot of the Registry Editor given below to understand them.

Naming convention

As you might have guessed from the image, there are two classes you will need whenever you work with the registry in .NET: Microsoft.Win32.RegistryKey and Microsoft.Win32.Registry. The RegistryKey class is used to represent any subkey in the registry. The Registry class, on the other hand, is used to represent only the root keys in the registry. Root keys are nothing but special kind of subkeys - they form the top-level keys in the registry. Ultimately, whichever key you select, it will be of the type RegistryKey. Refer to the image once again and make sure that everything is clear. If done, let's move on to some code.

Selecting a subkey

Irrespective of what you want to do with the registry, you will have to select some subkey first. To select a subkey, you need to access the subkey's root key first. Once you select a root key, you need to create a new RegistryKey object to obtain access to your subkey.

So, first, we will select a root key. All the root keys are listed in Microsoft.Win32.Registry as fields. To select a root key, you use the respective field in the Microsoft.Win32.Registry class. The important fields are:

Field Name Use Description
ClassesRoot to access HKEY_CLASSES_ROOT info on file-types, components, etc.
CurrentConfig to access HKEY_CURRENT_CONFIG current hardware info
CurrentUser to access HKEY_CURRENT_USER info about current user
LocalMachine to access HKEY_LOCAL_MACHINE config info about current machine
Users to access HKEY_USERS info on the default user config

Note that since the root keys form the life and soul of the registry, these fields are all read-only. They are used to create subkeys under them and not to modify them as such.

After selecting a root key field, we need to create a new RegistryKey object. For this, you call either the static RegistryKey.OpenSubKey or the RegistryKey.CreateSubKey method on the respective root key field you selected. First let's see how to create a new subkey with RegistryKey.CreateSubKey method.

Creating new subkeys

To create a new subkey, you use the RegistryKey.CreateSubKey method, whose definition is:

Collapse
public RegistryKey CreateSubKey(string subkey);

where the string subkey represents the name or path of the subkey to create. Usually, this is of the form: key name\Company Name\Application Name\version. For example, any Windows� entry is situated in: SOFTWARE\Microsoft\Windows. You could check this out for yourself by opening the registry.

This method either returns the subkey or returns null and raises an exception if there has been an error. Possible reasons for failure are lack of permission, non-existence of any such key etc. All exceptions are dealt with in Part 2 of this article.

Usage example:

Collapse
...
RegistryKey MyReg = Registry.CurrentUser.CreateSubKey
("SOFTWARE\\SomeCompany\\SomeApp\\SomeVer");
...

which creates a new subkey under the CurrentUser root key with the specified path and returns the RegistryKey object representing the subkey.

A few notes:

  • if there already exists a subkey with the same name as you passed in the parameter subkey, then that subkey is returned; nothing new is created. So, you could in fact use the CreateSubKey method to both create or open a subkey.
  • the CreateSubKey method always returns the subkey in the write mode (of course!).
  • if you call CreateSubKey again (after already creating a subkey), new child subkeys below the present subkey are created.

Opening existing subkeys

To open an existing subkey, you use the RegistryKey.OpenSubKey method. You invoke it like:

Collapse
RegistryKey MyReg = Registry.CurrentUser.OpenSubKey(...);

The OpenSubKey has two overloads:

Collapse
public RegistryKey OpenSubKey(string name);

which returns the subkey in read only mode, and,

Collapse
public RegistryKey OpenSubKey(string name, bool writable);

which returns the subkey in the mode specified by the bool writable - write mode if writable is true, read mode if false. In both of these methods, the string name represents the path to the subkey you want to open.

So, set the path and pass it to the method. If everything goes fine, you are returned the RegistryKey object. Else, you are returned null. Possible reasons for failure are the same as mentioned before.

For example:

Collapse
...
RegistryKey MyReg = Registry.CurrentUser.OpenSubKey
("SOFTWARE\\SomeCompany\\SomeApp\\SomeVer", true);
...

returns the RegistryKey object from the CurrentUser root key with the specified path in write mode, provided the subkey exists.

Getting a value's data

Once (and only if) you have a valid RegistryKey object, you are ready to access the subkey's values and their data. First, let's see how to retrieve data. For obtaining the data associated with a value in a subkey, you use the RegistryKey.GetValue method. It's invoked like this:

Collapse
someRegistryKeyobject.GetValue(...);

The GetValue method had two overloads:

Collapse
public object GetValue(string name);

which returns the data associated with the value represented by name in the subkey, or null if the value doesn't exist, and,

Collapse
public object GetValue(string name, object defaultValue);

which returns the data associated with the value represented by name in the subkey, or the default value specified by the object defaultValue.

As is evident, GetValue returns data of type object. So you will have to type cast it into the appropriate type you want.

Setting a value's data

Now, we will see how to set the data of a value. For this, we use the RegistryKey.SetValue method with the definition as follows:

Collapse
public void SetValue(string name, object value);

The string name represents the name of the value to store the data in. The object value represents the data you want to store. Since value is of type object, you could pass any object to it. It gets converted to DWORD, binary or string internally. And that's the reason why RegistryKey.GetValue method returns data in the type object and not the original types.

To store data in a subkey's default value, just set name as an empty string.

Closing a subkey

Once you have done with accessing your subkey, you need to close it. It's only when you close the subkey that modifications made are written to the registry (a process known as 'flushing'). You use the RegistryKey.Close method for closing a subkey.

An example code

Collapse
...
RegistryKey MyReg = Registry.CurrentUser.CreateSubKey
("SOFTWARE\\SomeCompany\\SomeApp\\SomeVer");
int nSomeVal = (int)MyReg.GetValue("SomeVal", 0);
MyReg.SetValue("SomeValue", nSomeVal+1);
MyReg.Close();
...

See, it's quite simple!

Miscellaneous stuff

All that had been dealt with until now were pretty basic stuff. Now let's move on to things that even though you may not use, are useful under some circumstances.

Deleting a subkey

To delete a subkey, use any one of the 2 overloads of the RegistryKey.DeleteSubKey method:

Collapse
public void DeleteSubKey(string subkey);

which deletes the subkey specified in subkey (provided, the subkey exists and no child keys or child subkeys are present in it), and,

Collapse
public void DeleteSubKey(string subkey, bool throwOnMissingSubKey);

which deletes the subkey specified in subkey (with the same condition stated above), and if the subkey can't be found, it raises an exception if throwOnMissingSubKey is true.

Deleting an entire tree

To delete an entire subkey tree including child keys, values etc., you use the RegistryKey.DeleteSubKeyTree method:

Collapse
public void DeleteSubKeyTree(string subkey);

You should know what the parameters mean, by now.

Deleting a value

To delete values, use any of the 2 overloads of the RegistryKey.DeleteValue method:

Collapse
public void DeleteValue(string name);

where if a value with name specified in name exists, it is deleted; else an exception is thrown, and,

Collapse
public void DeleteValue(string name, bool throwOnMissingValue);

which is the same as the previous overload, except that an exception is thrown only if the bool parameter throwOnMissingValue is true.

To get a list of subkeys

To obtain a list of all the subkeys (child keys) that exist within your present RegistryKey object, use the RegistryKey.GetSubKeyNames method:

Collapse
public string[] GetSubKeyNames();

which returns a string array.

To get a list of value names

To obtain a list of all the values that exist within your present RegistryKey object, use the RegistryKey.GetValueNames method:

Collapse
public string[] GetValueNames(); 

which returns a string array.

To flush manually

If you want to flush manually, you call the RegistryKey.Flush method. When you call the RegistryKey.Close method, the object is automatically flushed, so you needn't flush manually unless in the most necessary circumstances.

Collapse
public void Flush();

End of Part 1

This article focused in getting you acquainted with how to do basic stuff with the registry. In the next article - part 2, the prime focus will be upon security and permissions regarding the registry, exceptions thrown by the different methods when accessing the registry etc.

P.S.: As Microsoft� always warns, backup your registry before you play with it :-)

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Rakesh Rajan


Member
Rakesh Rajan is a Software Engineer from India working at Technopark, Trivandrum in Kerala. He is a Microsoft MVP and an MCSD (.NET) with a few other certifications, and had been working in .NET for the past 3 years. He graduated majoring in Computer Science during his memorable days at Ooty (a wonderful hill station in Southern India). You can find him posting at newgroups, writing articles, working on his own projects or taking some time off by listening to music by Enya or Yanni, or reading an Archer or Sheldon.

Find his online publications here.

Rakesh blogs at http://rakeshrajan.com/blog/ and maintains a site http://rakeshrajan.com/.
He used to blog at http://www.msmvps.com/rakeshrajan/.

Drop him a mail at rakeshrajan {at} mvps {dot} org.

Occupation: Web Developer
Location: India India

No comments:

Post a Comment

Popular Posts