Looping Registry Keys

Posted on 1999-10-06
Medium Priority
Last Modified: 2008-02-26
I am trying to loop through a list of subkeys in the registry, but I am having no success. I am able to loop through string values using RegEnumValue, but RegEnumKeyEx is not working. Here is a copy of my code. What have I missed?


Sub TestLoop()
    'NOTE: sFullPath = "Software\MyCompany\SwitchDB\Aliases"
    mnlRetVal = RegOpenKeyEx(adhcnlhKey_LOCAL_MACHINE, sFullPath, 0, KEY_READ, mnlhKey)
    'mnlhKey does contain a value at this point
    For nlKeyIndex = 0 To 10
        Call RegEnumKeyEx(mnlhKey, nlKeyIndex, sKeyName, nlKeyLength, Null, Null, Null, mtoLastMod)
        Debug.Print "sKeyName= " & Trim(sKeyName)
        'sKeyName is always empty
    Next nlKeyIndex
    mnlRetVal = RegCloseKey(mnlhKey)
End Sub

Question by:bjames
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
LVL 96

Expert Comment

by:Bob Learned
ID: 2103980
Try using vbNull instead of Null on the RegEnumKeyEx line
LVL 25

Expert Comment

ID: 2104114
I actually think you'd want to use 0& rather than vbNull.

  Call RegEnumKeyEx(mnlhKey, nlKeyIndex, sKeyName, nlKeyLength, 0&, 0&, 0&, mToLastMod)

Author Comment

ID: 2104195
Neither vbNull nor 0& made any difference. sKeyName is still an empty string.
10 Questions to Ask when Buying Backup Software

Choosing the right backup solution for your organization can be a daunting task. To make the selection process easier, ask solution providers these 10 key questions.

LVL 25

Expert Comment

ID: 2104620
It's not obvious what you've missed from what you've posted.

Here's your code altered slightly with the declarations included and additional error messaging features added.  It works fine.

Option Compare Database
Option Explicit

Public Const HKEY_LOCAL_MACHINE = &H80000002
Public Const KEY_QUERY_VALUE = &H1
Public Const KEY_NOTIFY = &H10
Public Const READ_CONTROL = &H20000
Public Const SYNCHRONIZE = &H100000
Public Const ERROR_NO_MORE_ITEMS = 259&

Public Type FILETIME
        dwLowDateTime As Long
        dwHighDateTime As Long
End Type

Public Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired As Long, phkResult As Long) As Long
Public Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" (ByVal dwFlags As Long, lpSource As Any, ByVal dwMessageID As Long, ByVal dwLanguageId As Long, ByVal lpBuffer As String, ByVal nSize As Long, Arguments As Long) As Long
Public Declare Function GetLastError Lib "kernel32" () As Long
Public Declare Function RegEnumKeyEx Lib "advapi32.dll" Alias "RegEnumKeyExA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpName As String, lpcbName As Long, ByVal lpReserved As Long, ByVal lpClass As String, lpcbClass As Long, lpftLastWriteTime As FILETIME) As Long
Public Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long

Function getSystemError(dwMessageID As Long)
    Dim myMessage As String
    Dim myStrLen As Long
    myMessage = Space(1024)
    myStrLen = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0&, dwMessageID, 0&, myMessage, 1024, 0&)
    If myStrLen <> 0 Then
        myMessage = Left(myMessage, myStrLen)
        'Error in call to Format Message
        myMessage = "Unable to determine error.  FormatMessage is returning an error." & vbCrLf & vbCrLf & "  " & getSystemError(GetLastError)
    End If
    getSystemError = myMessage
End Function

Sub TestLoop()

    Dim sFullPath As String, mnlRetVal As Long, mnlhKey As Long
    Dim nlKeyIndex As Long
    Dim sKeyName As String
    Dim nlKeyLength As Long
    Dim mtoLastMod As FILETIME
    sKeyName = Space(1024)
    sFullPath = "Software\MyCompany\SwitchDB\Aliases"
    mnlRetVal = RegOpenKeyEx(HKEY_LOCAL_MACHINE, sFullPath, 0, KEY_READ, mnlhKey)
    If mnlRetVal <> 0 Then Err.Raise vbObjectError + 5000, "TestLoop", getSystemError(mnlRetVal)
    Dim i As Integer
    nlKeyIndex = 0
    Do While True
        i = 0
        mnlRetVal = RegEnumKeyEx(mnlhKey, nlKeyIndex, sKeyName, 1024, 0&, 0&, 0&, mtoLastMod)
        If mnlRetVal = ERROR_NO_MORE_ITEMS Then
            Debug.Print "Done reading keys"
            Exit Do
        ElseIf mnlRetVal <> 0 Then
            Err.Raise vbObjectError + 5001, "TestLoop", getSystemError(mnlRetVal)
            Debug.Print "sKeyName= " & Trim(sKeyName)
        End If
        nlKeyIndex = nlKeyIndex + 1
    mnlRetVal = RegCloseKey(mnlhKey)
    If mnlRetVal <> 0 Then Err.Raise vbObjectError + 5002, getSystemError(mnlRetVal)
End Sub
LVL 25

Expert Comment

ID: 2104636
Sorry, I forgot to remove the reference to the "i" variable within TestLoop.  I was originally using it for something, and forgot to take it out before I posted the code.  It will work with it in there as it is (obviously it's not doing anything), but in case you were wondering I just forgot to take it out.

Author Comment

ID: 2106740
I copied Clockwater's code and gave it a go. It ran without error and did give me my list of keys. I relooked at my code and tried to compare it with Clockwater's, but I still don't see where the difference is. No matter. Since Clockwatcher's code works and mine doesn't, I will use Clockwatcher's.

If Clockwatcher will lock the question I will accept the answer as 'Excellent'.

LVL 25

Accepted Solution

clockwatcher earned 400 total points
ID: 2107024

Expert Comment

ID: 6856295
This question was awarded, but never cleared due to the JSP-500 errors of that time.  It was "stuck" against userID -1 versus the intended expert whom you awarded.  This corrects the problem and the expert will now receive these points; points verified.

Please click on your Member Profile and select "View Question History" to navigate through any open or locked questions you may have to update and finalize them.  If you are an EE Pro user, you can also choose Power Search to find all your open questions.

This is the Community Support link, if help is needed, along with the link to All Topics which reflects many TAs recently added.

Thank you,
Moderator @ Experts Exchange

Featured Post

Microsoft Certification Exam 74-409

Veeam® is happy to provide the Microsoft community with a study guide prepared by MVP and MCT, Orin Thomas. This guide will take you through each of the exam objectives, helping you to prepare for and pass the examination.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Access custom database properties are useful for storing miscellaneous bits of information in a format that persists through database closing and reopening.  This article shows how to create and use them.
Did you know that more than 4 billion data records have been recorded as lost or stolen since 2013? It was a staggering number brought to our attention during last week’s ManageEngine webinar, where attendees received a comprehensive look at the ma…
In Microsoft Access, learn the trick to repeating sub-report headings at the top of each page. The problem with sub-reports and headings: Add a dummy group to the sub report using the expression =1: Set the “Repeat Section” property of the dummy…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

718 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question