oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

Reading and Writing Registry Keys with Visual Basic
Pages: 1, 2, 3

Opening a Registry Key

Opening the key is always the first step involved in working with a registry key (unless you intend to work with one of the top-level keys, which are always considered open). Once you open the key, you work with its handle, or hKey. We can take advantage of the fact that a successful open operation results in a valid handle to a registry key when determining whether a particular key exists, which is one of the more common operations performed on registry keys. For example, consider the following example function:

Private Function RegKeyExists(hKey As Long, sKeyPath As String) As Boolean

Dim lResult As Long
Dim hSubkey As Long

lResult = RegOpenKeyEx(hKey, sKeyPath, 0, KEY_EXECUTE, hSubkey)
' Determine if handle is valid
If hSubkey <> 0 Then
   RegKeyExists = True
   RegCloseKey hKey
End If

End Function

This example function takes two parameters: a handle to a registry key (or a top-level registry key), and the path from the open key to the registry key to be opened. It then calls the RegOpenKeyEx function, which simply opens an existing key and returns its handle in phkResult, a parameter passed to the function by reference. Its syntax is:

Public Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" _
       (ByVal hKey As Long, _               ' Handle of already open key
       ByVal lpSubKey As String, _          ' Path from hKey to key to open	
       ByVal ulOptions As Long, _           ' Reserved, must be 0
       ByVal samDesired As Long, _          ' SAM constant(s)
       phkResult As Long) As Long           ' Handle of newly opened key

The RegKeyExists function then examines the value of the RegOpenKeyEx function's phkResult argument to determine whether the key exists. If its value is non-zero, the phkResult argument has been assigned a valid handle value, indicating that the key exists. The example function can then return True.

Otherwise, it returns False. Instead of examining the value of the phkResult parameter, the example function could have examined the value returned by the RegOpenKeyEx function call. A value of ERROR_SUCCESS indicates that the key exists, so the function should return True; any other value indicates that it does not exist.

The RegKeyExists function, if it determines that the key exists, calls the Win32 RegCloseKey function to close the opened key. Its syntax is:


Where hKey is the handle to the registry key to close. Since handles to registry keys are system resources, calling the RegCloseKey function when the handle is no longer needed is good programming practice.

Rather than calling RegOpenKeyEx, an earlier and simpler version of the function, RegOpenKey, can be called instead.

The function was introduced as part of the Win16 API, when Windows was predominantly a single-user desktop operating system and system security was considered relatively unimportant, and so lacks the samDesired parameter. As a result, the function often returns ERROR_ACCESS_DENIED when the default security access mask used by the function exceeds the permissions required by the key. Because of this, using RegOpenKeyEx in the long run is simpler and more convenient.

Opening or Creating a Registry Key

Often when accessing the registry, you don't really care whether or not a key exists. Instead, you wish to open it if it exists and create it if it does not. This is often the case, for instance, when a new user first runs your application on a system configured to support multiple users. For this purpose, you use the RegCreateKeyEx function, which opens an existing registry key or, if the key does not exist, creates it. Its syntax is:

Public Declare Function RegCreateKeyEx Lib "advapi32.dll" Alias "RegCreateKeyExA" _
       (ByVal hKey As Long, _                ' Handle of already open key	
       ByVal lpSubKey As String, _           ' Path from hkey to key to open/create
       ByVal Reserved As Long, _             ' Reserved, must be 0
       ByVal lpClass As String, _            ' Reserved, must be a null string
       ByVal dwOptions As Long, _            ' Type of key, or backup/restore 
       ByVal samDesired As Long, _           ' SAM constant(s)
       lpSecurityAttributes As SECURITY_ATTRIBUTES, _   
       phkResult As Long, _                  ' Handle of opened/created key
       lpdwDisposition As Long) As Long      ' 

Although most of these parameters need no explanation, several are not so obvious. The dwOptions parameter determines the type of key to be created if lpSubKey does not exist. Possible values are:


Non-volatile keys are saved as part of the registry, while volatile keys are not. REG_OPTION_BACKUP_RESTORE indicates that RegCreateKeyEx is called as part of a registry backup/restore operation and if necessary overrides the samDesired parameter to provide for the necessary access.

If the function succeeds, the operation it performed is indicated by the lphDisposition parameter, which is passed by reference to the function. Its value can be either of the following two constants:

Public Const REG_CREATED_NEW_KEY = &H1        ' A new key was created             
Public Const REG_OPENED_EXISTING_KEY = &H2    ' An existing key was opened

The function also includes a parameter of type SECURITY_ATTRIBUTES, which is defined as follows:

        nLength As Long
        lpSecurityDescriptor As Long
        bInheritHandle As Long
End Type

The SECURITY_ATTRIBUTES type includes a security descriptor and determines whether the handle returned by the function call can be inherited. If we pass a Null as the value of the pointer to the security descriptor, a newly created registry key will be assigned the default security descriptor of the current process. Assuming that this is adequate, we can define this argument in either of two ways:

sa.nLength = Len(sa)
sa.bInheritHandle = CLng(True)

The code to either open or create a subkey of HKEY_CURRENT_USER named Software\MyCompany\MyCorporateApp is as follows:

Dim lResult As Long
Dim hTopKey As Long, hKey As Long, lDisposition As Long
Dim sRegPath As String

sRegPath = "Software\MyCompany\MyCorporateApp"

sa.nLength = Len(sa)
sa.bInheritHandle = CLng(True)

lResult = RegCreateKeyEx(hTopKey, sRegPath, 0, vbNullString, REG_OPTION_NON_VOLATILE, _
                         KEY_ALL_ACCESS, sa, hKey, lDisposition)
If lResult = ERROR_SUCCESS Then
   If lDisposition = REG_CREATED_NEW_KEY Then
      ' Assign default values
   ElseIf lDisposition = REG_OPENED_EXISTING_KEY Then
      ' Retrieve values from existing keys
   End If
   MsgBox "Error " & lResult
End If

Pages: 1, 2, 3

Next Pagearrow