In Windows 3.1, INI or initialization files were used to hold information used to configure application programs. For example, an INI file might have a list of the most recently used files or hold the status of an option to save modified files. However, INI files had several weaknesses:
These problems, and others, prompted Microsoft to design the Registry.
The Registry is a database that contains information about
your operating system, its applications and file associations.
An exhaustive list of the different types of information is too
long to reproduce here. Suffice to say that the Registry holds
both hardware and software information.
Caution |
Changing the Registry is dangerous! Make sure that your Registry is backed up and you can afford to totally wreck your test machine. I'm serious; don't mess with the Registry unless you can afford to take the time to back up your system. |
There are several advantages to using the Registry:
Information in the Registry is stored in a key-value format.
This means that every value stored in the Registry has an associated
key. Similar to the lock on your front door. You can't unlock
the door without the correct key. Likewise, you can't retrieve
the stored value without the correct key. Each key can have both
subkeys andone or more sets of name-value pairs. In fact, you
might think of eachkey as an associative array. For example, there
is a key called HKEY_USERS\Default\Software\Microsoft\User
information that is interesting. This key has several
name-value pairs. Here is a small sampling of the name-value pairs
from the Registry on my system:
Name | Value |
Operating System | Microsoft Windows 95 |
Processor | Pentium |
Default Company | Eclectic Consulting |
Default First Name | David |
In addition to named values, there is an unnamed default value
that is referred to using an empty string as the name.
Note |
The concept of a default name-value will become clear if you peek ahead to Figure 22.6 where you'll see a Registry key with several name-value keys defined. |
As you may guess from looking at the key just mentioned, all of the information in the Registry is stored in a hierarchical or tree format-similar to a directory structure. Each key can have subkeys. There are three root or base keys:
Some of the Registry information is accessed so often that Microsoft has provided three shortcut keys:
Caution |
Remember, changing the Registry is dangerous! Make sure that your Registry is backed up before making changes. |
There are two files associated with the Registry. The user.dat file holds user-specific data, and the system.dat file holds everything else. They are located in the \windows directory and have their hidden, system, and read-only attributes turned on. This means that if you run the dir command while connected to those directories, you will not see these files. When the system is booted, both files are read and a single Registry is created in memory.
The user.da0 and system.da0 files in the \windows directory are copies of the Registry from a successful boot of the computer system. If the Registry gets corrupted, Windows will try to fix the problem by using these earlier versions.
You will also find a system.1st file in the root directory of your boot drive (usually C:). The file was created when you first installed Windows. If Windows can't recover from a Registry failure using the DA0 files, you can try using system.1st file.
You can manually back up the Registry by exporting the information using the Windows regedit utility. This utility lets you export all of the Registry information to a text file. Follow these steps to perform the export:
This procedure creates a text-based backup of the Registry. You should copy this file onto a diskette or other data storage medium. You will probably need to compress the resulting backup file since mine was over 1.8 million bytes in length-too long to place on a diskette.
You can also boot your system into DOS mode and copy the \windows\user.dat and \windows\system.dat files either onto a diskette or into a directory other than \windows.
Now that you know how to back up the Registry by using the export feature of the Registry Editor, let's look at restoring the Registry using the import feature. Use this procedure to import the text-based Registry file:
If your system is still not working, and you have copied the two Registry files and were created in the previous section, "How to Back Up the Registry," then you can try rebooting to DOS and copy the two backup files directly into the \windows directory. After copying the files, reboot your system.
If you are still having problems, consider re-installing Windows or calling an expert for help.
At this point, you have some background information about the
Registry, and you know how to make a Registry backup. Let's look
at how to use the Registry. To make Registry access as easy as
possible, I have created an object-oriented module, called DmmReg.pm,
for Registry access.
Note |
The module was called DmmReg because there is already a module called Registry.pm included with Perl for Win32. However, that module has little documentation and I wanted to create something special for this book. |
The DmmReg module was designed
to make Registry access as easy as possible. You do not need in-depth
knowledge of the Registry to use the methods. The examples in
this chapter show you how to open and create keys, read key values,
and list subkeys.
Tip |
On the other hand, you might feel more comfortable changing the Registry if you know more. If so, read Que's Special Edition Using the Windows 95 Registry by Jerry Honeycutt. |
All of the snippets of code that are discussed in the following sections are collected into one script file called ELST01.PL on the CD-ROM that accompanies this book. When creating your own scripts you merely need to cut and paste the lines of code that you're interested in. You won't need to hunt through four or five files.
The next few sections discuss how to do specific Registry tasks using the DmmReg module. You see how to use the following methods:
Tip |
In order to avoid a bit of potential confusion, let me clarify one thing. The DmmReg module has two constructor functions: createKey() and openKey(). Both functions will return an object reference. If you aren't sure what constructor functions are, see Chapter 14, "What Are Objects?". |
To open an existing Registry key, you need only know the key's name. For example, if you want to determine if a file association exists for .pl files, check for the existence of the HKEY_CLASSES_ROOT\.pl key like this:
Specify that this script will use the DmmReg module.
Specify that strict variable checking should be done.
Declare the $handle variable to be local to the file.
Create an object of type HKEY_CLASSES_ROOT and open the subkey called .pl. The $handle object will hold the object reference.
Display a message indicating the existence of the subkey.
use DmmReg; use strict; my($handle); $handle = HKEY_CLASSES_ROOT->openKey('.pl'); print("There " . (defined($handle)? "is an" : "is no") . " association for .pl files\.n");
If your system does not have any file associations defined for Perl scripts, this program displays:
There is no association for .pl files.
The name of the root key is used as the class name and the subkey name is passed as the only argument to the openKey method.
If you need to open a key that is deeper in the hierarchy, simply add the branches to the argument of the openKey method.
$handle = HKEY_USERS->openKey('Default\Software\Microsoft\User information');
You can also see from this second example that the DmmReg module lets you create more than one type of object. Actually, you can create a different object for each of the six root keys. Each class has exactly the same methods and functionality.
Creating a new key is almost as simple as opening an existing one. You specify the name of the new key, and you optionally specify a value for the default name-value pair. For example, if you wanted to create a Registry key that holds the name of the last data file that your script opened you could do it like this:
$h = HKEY_LOCAL_MACHINE->createKey( 'SOFTWARE\A Perl Test Script\Last Data File', 'C:\TEST.DAT');
The first argument is the name of the key and the second argument
is the data that will be assigned to the default name.
Note |
The most confusing aspect of the Registry and its keys is that each key can have both subkeys and name-value pairs associated with it. The default name is represented by an empty string. The createKey() method lets you create a new key and assign a value to its default name in one step. |
You can verify that the assignment worked by using the Registry Editor. The new key and its default value is shown in Figure D.5. Some programmers refer to this type of information as persistent because the Registry key will be around even after your script has ended. If the key specified as the parameter to the createKey() method already exists, then that key will be opened.
Figure D.5 : Creating persistent information in the Registry.
As with the openKey() method, you can specify limited access rights when opening a key. You can also tell Windows that the key should be kept in memory and not written to disk-a volatile key. However, this level of detail is more involved than this brief introducton can cover. Please read Special Edition Using the Windows 95 Registry if you need more advanced information.
You can find out a key's value by using the getValue() method in the DmmReg module. For example, to read the name of the data file that was written in the last section, you do this:
Specify that this script will use the DmmReg module.
Specify that strict variable checking should be done.
Declare the $handle and $keyName variables to be local to the file.
Initialize $keyName to be the name of the key we're interested in.
Call the openKey() method, $handle will hold the object reference.
Call the getValue() method. The argument to getValue() is the name of the value to be retrieved. In this instance, the default value is sought.
Print the data associated with the default value.
use DmmReg; use strict; my($handle); my($keyName) = 'SOFTWARE\A Perl Test Script\Last Data File'; my($value) $handle = HKEY_LOCAL_MACHINE->openKey($keyName); $value = ($handle->getValue(''))[1]; print("The data file was named $value\n");
This program displays:
The data file was named C:\TEST.DAT
You may find the call to the getValue() method to be a little confusing. Let's take a closer look at it:
$data = ($handle->getValue(''))[1];
The getValue() method returns an array that holds the data type of the value and the value itself. Since you only need the value in this example, an array slice was used. You place parentheses around the entire function call to ensure that the return value is evaluated in an array context. Then, regular subscripting notation selects the second element of the returned array. The second element is assigned to $value.
The DmmReg module is designed to work with strings, the most popular type of data stored in the Registry. While you can work with other data types, like binary data, you'll need to look at more advanced books to find out how.
You've already seen how to set the value of the default name-value pair by using the createKey() method. In this section, you use the setValue() method to explicitly set any name-value pair. Let's build on the example shown in "Creating a New Key." Perhaps, instead of just saving one data file, you need to save more than one. Maybe you have the names of a message file and a data file to store. You can use the following script as a template:
Specify that this script will use the DmmReg module.
Specify that strict variable checking should be done.
Declare the $handle and $keyName variables to be local to the file.
Initialize $keyName to be the name of the key we're interested in.
Call the createKey() method, $handle will hold the object reference.
Call the setValue() method once for each name-value pair that needs to be stored.
use DmmReg; use strict; my($handle); my($keyName) = 'SOFTWARE\A Perl Test Script'; $handle = HKEY_LOCAL_MACHINE->createKey($keyName); $handle->setValue('Data File', 'c:\perl5\test.dat'); $handle->setValue('Date', '07-01-1996'); $handle->setValue('Message File', 'c:\perl5\friday.log');
After this script is run, you can see the name-value pairs using the Registry Editor as shown in Figure D.6.
Figure D.6 : A Registry key with four name-value pairs.
Notice that the default name-value pair is no longer valued. Since you are using specifying names with the setValue() method, the default name is no longer needed.
The getKeys() method of the DmmReg module is used to retrieve a list of subkeys for any specified key. For example, if you need to find all of the subkeys for the HKEY_CURRENT_USER\Network key use the following code.
Specify that this script will use the DmmReg module.
Specify that strict variable checking should be done.
Declare variables to be local to the file.
Initialize $keyName to be the name of the key we're interested in.
Open the HKEY_CURRENT_USER\Network subkey.
Check the status of the openKey() method, die if an error occured.
Call the getKeys() method.
Iterate over @subKeys and display the subkeys.
use DmmReg; use strict; my($handle); my($keyName) = 'Network'; my(@subKeys); my($subKey); $handle = HKEY_CURRENT_USER->openKey('Network'); die("Unable to open $keyName") unless defined($handle); $handle->getKeys(\@subKeys); foreach $subKey (sort(@subKeys)) { print("$subKey\n"); }
This program displays:
Persistent Recent
Caution |
There is a bug-that I have not been able to correct-that will not let you get a list of keys starting from one of the six root keys. Since the first level of subkeys do not change, use the Registry Editor to find them. |
Earlier, in "Setting a Key's Name-Value Pairs," you saw that each Registry key can have name-value pairs associated with it. You use the getValues() method to get a list of these pairs.
Specify that this script will use the DmmReg module.
Specify that strict variable checking should be done.
Declare variables to be local to the file.
Initialize $keyName to be the name of the key we're interested in.
Open the HKEY_LOCAL_MACHINE\SOFTWARE\A Perl Test Script subkey.
Call the getValues() method to populate the %pairs hash.
Iterate over %pairs to print the name-value pairs.
use DmmReg; use strict; my($handle); my($keyName) = 'SOFTWARE\A Perl Test Script'; my($name); my(%pairs); $handle = HKEY_LOCAL_MACHINE->openKey($keyName); $handle->getValues(\%pairs); foreach $name (sort(keys(%pairs))) { printf("%-12.12s: @{$pairs{$name}}[1]\n", $name); }
This program displays:
Data File : c:\perl5\test.dat Date : 07-01-1996 Message File: c:\perl5\friday.log
There are several common uses for the Registry besides storing configuration information that needs to be persistent:
By this time, you understand all of the concepts involved in creating Registry keys and name-value pairs, so the code to do each task will be presented with very few comments.
There are three steps to creating file associations:
$handle = HKEY_CLASSES_ROOT->createKey('A Perl File\Shell\Open\ Command', 'C:\MSOFFICE7\WINWORD\WINWORD.EXE %1'); $handle = HKEY_CLASSES_ROOT->createKey('A Perl File\Shell\Edit\Command', 'C:\MSOFFICE7\WINWORD\WINWORD.EXE %1'); $handle = HKEY_CLASSES_ROOT->createKey('A Perl File\Shell\Print\Command', 'C:\MSOFFICE7\WINWORD\WINWORD.EXE /p %1');
For simplicity's sake, I have all of my associations pointing to Microsoft Word, you should start whatever editor you normally use.
You specify the icon for a file extension by creating a DefaultIcon subkey under the extension description key like this:
$handle = HKEY_CLASSES_ROOT->createKey('A Perl File\DefaultIcon', 'C:\WINDOWS\SYSTEM\SHELL32.DLL,27');
The default value of the DefaultIcon key indicates which DLL and icon number to use. You can experiment with different icon numbers to find one that you like. Icon number 27 in the shell32.dll file looks like a monitor that is displaying a starburst.
If you right-click while inside a folder or on the desktop, one of the context menu options is new. You can add your own file types to the new sub-menu by following these steps:
$handle->setValue('NullFile', '');
If you follow these steps for both the .pl and .pm extensions, your new context menu will look like Figure D.7.
Figure D.7 : The new sub-menu with options to create Perl files.
This chapter briefly introduced you to the Windows Registry. The Registry is used to store all types of information about the hardware and software that are installed on your computer system.
You learned that there are three root keys (HKEY_DYN_DATA, HKEY_LOCAL_MACHINE, and HKEY_USERS) and three shortcut keys (HKEY_CLASSES_ROOT, HKEY_CURRENT_CONFIG, and HKEY_CURRENT_USER). These keys are at the top of a hierarchical structure similar to a directory tree.
The Registry information is stored on two files, user.dat and system.dat. When the system is booted, these files are read into memory and the Registry is created. You read about sing the Registry Editor to export and import the Registry information for backup and recovery.
Then, you saw how to use the DmmReg module to access and modify Registry keys and name-value pairs. Examples were shown that create file association for .pl and .pm files; changed their default icons; and added Perl file types to the new option of the context menu.