Monday, August 31, 2009

C# Registry Basics

C# Registry Basics  
Introduction: The Registry

(Feel free to skip over this section if you’re already comfortable with what the registry does, and how to use the regedit utility to browse the registry)

Modifying the registry has to be one of a user’s worst nightmares: make one wrong move and you’re dead. A friend recently called me up, saying “These instructions are telling me to modify my registry... but what if I mess up”?

If only we were so lucky: As Windows developers, we can only get so far before we’re forced to delve into the registry.

“The Registry”, if you’re not already familiar, is a sort of central Windows database. It’s used both by the operating system and by Windows applications to store persistent information; that is, information that sticks around even when you close your application or turn your computer off. For example, the registry is used by Windows to store file associations (Mappings between file extensions and their associated programs). When you double-click on a file in Windows Explorer, this registry data is used to make the decision: Is there a program installed on the system to open a file of this type?

Aside from file associations, the registry is used by Windows applications to store all sorts of information. Some of this information is obvious; user preferences for example. Other kinds of information, like window positions, are more subtle.

Most likely, you’re already familiar with the regedit utility. If you’re not, click on Start, Run, and enter “regedit”. Be forewarned: The data contained in the registry is very important to your system’s health. Bad edits can damage your system.

http://www.devhood.com/tutorials/images/264/1.jpg

You’ll notice what seem to be folders, which form a seemingly endless hierarchy. At the leafs of this tree lie the actual registry values. These values come in a few different flavors (Click the Edit menu item, followed by New to see a list).

Using the Registry With C#

We’ll mostly be concerned with the part of the hierarchy labelled HKEY_CURRENT_USER; it is here that, you guessed it, user-specific settings are stored. More specifically, we’ll be dealing with HKEY_CURRENT_USER\Software\[Company Name]. Since we’re not a company, we’ll simply use “Play” in place of the company name.

Go ahead and create a new workspace in Visual Studio.NET.
  • File, New, Project
  • Type “RegPlay” in the Name field and click Ok.

A workspace will be created for you. To get started, we need to explicitly reference Microsoft.Win32 within our code. To do this, right click on the form (Somewhere inside all of that grey area) and select “View Code”. You show now see:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
...

Add the line:
using Microsoft.Win32;

This will allow us to make use of Windows registry functionality within our C# program. Now close this code window to get back to Form1, and double click the form to re-open the Form1.cs* code window, but at the position Form1_Load.

Before we go any further, let’s consider how we will store information within the registry. The location will be HKEY_CURRENT_USER\Software\Play\WindowPos; this path is called the “key”, and it can be thought of much like a folder. We’ll use this key to create two values, X and Y, which will hold the coordinates of Form1. These values, X and Y, are like files, if we continue to use our key-as-folder analogy.

Add the following code to Form1_Load:
// Attempt to open the key
RegistryKey key = Registry.CurrentUser.OpenSubKey( "Software\\Play\\WindowPos" );
// If the return value is null, the key doesn't exist
if ( key == null )
{
    // The key doesn't exist; create it / open it
    key = Registry.CurrentUser.CreateSubKey( "Software\\Play\\WindowPos" );
}
// Attempt to retrieve the value X; if null is returned, the value
// doesn't exist in the registry.
if ( key.GetValue( "X" ) != null )
{
    // The value exists; move the form to the coordinates stored in the
    // registry.
    Location = new Point( (int)key.GetValue( "X" ), (int)key.GetValue( "Y" ) );
}

Here, we attempt to retrieve the X and Y values from the HKEY_CURRENT_USER\Software\Play\WindowPos key. If the values exist, we move the form to the appropriate location. This is done by setting the Location of our form. Location is of type Point, so we first create a Point object, initialize it with the appropriate values from our registry-lookup, and then assign it as the new value of Location. At this point, though, the form’s position has never been saved, so the X an Y values will not exist in our registry key.

http://www.devhood.com/tutorials/images/264/2.jpg

To allow for this information to be saved, we will add a “Save Position” button to our form. To do this, close the current Form1.cs* code window. You should now be viewing the form designer for Form1. Add a button to the form and change the button’s Text property to something appropriate (See figure). Now double-click the button to show the code for the button’s Click event handler. Add the following code:
// Open the key
RegistryKey key = Registry.CurrentUser.OpenSubKey( "Software\\Play\\WindowPos", true );
// Set the registry values to correspond to the form's coordinates on the
// screen.
key.SetValue( "X", Location.X );
key.SetValue( "Y", Location.Y );

Something very important to notice at this point is the second parameter supplied to OpenSubKey method, which is a boolean true. This opens the key in Write mode and allows us to make calls to the SetValue method of our key; otherwise, these SetValue calls would cause an error: UnauthorizedAccessException.

Our work here is done. Press F5 to run the program. Move the form to some memorable spot and click our save position button. If you restart the program, the form should be initialized to the last position where the save button was clicked.

At this point, you might pop open regedit and take a peek: Are the values really there?

Congratulations on your successful use of the registry! This is only a very basic example to whet your apatite; good luck in your further registry endeavors.

No comments: