dcsimg
Results 1 to 11 of 11

Thread: Help enumerating registry folders

  1. #1

    Thread Starter
    New Member
    Join Date
    Mar 2014
    Posts
    11

    Question Help enumerating registry folders

    Hi all,

    I am trying to enumerate the folders (subkeys?) in a certain directory in registry "Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Developer\Software Name\Folders". The user creates the folders another way and I would like my program to be able to enumerate or list all of the folders with the "Folders" directory.

    I am done a lot of searching and tried several sample codes but am not having any luck. I appreciate any help!

    Thanks

  2. #2
    Member Grant Swinger's Avatar
    Join Date
    Jul 2015
    Posts
    59

    Re: Help enumerating registry folders

    Add this class to your program and use it like this:

    Code:
    Dim objReg As New CRegistry
    Dim SubKeys() As String
    
    With objReg
          .RootKey = "HKEY_LOCAL_MACHINE"
          .KeyPath = "SOFTWARE\Developer\Software Name\Folders"
          .Arch = "x86" 'Change to x64 if accessing the 64-bit side
          .EnumerateSubKeys
    End With
    SubKeys = objReg.SubKeys
    It will return an array with the names of all the subkeys in the key path. Note that your program will need administrative privileges to access the Registry.

    The Arch property is used to set the KEY_WOW64_64KEY or KEY_WOW64_32KEY flags. Read this if you are not familiar with what that means.
    Attached Files Attached Files
    Last edited by Grant Swinger; Feb 23rd, 2019 at 07:07 PM. Reason: Formatting

  3. #3

    Thread Starter
    New Member
    Join Date
    Mar 2014
    Posts
    11

    Re: Help enumerating registry folders

    Quote Originally Posted by Grant Swinger View Post
    Add this class to your program and use it like this:

    Code:
    Dim objReg As New CRegistry
    Dim SubKeys() As String
    
    With objReg
          .RootKey = "HKEY_LOCAL_MACHINE"
          .KeyPath = "SOFTWARE\Developer\Software Name\Folders"
          .Arch = "x86" 'Change to x64 if accessing the 64-bit side
          .EnumerateSubKeys
       End With
    SubKeys = objReg.SubKeys
    It will return an array with the names of all the subkeys in the key path. Note that your program will need administrative privileges to access the Registry.

    The Arch property is used to set the KEY_WOW64_64KEY or KEY_WOW64_32KEY flags. Read this if you are not familiar with what that means.
    I literally could not ask for a better example, it is working perfectly. A million thanks!!

  4. #4

    Thread Starter
    New Member
    Join Date
    Mar 2014
    Posts
    11

    Re: Help enumerating registry folders

    Quote Originally Posted by Grant Swinger View Post
    Add this class to your program and use it like this:

    Code:
    Dim objReg As New CRegistry
    Dim SubKeys() As String
    
    With objReg
          .RootKey = "HKEY_LOCAL_MACHINE"
          .KeyPath = "SOFTWARE\Developer\Software Name\Folders"
          .Arch = "x86" 'Change to x64 if accessing the 64-bit side
          .EnumerateSubKeys
    End With
    SubKeys = objReg.SubKeys
    It will return an array with the names of all the subkeys in the key path. Note that your program will need administrative privileges to access the Registry.

    The Arch property is used to set the KEY_WOW64_64KEY or KEY_WOW64_32KEY flags. Read this if you are not familiar with what that means.
    Hi again, this is working perfectly but I am having another issue. I am able to write a string to 64-bit registry but not a DWORD (long). This is the code I am using for a string that is working but not for a DWORD.

    Code:
    Public Sub Registry64write(SubKey As String, ValueName As String, TheData As String)
        Dim hKey As Long, nSize As Long, RV As Long, sBuffer As String
    
        If RegCreateKeyExW(HKEY_LOCAL_MACHINE, StrPtr(SubKey), 0&, 0&, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS Or KEY_WOW64_64KEY, 0&, hKey) = ERROR_SUCCESS Then
    
            nSize = LenB(TheData) + 2&
            If RegSetValueExW(hKey, StrPtr(ValueName), 0&, REG_SZ, ByVal StrPtr(TheData), nSize) = ERROR_SUCCESS Then
    
                If RegQueryValueExW(hKey, StrPtr(ValueName), , , , nSize) = ERROR_SUCCESS Then
                    SysReAllocStringLen VarPtr(sBuffer), , nSize \ 2& - 1&
                    RV = RegQueryValueExW(hKey, StrPtr(ValueName), , , StrPtr(sBuffer), nSize): Debug.Assert RV = ERROR_SUCCESS
                    Debug.Assert sBuffer = TheData
                End If
                
            End If
        
        End If
    End Sub
    Could you please provide a sample code that will write properly to a DWORD?

    Thank you.

  5. #5
    Hyperactive Member
    Join Date
    Aug 2017
    Posts
    320

    Re: Help enumerating registry folders

    Quote Originally Posted by Mike VB View Post
    ... but I am having another issue. I am able to write a string to 64-bit registry but not a DWORD (long). This is the code I am using for a string that is working but not for a DWORD.
    It appears your code came from here. Here's how you can make it write a DWORD value instead:

    Code:
    Private Const REG_DWORD As Long = 4
    
    Public Sub Registry64write(ByRef SubKey As String, ByRef ValueName As String, ByVal TheData As Long)
        Dim hKey As Long, RV As Long
    
        If RegCreateKeyExW(HKEY_LOCAL_MACHINE, StrPtr(SubKey), 0&, 0&, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS Or KEY_WOW64_64KEY, 0&, hKey) = ERROR_SUCCESS Then
            If RegSetValueExW(hKey, StrPtr(ValueName), 0&, REG_DWORD, TheData, LenB(TheData)) <> ERROR_SUCCESS Then
                Err.Raise vbObjectError, , "Failed to write specified data!"
            End If
    
           'Don't forget to close the handle!
            RV = RegCloseKey(hKey): Debug.Assert RV = ERROR_SUCCESS
        End If
    End Sub
    BTW, you don't really need the RegQueryValueExW block if RegSetValueExW already reports that it successfully wrote TheData. You could rewrite that code so that it raises an error instead if RegSetValueExW failed (i.e. it returned a value other than ERROR_SUCCESS. Note: RegSetValueExW returns a value that you can pass to the FormatMessage API function to get a description of the error).

  6. #6

    Thread Starter
    New Member
    Join Date
    Mar 2014
    Posts
    11

    Re: Help enumerating registry folders

    Quote Originally Posted by Victor Bravo VI View Post
    It appears your code came from here. Here's how you can make it write a DWORD value instead:

    Code:
    Private Const REG_DWORD As Long = 4
    
    Public Sub Registry64write(ByRef SubKey As String, ByRef ValueName As String, ByVal TheData As Long)
        Dim hKey As Long, RV As Long
    
        If RegCreateKeyExW(HKEY_LOCAL_MACHINE, StrPtr(SubKey), 0&, 0&, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS Or KEY_WOW64_64KEY, 0&, hKey) = ERROR_SUCCESS Then
            If RegSetValueExW(hKey, StrPtr(ValueName), 0&, REG_DWORD, TheData, LenB(TheData)) <> ERROR_SUCCESS Then
                Err.Raise vbObjectError, , "Failed to write specified data!"
            End If
    
           'Don't forget to close the handle!
            RV = RegCloseKey(hKey): Debug.Assert RV = ERROR_SUCCESS
        End If
    End Sub
    BTW, you don't really need the RegQueryValueExW block if RegSetValueExW already reports that it successfully wrote TheData. You could rewrite that code so that it raises an error instead if RegSetValueExW failed (i.e. it returned a value other than ERROR_SUCCESS. Note: RegSetValueExW returns a value that you can pass to the FormatMessage API function to get a description of the error).
    I really cannot thank you enough. You and Grant both, thank you! Long live VB6!

  7. #7

    Thread Starter
    New Member
    Join Date
    Mar 2014
    Posts
    11

    Re: Help enumerating registry folders

    Hi guys. I am having an issue reading a Binary Value. I only need to read it, not write to it. Could anyone help?

    Thanks!

  8. #8
    Hyperactive Member
    Join Date
    Aug 2017
    Posts
    320

    Re: Help enumerating registry folders

    Here's an example:

    Code:
    Option Explicit
    
    Private Const ERROR_SUCCESS   As Long = 0
    Private Const KEY_QUERY_VALUE As Long = &H1
    Private Const KEY_WOW64_64KEY As Long = &H100
    Private Const REG_BINARY      As Long = 3
    
    Public Enum PredefinedKeys
        HKEY_CLASSES_ROOT = &H80000000
        HKEY_CURRENT_USER = &H80000001
        HKEY_LOCAL_MACHINE = &H80000002
        HKEY_USERS = &H80000003
        HKEY_PERFORMANCE_DATA = &H80000004
        HKEY_CURRENT_CONFIG = &H80000005
        HKEY_DYN_DATA = &H80000006
    End Enum
    #If False Then
        Dim HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, _
        HKEY_USERS, HKEY_PERFORMANCE_DATA, HKEY_CURRENT_CONFIG, HKEY_DYN_DATA
    #End If
    
    Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
    Private Declare Function RegOpenKeyExW Lib "advapi32.dll" (ByVal hKey As Long, ByVal lpSubKey As Long, ByVal ulOptions As Long, ByVal samDesired As Long, ByRef phkResult As Long) As Long
    Private Declare Function RegQueryValueExW Lib "advapi32.dll" (ByVal hKey As Long, Optional ByVal lpValueName As Long, Optional ByVal lpReserved As Long, Optional ByRef lpType As Long, Optional ByVal lpData As Long, Optional ByRef lpcbData As Long) As Long
    
    Public Function RegReadBin(ByVal Key As PredefinedKeys, _
                               ByRef SubKey As String, _
                               ByRef Value As String, _
                      Optional ByVal Access64BitKey As Boolean) As Byte()
    
        Dim hKey As Long, nSize As Long, RegType As Long, RV As Long, Buffer() As Byte
    
        If RegOpenKeyExW(Key, StrPtr(SubKey), 0&, KEY_QUERY_VALUE Or KEY_WOW64_64KEY And Access64BitKey, hKey) = ERROR_SUCCESS Then
            If RegQueryValueExW(hKey, StrPtr(Value), , RegType, , nSize) = ERROR_SUCCESS And RegType = REG_BINARY Then
                ReDim Buffer(0& To nSize - 1&) As Byte
                RV = RegQueryValueExW(hKey, StrPtr(Value), , , VarPtr(Buffer(0&)), nSize): Debug.Assert RV = ERROR_SUCCESS
            End If
    
            RV = RegCloseKey(hKey): Debug.Assert RV = ERROR_SUCCESS
        End If
    
        RegReadBin = Buffer
    End Function
    Code:
    'Usage example
    Debug.Print RegReadBin(HKEY_LOCAL_MACHINE, "SOFTWARE\Microsoft\Windows NT\CurrentVersion", "DigitalProductId", True)(0&)

  9. #9

    Thread Starter
    New Member
    Join Date
    Mar 2014
    Posts
    11

    Re: Help enumerating registry folders

    Quote Originally Posted by Victor Bravo VI View Post
    Here's an example:

    Code:
    Option Explicit
    
    Private Const ERROR_SUCCESS   As Long = 0
    Private Const KEY_QUERY_VALUE As Long = &H1
    Private Const KEY_WOW64_64KEY As Long = &H100
    Private Const REG_BINARY      As Long = 3
    
    Public Enum PredefinedKeys
        HKEY_CLASSES_ROOT = &H80000000
        HKEY_CURRENT_USER = &H80000001
        HKEY_LOCAL_MACHINE = &H80000002
        HKEY_USERS = &H80000003
        HKEY_PERFORMANCE_DATA = &H80000004
        HKEY_CURRENT_CONFIG = &H80000005
        HKEY_DYN_DATA = &H80000006
    End Enum
    #If False Then
        Dim HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, _
        HKEY_USERS, HKEY_PERFORMANCE_DATA, HKEY_CURRENT_CONFIG, HKEY_DYN_DATA
    #End If
    
    Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
    Private Declare Function RegOpenKeyExW Lib "advapi32.dll" (ByVal hKey As Long, ByVal lpSubKey As Long, ByVal ulOptions As Long, ByVal samDesired As Long, ByRef phkResult As Long) As Long
    Private Declare Function RegQueryValueExW Lib "advapi32.dll" (ByVal hKey As Long, Optional ByVal lpValueName As Long, Optional ByVal lpReserved As Long, Optional ByRef lpType As Long, Optional ByVal lpData As Long, Optional ByRef lpcbData As Long) As Long
    
    Public Function RegReadBin(ByVal Key As PredefinedKeys, _
                               ByRef SubKey As String, _
                               ByRef Value As String, _
                      Optional ByVal Access64BitKey As Boolean) As Byte()
    
        Dim hKey As Long, nSize As Long, RegType As Long, RV As Long, Buffer() As Byte
    
        If RegOpenKeyExW(Key, StrPtr(SubKey), 0&, KEY_QUERY_VALUE Or KEY_WOW64_64KEY And Access64BitKey, hKey) = ERROR_SUCCESS Then
            If RegQueryValueExW(hKey, StrPtr(Value), , RegType, , nSize) = ERROR_SUCCESS And RegType = REG_BINARY Then
                ReDim Buffer(0& To nSize - 1&) As Byte
                RV = RegQueryValueExW(hKey, StrPtr(Value), , , VarPtr(Buffer(0&)), nSize): Debug.Assert RV = ERROR_SUCCESS
            End If
    
            RV = RegCloseKey(hKey): Debug.Assert RV = ERROR_SUCCESS
        End If
    
        RegReadBin = Buffer
    End Function
    Code:
    'Usage example
    Debug.Print RegReadBin(HKEY_LOCAL_MACHINE, "SOFTWARE\Microsoft\Windows NT\CurrentVersion", "DigitalProductId", True)(0&)
    Thank you. For some reason this returns a # and not the actual registry value.

  10. #10
    Hyperactive Member
    Join Date
    Aug 2017
    Posts
    320

    Re: Help enumerating registry folders

    Quote Originally Posted by Mike VB View Post
    For some reason this returns a # and not the actual registry value.
    If you're talking about the usage example, that is to be expected as I only wanted to print out the first element of the byte array (notice the (0&) at the end of that statement). If you'd like to see a string representation of the entire byte array, here's how you'd convert it:

    Code:
    Debug.Print """"; StrConv(RegReadBin(HKEY_LOCAL_MACHINE, "SOFTWARE\Microsoft\Windows NT\CurrentVersion", "DigitalProductId", True), vbUnicode); """"

  11. #11

    Thread Starter
    New Member
    Join Date
    Mar 2014
    Posts
    11

    Re: Help enumerating registry folders

    Quote Originally Posted by Victor Bravo VI View Post
    If you're talking about the usage example, that is to be expected as I only wanted to print out the first element of the byte array (notice the (0&) at the end of that statement). If you'd like to see a string representation of the entire byte array, here's how you'd convert it:

    Code:
    Debug.Print """"; StrConv(RegReadBin(HKEY_LOCAL_MACHINE, "SOFTWARE\Microsoft\Windows NT\CurrentVersion", "DigitalProductId", True), vbUnicode); """"
    Thank you, sir!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width