Q: How do I access the Windows registry using Visual Basic?
A: The answer to this question depends on what you want to accomplish by accessing the registry. If you just want to preserve some configuration information about your app between runs, then VB's SaveSetting and GetSetting commands might be all you need. A slightly more complex solution lies in the Windows Script Host's (WSH) WshShell object, which offers easy-to-use access to most of the registry. A third option lies in the Win32 API's registry functions, which offer the most flexibility but also insulate you the least from the registry's complexity.
In this article, I'll introduce you to the first two options.
A simple but inflexible solution
VB's SaveSetting and GetSetting commands let you store string data in the registry with a minimum of fuss. Any data saved with these commands goes into Subkeys of HKEY_CURRENT_USER\Software\VB and VBA Program Settings. Usually your settings are saved in a Subkey that shares your application's name. For example, to save the name of the last user to log in to an application called RegistryHacker, I'd use the following code:
SaveSetting "RegistryHacker", "UserManagement", _
What's the registry look like?
The Windows registry is essentially a database that has been optimized for extremely fast reads of relatively small amounts of data. It's organized in a hierarchical tree structure, much like the Windows file system. At the roots are Hives, which represent top-level keys like HKEY_CURRENT_USER. The nodes in the tree are Keys, which can contain Subkeys (other Keys) or pieces of named data called Values. Registry Values can hold a variety of data, including simple strings, 32- and 64-bit integers, binary data, and arrays of strings.
Running the above code creates the Key RegistryHacker and the Subkey UserManagement (if they don't already exist), adds a Value called LastUser to UserManagement (if it doesn't already exist), and saves the string "Lamont" to that value. Figure A shows what these changes look like, as seen through RegEdit.
|New registry key created with SaveSetting|
To retrieve this information from the registry, you'd use GetSetting, which would look like this:
strUser = GetSetting("RegistryHacker", _
VB also provides a DeleteSetting command that allows you to delete a Value you previously stored via SaveSetting.
As you can see, GetSetting and SaveSetting are very simple to use. However, they aren't very powerful, either. What if you need to read a Value from a Key that's not a Subkey of the VB and VBA Program Settings Key? Suppose you need to save some binary data? Or you simply just don't want to advertise the fact that your app was written in VB?
Good old WSH
If you need a little more flexibility than GetSetting and SaveSetting provide but don't want to deal with the complexities of the registry API, you can take advantage of the WSH WshShell object. WshShell exposes three methods: RegRead, RegWrite, and RegDelete. These methods allow you to manipulate most areas of the registry with a minimum of fuss. You simply have to reference Windows Script Host Object Model (wshom.ocx) in your project and off you go.
To read data from a Key in the registry, you use the RegRead method, which accepts the path to a Key, or Value in the registry, as a parameter. For example, to read the LastUser Value from the UserManagement key we created above, we could use the following code, assuming that o is a properly instantiated WshShell object:
strUser = o.RegRead("HKEY_CURRENT_USER\" _
& "Software\VB and VBA Program Settings\" _
With the RegWrite method, you can write data to the registry just as easily:
o.RegWrite "HKEY_CURRENT_USER\Software\VB " _
& "and VBA Program Settings\RegistryHacker\" _
& "UserManagement\LastUser", "Adams"
So how is this superior toGetSetting and SaveSetting? With WshShell, you can access Keys under most of the available Hives. WshShell defines a set of abbreviated Hive names you can use instead of the full hive name, and save yourself the typing (see Figure B).
|Use these WshShell support Hive abbreviations instead of full Hive names.|
WSH assumes that if the name you specify ends with a backslash (\), then you have given it the name of a Key. If, on the other hand, you have supplied a name that does not end in a backslash, then WSH will assume you have just named a Value.
Registry data types
Up until now, we've only been saving and retrieving simple strings. However, the registry can handle 12 different data types. Most of those you likely won't be interested in using from VB—even if you could. The WshShell object understands five of these data types (see Figure C).
|WshShell-supported registry data types|
When using RegWrite, you specify the type of data you are saving by passing the data type name from Figure C as its optional Type parameter. If you don't specify a type, RegWrite assumes you want REG_SZ.
By now you are probably asking, "So how do I specify a data type with RegRead?" Well, you don't. Remember that WSH was created to support scripting languages like VBScript and JScript, neither of which have any concept of a variable type. RegRead always returns a Variant type, which VB will automatically coerce into another type—if it can. You're probably safe retrieving a REG_DWORD into a string, but I'd be careful trying it the other way around.
You'll also find support for deleting registry keys with the RegDelete method, which will delete all Subkeys and Values in the key you specify.
The missing ingredients
Both registry access methods discussed in this article have advantageous uses. If all you are really interested in doing is saving a few variables between executions, then GetSetting and SaveSetting may be all you need. However, if you need access to other areas of the registry, then the WshShell solution deserves a look. You should also be aware that, because of its role in the recent wave of script viruses, the WSH has gotten a terrible rep lately and may be changed dramatically (that is, crippled) in the near future.
Neither of the methods I've talked about here allow you to explicitly create a new Key or provide any way of enumerating the Subkeys or Values contained in a Key. If you need advanced functionality like this, then you'll need to look for a third-party component or use the registry API.