如何在vba中用RegEnumKeyEx枚举注册表子键的名称?

要枚举所有注册表子健的名称,实现原理为先用RegOpenKey函数打开要遍历的注册表子健的父键,然后先调用一次RegEnumKeyEx函数,把索引设置为0,获得第一个子健,最后用循环不断地增加索引,获取其它子健,直到返回的值为非0,表示遍历结束,最后用RegCloseKey函数关闭打开的注册表父键。

其中RegEnumKeyEx函数的语法如下:

LONG WINAPI RegEnumKeyEx(
  _In_        HKEY      hKey,
  _In_        DWORD     dwIndex,
  _Out_       LPTSTR    lpName,
  _Inout_     LPDWORD   lpcName,
  _Reserved_  LPDWORD   lpReserved,
  _Inout_     LPTSTR    lpClass,
  _Inout_opt_ LPDWORD   lpcClass,
  _Out_opt_   PFILETIME lpftLastWriteTime
);

其中参数hKey表示要遍历的注册表父键的句柄,dwIndex参数表示子健的索引,以0开始,lpName参数为接收子健名称的缓冲区,lpcName参数为接收子健名称的缓冲区的长度,其它参数较少使用,可以全部传入Null。

比如想要遍历注册表键HKEY_CLASSES_ROOT\MIME\Database\Charset 下的所有子健的名称,可以使用如下的代码:

Public Declare Function RegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyA" (ByVal hKey As Long, _
ByVal lpSubKey As String, phkResult As Long) As Long
Private 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
Type FILETIME
    dwLowDateTime As Long
    dwHighDateTime As Long
End Type
Const HKEY_CURRENT_USER = &H80000001
Const HKEY_LOCAL_MACHINE = &H80000002
Const HKEY_CLASSES_ROOT = &H80000000
Const HKEY_USERS = &H80000003
Const HKEY_CURRENT_CONFIG = &H80000005
Sub QQ1722187970()
    Dim lhKey As Long
    Dim i As Long
    Dim subKey As String
    Dim sKeyName As String
    Dim lenKeyName As Long
    Dim tFT As FILETIME
    i = 0
    '先预置缓冲区
    sKeyName = Space(1024)
    '先预置缓冲区的长度
    lenKeyName = 1024
    subKey = "MIME\Database\Charset"
    '先打开注册表键HKEY_CLASSES_ROOT\MIME\Database\Charset
    RegOpenKey HKEY_CLASSES_ROOT, subKey, lhKey
    '第一次运行RegEnumKeyEx,将dwIndex设置为0,然后逐次递增
    n = RegEnumKeyEx(lhKey, i, sKeyName, lenKeyName, 0, vbNullString, 0, tFT)
    '当n非0时,表示遍历结束
    Do Until n <> 0
        '提取实际的键名
        Debug.Print Left(sKeyName, lenKeyName)
        '重置缓冲区的大小
        lenKeyName = 1024
        i = i + 1
        n = RegEnumKeyEx(lhKey, i, sKeyName, lenKeyName, 0, vbNullString, 0, tFT)
    Loop
    RegCloseKey lhKey
End Sub

其中的关键点在于每次调用RegEnumKeyEx之后,需要重新设置缓冲区的长度,也就是每次都要设置 lenKeyName = 1024,方能返回正确的子健名称。

       

发表评论