要枚举所有注册表子健的名称,实现原理为先用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,方能返回正确的子健名称。
发表评论