Microsoft Access VBA Uses WMI to Read the Registry


Microsoft Access VBA can read and write to the Windows Registry by using WMI. In this article we are going to show you how easy it is to read 5 different types of Registry Values with VBA and WMI.

The Registry provided a solution for the problem caused by the proliferation of separate ini settings files which often contained conflicting settings. The Registry became the central repository for data and settings reducing conflicts and providing better organization for the operating system, hardware, services, and applications settings. Most changes made concerning a computer and software are stored in the Registry.


The Registry is useful for the Access developer for storing connection strings, user preferences, a last used list, default startup settings and more. Since the Registry is vital to the operating system, hardware, services, and software it contains a very large and varied amount of data. Within this vast amount of data are treasures of information to be found. So let us begin by examining how we can read data from the Registry.


At first glance the Registry may seem very complicated, but actually the registry contains just two main types of elements: Keys and Values. The Keys are very similar to folders and subfolders having a similar hierarchy of Keys and SubKeys. The Registry Values are Name and Data pairs which are very much like the Properties and their Values we use in VBA code.


The top level Registry Keys are organized into Root Keys also known as Hives. The Root Keys on my XP are:

  • HKEY_CLASSES_ROOT
  • HKEY_CURRENT_USER
  • HKEY_LOCAL_MACHINE
  • HKEY_USERS
  • HKEY_CURRENT_CONFIG

The most common Registry Value Names and their Constants are:

  • String: REG_SZ = 1
  • Expanded String: REG_EXPAND_SZ = 2
  • Binary: REG_BINARY = 3
  • DWord: REG_DWORD = 4
  • Multi-String: REG_MULTI_SZ = 7

I will not take the time to explain them all here since ample information about Registry Value Types can easily be found on the internet.

Before I forget I need to give the usual, but important, warning that making changes to the Registry can cause damage to your software and operating system so if you are smart you will back up the Registry before making changes. To do that click on Start, then select Run, enter “Regedit” without the quotes and then click “OK”. After Regedit opens click on File and then Export to export your Registry to a backup file. This will probably take a few minutes, but it is better than hours of tears because you lost your loved ones photos!


The Registry stores information in several different types and using WMI we can read all the types listed here. We will start by declaring the Root Key Constants at the beginning of the Module.

Option Compare Database
Option Explicit

Const HKEY_CLASSES_ROOT = &H80000000
Const HKEY_CURRENT_USER = &H80000001
Const HKEY_LOCAL_MACHINE = &H80000002
Const HKEY_USERS = &H80000003
Const HKEY_CURRENT_CONFIG = &H80000005

Most of this first part of the procedures is familiar to you if you have been following our articles. However in these procedures we access a different WMI root. When we Set the objReg we use “\root\default:StdRegProv” instead of “\root\cimv2″.

The first example demonstrates how to read is the simple String Value.

Sub GetRegString()
    Dim objReg As Object
    Dim strComputer As String
    Dim strKeyPath As String
    Dim strValueName As String
    Dim strValue

    strComputer = "."
    
     Set objReg = GetObject("winmgmts:" _
        & "{impersonationLevel=impersonate}!\" _
        & strComputer & "\root\default:StdRegProv")
            
    strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\MSACCESS.EXE"
    strValueName = "Path"
    
    objReg.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue
    Debug.Print "Microsoft Access Location: " & strValue
    
    Set objReg = Nothing

End Sub


The next value to read is the often used DWord Value. In this procedure we use a Select Case construct to give meaning to the DWord value. In this case it is the Windows Automatic Updates setting.

Sub GetRegDWord()
    Dim objReg As Object
    Dim strComputer As String
    Dim strKeyPath As String
    Dim strValueName As String
    Dim strDWordValue As String
    Dim dwValue
    
    strComputer = "."
    
     Set objReg = GetObject("winmgmts:" _
        & "{impersonationLevel=impersonate}!\" _
        & strComputer & "\root\default:StdRegProv")
    
    strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update"
    strValueName = "AUOptions"
    
    objReg.GetDWORDValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, dwValue
    
    ' If there is no DWord Value we want "Null" to be returned
    strDWordValue = Nz(dwValue, "Null")
    
    Select Case strDWordValue
        Case "2"
            strDWordValue = strDWordValue & " - Notify for download and notify for install."
        Case "3"
            strDWordValue = strDWordValue & " - Auto download and notify for install."
        Case "4"
            strDWordValue = strDWordValue & " - Auto download and schedule the install."
        Case "Null"
            strDWordValue = "Automatic Updates status is Unknown - No value was returned."
        Case Else
            strDWordValue = strDWordValue & " - Automatic Updates are not enabled."
    End Select
    
    Debug.Print strDWordValue
    
    Set objReg = Nothing

End Sub


The next value to read is the Multi-String Value. In this procedure we will get a list of Event Log Sources. In a later article we will show how to filter and save specific Event Logs Text which contain important data.

' Example Call SaveRegSystemEventLog("C:\SystemEventLogSources.txt")
Sub SaveRegSystemEventLog(strTextFilePath As String)
    Dim objReg As Object
    Dim fso As Object
    Dim fsoFile As Object
    Dim strComputer As String
    Dim strValueName As String
    Dim strKeyPath As String
    Dim arrValues
    Dim arrValue

    Set fso = CreateObject("Scripting.FileSystemObject")
    Set fsoFile = fso.CreateTextFile(strTextFilePath)
        
    strComputer = "."
    
     Set objReg = GetObject("winmgmts:" _
        & "{impersonationLevel=impersonate}!\" _
        & strComputer & "\root\default:StdRegProv")
     
    strKeyPath = "SYSTEM\CurrentControlSet\Services\Eventlog\System"
    strValueName = "Sources"

    objReg.GetMultiStringValue HKEY_LOCAL_MACHINE, strKeyPath, _
        strValueName, arrValues
        
    For Each arrValue In arrValues
        fsoFile.WriteLine arrValue
'        Debug.Print arrValue
    Next

    fsoFile.Close
     
    Set fsoFile = Nothing
    Set fso = Nothing
    Set objReg = Nothing
    
End Sub


The next value to read is the Expanded String Value.

Sub ReadExpandedRegString()

    Dim objReg As Object
    Dim strComputer As String
    Dim strValueName As String
    Dim strKeyPath As String
    Dim strValue

    strComputer = "."
     
    Set objReg = GetObject("winmgmts:" _
        & "{impersonationLevel=impersonate}!\" _
        & strComputer & "\root\default:StdRegProv")
     
    strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon"
    strValueName = "UIHost"
    
    objReg.GetExpandedStringValue HKEY_LOCAL_MACHINE, strKeyPath, _
        strValueName, strValue
     
    Debug.Print "The Windows logon UI host is: " & strValue

    Set objReg = Nothing

End Sub


Lastly, we see the code to read a binary registry value. In this case the code reads the binary AccessName Value.

Sub ReadBinaryRegValue(strTextFilePath As String)

    Dim objReg As Object
    Dim fso As Object
    Dim fsoFile As Object
    Dim strComputer As String
    Dim strKeyPath As String
    Dim strValueName As String
    Dim i As Long
    Dim varValue
    
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set fsoFile = fso.CreateTextFile(strTextFilePath)
        
    strComputer = "."
    
    Set objReg = GetObject("winmgmts:" _
        & "{impersonationLevel=impersonate}!\" _
        & strComputer & "\root\default:StdRegProv")
     
    strKeyPath = "Software\Microsoft\Office\11.0\Access"
    strValueName = "AccessName"

    
    objReg.GetBinaryValue HKEY_CURRENT_USER, strKeyPath, _
        strValueName, varValue
     
    For i = LBound(varValue) To UBound(varValue)
        fsoFile.WriteLine varValue(i)
    Next
    
    fsoFile.Close
     
    Set fsoFile = Nothing
    Set fso = Nothing
    Set objReg = Nothing

End Sub


We will learn more about how VBA can manage the Registry using WMI in the articles to come.


You can download the free sample database, WMISample.zip which contains the code used here at our Gaining Access website. The code is located in the PAWWMIRegistry Module.

Other free downloads include our new Microsoft Access and SQL Azure and demonstration application which uses Microsoft Access and SQL Azure to leverage the power of cloud computing.

More Free Downloads:
Us or UK/AU Pop-up Calendar
Report Date Dialog Form in US or UK/AU Version.
Free Church Management Software with Contributions management.
Code Samples


Get the Access and Outlook Appointment Manager to manage all of your Outlook Calendar Appointments and Access dated information.


Happy computing,

Patrick (Pat) Wood
Gaining Access

About these ads

8 Comments

  1. Posted July 16, 2009 at 8:24 AM | Permalink | Reply

    The VBA object library also has built-in methods for reading and writing to the registry. Just use VBA.SaveSetting to write and VBA.GetSetting to read.

    For example, if you wrote an add-in for an Office program and wanted to store custom application-specific settings in between sessions, or log the number of times a program has been run (for time-bombing purposes).

    Keep in mind these methods only work with the Office application’s entry in the registry, so if you need to work with the registry as a whole, we need to use your method.

    • Posted July 16, 2009 at 10:01 AM | Permalink | Reply

      Thanks for the informative comment J.P. You make an important point. The GetSetting, SaveSetting, GetAllSettings, and DeleteSetting Functions are easy to use ways of saving and getting data from the spot of the Registry reserved for VBA. Because it only takes one line of code to Save to the Regestry and one line to Read what you have saved it provides a safe and easy alternative to Global Variables.

  2. Joo Mo Kim
    Posted July 23, 2010 at 4:23 PM | Permalink | Reply

    I’m a programmer using Access Database in Chicago.
    I’m trying to use your logic to read registry values.
    By the way, I got an error ‘Automation Error’ at the following line and couldn’t go forward at all.

    Set objReg = GetObject(“winmgmts:” & “{impersonationLevel=impersonate}!\” & strComputer & “\root\default:StdRegProv”)

    If you have any idea on this, your suggestion would be very much appreciated.

    • Posted July 23, 2010 at 6:34 PM | Permalink | Reply

      Hi Joo Mo Kim,

      There are several things that may be causing problems.

      The “{impersonationLevel=impersonate}!\” enables System Administrators to work on remote Computers. If you are using this code on your own computer you can replace the code with this:

          Set objWMIService = GetObject("winmgmts:\\" _
              & strComputer & "\root\CIMV2")
      

      Another thing that might cause problems are the quotes that when copies and pasted may not be normal quotes. So you can try replacing the quotes with “.

      Also, If you are using Vista or Windows 7, you may have to run Access as an Administrator to modify the Registry. Another issue may be that you may not have rights to modify specific hives of the Registry. You can find help with this by doing a search for rights to change the Registry. As always use care when modifying the Registry and be sure to export a back up copy.

      Best Regards.

      • Joo Mo Kim
        Posted July 26, 2010 at 6:09 PM | Permalink

        Thanks a lot, Patrick.
        By changing the code as your suggestion, “Automation Error” doesn’t come out any more.
        But I got another error “438 Object doesn’t support this property or method”, which I’ll try to solve.
        Thank you again for your logic and WMI sample database, that contains very useful information.

      • Posted July 26, 2010 at 7:52 PM | Permalink

        Hi Joo Mo Kim,
        The only thing I can think to write that may help you at this point is to make sure that you are using the right code to match the value according to whether it is a Binary Registry value, an Expanded String Value, a DWord Value, or a String Value.

        Best Regards

      • Andy Tynan
        Posted April 19, 2011 at 7:13 AM | Permalink

        I had the “Automation Error” as well.
        But I found that it works on a local machine if instead of “\root\CIMV2″ you use “\root\default:StdRegProv”.

  3. Ryan Wei
    Posted May 26, 2011 at 12:19 PM | Permalink | Reply

    If you use API Sendmessage to trigger any sub about WMI registry. It will 100% has an‘Automation Error’ in here.

    Set objReg = GetObject…

    XP, Vista and Windows 7 they All have the same bug. Alternatively you can use a timer to trigger that sub.

2 Trackbacks

  1. [...] to either the HKEY_CURRENT_USER or the HKEY_LOCAL_MACHINE Key. Please see our previous article on Microsoft Access VBA Uses WMI to Read the Registry for Constants for these keys. Another important point to remember is to be sure you have [...]

  2. [...] to either the HKEY_CURRENT_USER or the HKEY_LOCAL_MACHINE Key. Please see our previous article on Microsoft Access VBA Uses WMI to Read the Registry for Constants for these keys. Another important point to remember is to be sure you have [...]

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 72 other followers

%d bloggers like this: