如何在vba中用RegEnumValue遍历枚举注册表的键值名称?

如何在vba中用RegEnumKeyEx枚举所有注册表子键的名称?一文中我们介绍了遍历注册表某个父键的所有子键的名称的方法。

接下来我们介绍在vba中遍历枚举注册表的键值的方法,遍历枚举注册表的键值的原理如下:

先用RegOpenKeyEx函数打开注册表的键,然后先调用一次RegEnumValue函数,获取其中一个键值,最后用循环的形式反复调用RegEnumValue函数,直到遍历所有键值。

以下代码将遍历注册表键HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Excel\StatusBar下的所有键值的名称:

Declare Function RegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyA" (ByVal hKey As Long, _
ByVal lpSubKey As String, phkResult As Long) As Long
Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
Declare Function RegEnumKeyEx Lib "advapi32.dll" Alias "RegEnumKeyExA" (ByVal hKey As Long, _
ByVal dwIndex As Long, ByVal lpName As String, lpcName As Long, ByVal lpReserved As Long, _
ByVal lpClass As String, ByVal lpcClass As Long, lpftLastWriteTime As FILETIME) As Long
Declare Function RegEnumValue Lib "advapi32.dll" Alias "RegEnumValueA" (ByVal hKey As Long, _
ByVal dwIndex As Long, ByVal lpValueName As String, lpcchValueName As Long, ByVal lpReserved As Long, _
lpType As Long, ByVal lpData As Long, lpcbData As Long) As Long
Type FILETIME
    dwLowDateTime As Long
    dwHighDateTime As Long
End Type
Public Enum ERegistryClassConstants
    HKEY_CLASSES_ROOT = &H80000000
    HKEY_CURRENT_USER = &H80000001
    HKEY_LOCAL_MACHINE = &H80000002
    HKEY_USERS = &H80000003
End Enum
Public Enum ERegistryValueTypes
'Predefined Value Types
    REG_NONE = (0)                         'No value type
    REG_SZ = (1)                           'Unicode nul terminated string
    REG_EXPAND_SZ = (2)                    'Unicode nul terminated string w/enviornment var
    REG_BINARY = (3)                       'Free form binary
    REG_DWORD = (4)                        '32-bit number
    REG_DWORD_LITTLE_ENDIAN = (4)          '32-bit number (same as REG_DWORD)
    REG_DWORD_BIG_ENDIAN = (5)             '32-bit number
    REG_LINK = (6)                         'Symbolic Link (unicode)
    REG_MULTI_SZ = (7)                     'Multiple Unicode strings
    REG_RESOURCE_LIST = (8)                'Resource list in the resource map
    REG_FULL_RESOURCE_DESCRIPTOR = (9)     'Resource list in the hardware description
    REG_RESOURCE_REQUIREMENTS_LIST = (10)
End Enum
Sub QQ1722187970()
    '定义变量lhKey表示打开的注册表父键的句柄
    Dim lhKey As Long
    '定义变量i表示键值的索引
    Dim i As Long
    '定义变量lType表示键值的数据类型
    Dim lType As Long
    '定义字节数组存储键值的数据字节
    Dim bData() As Byte
    '定义变量lenbData表示键值的数据的字节数
    Dim lenbData As Long
    ReDim bData(1024) As Byte
    lenbData = 1024
    Dim subKey As String
    '定义变量sValueName表示键值的名称
    Dim sValueName As String
    '定义变量lenValueName表示键值的名称的字符长度
    Dim lenValueName As Long
    Dim tFT As FILETIME
    i = 0
    '先预置缓冲区
    sValueName = Space(1024)
    '先预置缓冲区的长度
    lenValueName = 1024
    subKey = "Software\Microsoft\Office\15.0\Excel\StatusBar"
    RegOpenKey HKEY_CURRENT_USER, subKey, lhKey
    '第一次运行RegEnumValue,将dwIndex设置为0,然后逐次递增
    n = RegEnumValue(lhKey, i, sValueName, lenValueName, 0, lType, VarPtr(bData(0)), lenbData)
    '当n非0时,表示遍历结束
    Do Until n <> 0
        '提取实际的键值的名称
        Debug.Print Left(sValueName, lenValueName)
        '重置缓冲区的大小
        lenValueName = 1024
        i = i + 1
        n = RegEnumValue(lhKey, i, sValueName, lenValueName, 0, lType, VarPtr(bData(0)), lenbData)
    Loop
    RegCloseKey lhKey
End Sub

RegEnumValue函数在遍历键值的名称同时还可以获得键值的数据类型,以及键值的数据。其中参数lType表示键值的数据类型,由于注册表键值的数据类型有多种,有字符串形式,有字节形式、也有数值形式,故无法用一种变量类型代替,故这里都只获取注册表键值的数据的二进制形式,也就是bData字节数组存储的就是键值的数据的二进制值。

       

发表评论