VB6 注册表的递归访问与面象对象模块化封装

这篇具有很好参考价值的文章主要介绍了VB6 注册表的递归访问与面象对象模块化封装。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

总述

1)较低层次的封装 “过程化模块封装” 模块: Module1包含windows API 注册表相关函数声明 及少量的 GetValue、SetValue函数等浅封装。
2)较高层次的封装 基于面向对象:类模块CEnumReg定义属性、方法、事件。

CEnumReg 接口说明

核心方法
EnumAll(hkey As Long, ByVal subkey As String)

1.该方法的作用递归枚举指定 “注册表项句柄”(或指定句柄的子项)的全部注册表项;
2. 该方法是 递归方法 ,会多次触发 EnumLeaf、 EnumNode、EnumFinished 等事件;(这里把没有子项的“键值对“称为Leaf,把有子项的称为Node)当然如果枚举失败会触发对应的错误事件:EnumError事件,当枚举完成会触发EnumFinished事件。

DeleteTreeKey(ByVal hkey As Long, ByVal subkey As String)

1.该方法的作用删除指定 “注册表项句柄”(或指定句柄的子项)的全部注册表项;
2. 该方法也是 递归方法 ,会多次触发 DeletedNode 事件;当然如果某个结点删除失败会触发对应的错误事件:DeleteError事件。

CancelEnum()

1.该方法的作用放弃枚举EnumAll方法。
2. 该方法调用后 EnumAll 并不是立即返回,CancelEnum方法只是使放弃标记可用,当递归EnumAll方法执行遇到放弃标记代码段仅放弃该层方法返回上一层调用,当上层方法也执行到放弃标记处也放弃当前层方法,直到全部递归调用全部返回。

属性

RunningNum
1.该只读属性的作用返回当前正在运行递归函数的深度。(也可理解为当前进入注册表项的层数)

事件

EnumLeaf(ByVal hkey As Long, ByRef parentNodes() As String, ByVal parentNodeLevel As Long, ByVal subkey As String, ByVal keyName As String, keyValue As Variant, keyValueType As Long)
当EnumAll递归枚举到没有子项的注册项时(即键值对)该事件触发。
1.参数hkey注册表项句柄
2.参数parentNodes()存放当前项的每级父结点项的名称(键名)。
3.参数parentNodeLevel当前结点所在层级。
4.参数subkey子项名(子键名)
5.参数keyName 键值对的键名
6.参数keyValue 键值对的键值

EnumNode、DeletedNode、EnumFinished、DeleteError、EnumError 事件参数基本类似或根据参数名可以推测出其含义,或跟据源码推测出其用法,这里就不在赘述。

module1

Option Explicit

'注册表主键
Public Enum enumRegMainKey
   iHKEY_CLASSES_ROOT = &H80000000
   iHKEY_CURRENT_USER = &H80000001
   iHKEY_LOCAL_MACHINE = &H80000002
   iHKEY_USERS = &H80000003
   iHKEY_CURRENT_CONFIG = &H80000005
End Enum

'注册表数据类型
Public Enum enumRegSzType
   iREG_SZ = &H1 '符串值 (REG_SZ) 最长255
   iREG_EXPAND_SZ = &H2 '可扩充符串值
   iREG_BINARY = &H3 '二进制值 (REG_BINARY)
   iREG_DWORD = &H4 'DWORD值(REG_DWORD)由 4 字节长(32 位整数)的数字表示的数据。
   iREG_NONE = 0& '空
   iREG_DWORD_LITTLE_ENDIAN = 4&
   iREG_DWORD_BIG_ENDIAN = 5&
   iREG_LINK = 6&
   iREG_MULTI_SZ = 7& '多字符串值 (REG_SZ) 最长255
   iREG_RESOURCE_LIST = 8&
   iREG_FULL_RESOURCE_DEscription = 9&
   iREG_RESOURCE_REQUIREMENTS_LIST = 10&
End Enum
'注册表
Public Const ERROR_SUCCESS = 0&
Public Const ERROR_BADDB = 1009&
Public Const ERROR_BADKEY = 1010&
Public Const ERROR_CANTOPEN = 1011&
Public Const ERROR_CANTREAD = 1012&
Public Const ERROR_CANTWRITE = 1013&
Public Const ERROR_OUTOFMEMORY = 14&
Public Const ERROR_INVALID_PARAMETER = 87&
Public Const ERROR_ACCESS_DENIED = 5&
Public Const ERROR_NO_MORE_ITEMS = 259&
Public Const ERROR_MORE_DATA = 234&
Public Const KEY_QUERY_VALUE = &H1&
Public Const KEY_SET_VALUE = &H2&
Public Const KEY_CREATE_SUB_KEY = &H4&
Public Const KEY_ENUMERATE_SUB_KEYS = &H8&
Public Const KEY_NOTIFY = &H10&
Public Const KEY_CREATE_LINK = &H20&
Public Const SYNCHRONIZE = &H100000
Public Const READ_CONTROL = &H20000
Public Const WRITE_DAC = &H40000
Public Const WRITE_OWNER = &H80000
Public Const STANDARD_RIGHTS_REQUIRED = &HF0000
Public Const STANDARD_RIGHTS_READ = READ_CONTROL
Public Const STANDARD_RIGHTS_WRITE = READ_CONTROL
Public Const STANDARD_RIGHTS_EXECUTE = READ_CONTROL
Public Const KEY_READ = STANDARD_RIGHTS_READ Or KEY_QUERY_VALUE Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY
Public Const KEY_WRITE = STANDARD_RIGHTS_WRITE Or KEY_SET_VALUE Or KEY_CREATE_SUB_KEY
Public Const KEY_EXECUTE = KEY_READ
Public Declare Function RegCreateKey Lib "advapi32.dll" Alias "RegCreateKeyA" (ByVal hkey As Long, ByVal lpSubKey As String, phkResult As Long) As Long
Public Declare Function RegCreateKeyEx Lib "advapi32.dll" Alias "RegCreateKeyExA" (ByVal hkey As Long, ByVal lpSubKey As String, ByVal Reserved As Long, ByVal lpClass As String, ByVal dwOptions As Long, ByVal samDesired As Long, lpSecurityAttributes As SECURITY_ATTRIBUTES, phkResult As Long, lpdwDisposition As Long) As Long
Public Declare Function RegEnumValue Lib "advapi32.dll" Alias "RegEnumValueA" (ByVal hkey As Long, ByVal dwIndex As Long, ByVal lpValueName As String, lpcbValueName As Long, ByVal lpReserved As Long, lpType As Long, lpData As Byte, lpcbData As Long) 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 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 RegCloseKey Lib "advapi32.dll" (ByVal hkey As Long) As Long
Public Declare Function RegDeleteValue Lib "advapi32.dll" Alias "RegDeleteValueA" (ByVal hkey As Long, ByVal lpValueName As String) As Long


Public Declare Function RegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hkey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, ByVal lpData As String, ByVal cbData As Long) As Long
Public Declare Function RegSetValueExLong Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hkey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, lpData As Long, ByVal cbData As Long) As Long

Public Declare Function RegSetValueExA Lib "advapi32.dll" (ByVal hkey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, ByRef lpData As Long, ByVal cbData As Long) As Long
Public Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hkey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, lpType As Long, lpData As Any, lpcbData As Long) As Long         ' Note that if you declare the lpData parameter as String, you must pass it By Value.

Public Declare Function RegQueryInfoKey Lib "advapi32.dll" Alias "RegQueryInfoKeyA" (ByVal hkey As Long, ByVal lpClass As String, lpcbClass As Long, ByVal lpReserved As Long, lpcSubKeys As Long, lpcbMaxSubKeyLen As Long, lpcbMaxClassLen As Long, lpcValues As Long, lpcbMaxValueNameLen As Long, lpcbMaxValueLen As Long, lpcbSecurityDescriptor As Long, lpftLastWriteTime As FILETIME) As Long

Public Declare Function RegDeleteKey Lib "advapi32.dll" Alias "RegDeleteKeyA" (ByVal hkey As Long, ByVal lpSubKey As String) As Long

Public Declare Function RegSaveKey Lib "advapi32.dll" Alias "RegSaveKeyA" (ByVal hkey As Long, ByVal lpFile As String, ByVal lpSecurityAttributes As Long) As Long
Public Declare Function RegRestoreKey Lib "advapi32.dll" Alias "RegRestoreKeyA" (ByVal hkey As Long, ByVal lpFile As String, ByVal dwflags As Long) As Long


Public Type FILETIME
   dwLowDateTime As Long
   dwHighDateTime As Long
End Type
Public Type SECURITY_ATTRIBUTES
   nLength As Long
   lpSecurityDescription As Long
   bInheritHandle As Boolean
End Type

'键值对
Public Type CKVP
    keyName As String
    keyValue As Long
End Type



Public Function GetValue(ByVal mainKey As enumRegMainKey, _
                        ByVal subkey As String, _
                        ByVal keyV As String, _
                        ByRef sValue As Variant, _
                        Optional ByRef rlngErrNum As Long, _
                        Optional ByRef rstrErrDescr As String) As Boolean
   Dim hkey As Long, lType As Long, lBuffer As Long, sBuffer As String, ldata As Long
   On Error GoTo GetValueErr
   GetValue = False
   If RegOpenKeyEx(mainKey, subkey, 0, KEY_READ, hkey) <> ERROR_SUCCESS Then
      Err.Raise vbObjectError + 1, , "获取注册表值时出错"
   End If
   If RegQueryValueEx(hkey, keyV, 0, lType, ByVal 0, lBuffer) <> ERROR_SUCCESS Then
      Err.Raise vbObjectError + 1, , "获取注册表值时出错"
   End If
   Select Case lType
      Case iREG_SZ
         lBuffer = 255
         sBuffer = Space(lBuffer)
         If RegQueryValueEx(hkey, keyV, 0, lType, ByVal sBuffer, lBuffer) <> ERROR_SUCCESS Then
            Err.Raise vbObjectError + 1, , "获取注册表值时出错"
         End If
         sValue = Left(sBuffer, InStr(sBuffer, Chr(0)) - 1)
      Case iREG_EXPAND_SZ
         sBuffer = Space(lBuffer)
         If RegQueryValueEx(hkey, keyV, 0, lType, ByVal sBuffer, lBuffer) <> ERROR_SUCCESS Then
            Err.Raise vbObjectError + 1, , "获取注册表值时出错"
         End If
         sValue = Left(sBuffer, InStr(sBuffer, Chr(0)) - 1)
      Case iREG_DWORD
         If RegQueryValueEx(hkey, keyV, 0, lType, ldata, lBuffer) <> ERROR_SUCCESS Then
            Err.Raise vbObjectError + 1, , "获取注册表值时出错"
         End If
         sValue = ldata
      Case iREG_BINARY
         If RegQueryValueEx(hkey, keyV, 0, lType, ldata, lBuffer) <> ERROR_SUCCESS Then
            Err.Raise vbObjectError + 1, , "获取注册表值时出错"
         End If
         sValue = ldata
   End Select
   If RegCloseKey(hkey) <> ERROR_SUCCESS Then
      Err.Raise vbObjectError + 1, , "获取注册表值时出错"
   End If
   GetValue = True
   Err.Clear
GetValueErr:
   rlngErrNum = Err.Number
   rstrErrDescr = Err.Description
End Function
Public Function SetValue(ByVal mainKey As enumRegMainKey, _
                        ByVal subkey As String, _
                        ByVal keyV As String, _
                        ByVal lType As enumRegSzType, _
                        ByVal sValue As Variant, _
                        Optional ByRef rlngErrNum As Long, _
                        Optional ByRef rstrErrDescr As String) As Boolean
   Dim s As Long, lBuffer As Long, hkey As Long
   Dim ss As SECURITY_ATTRIBUTES
   On Error GoTo SetValueErr
   SetValue = False
   ss.nLength = Len(ss)
   ss.lpSecurityDescription = 0
   ss.bInheritHandle = True
   If RegCreateKeyEx(mainKey, "", 0, "", 0, KEY_WRITE, ss, hkey, s) <> ERROR_SUCCESS Then
      Err.Raise vbObjectError + 1, , "设置注册表时出错"
   End If
   Select Case lType
      Case iREG_SZ
         lBuffer = LenB(sValue)
         If RegSetValueEx(hkey, subkey, 0, lType, ByVal sValue, lBuffer) <> ERROR_SUCCESS Then
            Err.Raise vbObjectError + 1, , "设置注册表时出错"
         End If
      Case iREG_EXPAND_SZ
         lBuffer = LenB(sValue)
         If RegSetValueEx(hkey, subkey, 0, lType, ByVal sValue, lBuffer) <> ERROR_SUCCESS Then
            Err.Raise vbObjectError + 1, , "设置注册表时出错"
         End If
      Case iREG_DWORD
         lBuffer = 4
         If RegSetValueExA(hkey, subkey, 0, lType, sValue, lBuffer) <> ERROR_SUCCESS Then
            Err.Raise vbObjectError + 1, , "设置注册表时出错"
         End If
      Case iREG_BINARY
         lBuffer = 4
         If RegSetValueExA(hkey, subkey, 0, lType, sValue, lBuffer) <> ERROR_SUCCESS Then
            Err.Raise vbObjectError + 1, , "设置注册表时出错"
         End If
      Case Else
         Err.Raise vbObjectError + 1, , "不支持该参数类型"
   End Select
   If RegCloseKey(hkey) <> ERROR_SUCCESS Then
      Err.Raise vbObjectError + 1, , "设置注册表时出错"
   End If
   SetValue = True
   Err.Clear
SetValueErr:
   rlngErrNum = Err.Number
   rstrErrDescr = Err.Description
End Function
Public Function DeleteValue(ByVal mainKey As enumRegMainKey, _
                           ByVal subkey As String, _
                           ByVal keyName As String, _
                           Optional ByRef rlngErrNum As Long, _
                           Optional ByRef rstrErrDescr As String) As Boolean
   Dim hkey As Long
   On Error GoTo DeleteValueErr
   DeleteValue = False
   If RegOpenKeyEx(mainKey, subkey, 0, KEY_WRITE, hkey) <> ERROR_SUCCESS Then
      Err.Raise vbObjectError + 1, , "删除注册表值时出错"
   End If
   If RegDeleteValue(hkey, keyName) <> ERROR_SUCCESS Then
      Err.Raise vbObjectError + 1, , "删除注册表值时出错"
   End If
   If RegCloseKey(hkey) <> ERROR_SUCCESS Then
      Err.Raise vbObjectError + 1, , "删除注册表值时出错"
   End If
   DeleteValue = True
   Err.Clear
DeleteValueErr:
   rlngErrNum = Err.Number
   rstrErrDescr = Err.Description
End Function
Public Function DeleteKey(ByVal mainKey As enumRegMainKey, _
                           ByVal subkey As String, _
                           Optional ByRef rlngErrNum As Long, _
                           Optional ByRef rstrErrDescr As String) As Boolean
   Dim hkey As Long
   On Error GoTo DeleteKeyErr
   DeleteKey = False
   'RegOpenKeyEx(hkey, subkey, 0, KEY_READ, hSubKey)
   If RegOpenKeyEx(mainKey, subkey, 0, KEY_WRITE, hkey) <> ERROR_SUCCESS Then
      Err.Raise vbObjectError + 1, , "删除注册表值时出错"
   End If
   If RegDeleteKey(hkey, subkey) <> ERROR_SUCCESS Then
      Err.Raise vbObjectError + 1, , "删除注册表值时出错"
   End If
   If RegCloseKey(hkey) <> ERROR_SUCCESS Then
      Err.Raise vbObjectError + 1, , "删除注册表值时出错"
   End If
   DeleteKey = True
   Err.Clear
DeleteKeyErr:
   rlngErrNum = Err.Number
   rstrErrDescr = Err.Description
End Function

类模块CRegEnum.cls

Option Explicit
Dim mCancelEnum As Boolean


Dim rlngErrNum As Long, rstrErrDescr As String

Dim parentNodes(16) As String

'要引发该事件,请遵循下列语法使用 RaiseEvent:
'RaiseEvent EnumLeaf[(arg1, arg2, ... , argn)]
Public Event EnumLeaf(ByVal hkey As Long, ByRef parentNodes() As String, ByVal parentNodeLevel As Long, ByVal subkey As String, ByVal keyName As String, keyValue As Variant, keyValueType As Long)

'要引发该事件,请遵循下列语法使用 RaiseEvent:
'RaiseEvent EnumNode[(arg1, arg2, ... , argn)]
Public Event EnumNode(ByVal hkey As Long, ByRef parentNodes() As String, ByVal parentNodeLevel As Long, ByVal subkey As String)


'要引发该事件,请遵循下列语法使用 RaiseEvent:
'RaiseEvent DeletedNode[(arg1, arg2, ... , argn)]
Public Event DeletedNode(ByVal hkey As Long, ByVal subkey As String)


'要引发该事件,请遵循下列语法使用 RaiseEvent:
'RaiseEvent EnumFinished[(arg1, arg2, ... , argn)]
Public Event EnumFinished()

'要引发该事件,请遵循下列语法使用 RaiseEvent:
'RaiseEvent DeleteError[(arg1, arg2, ... , argn)]
Public Event DeleteError(ByVal hkey As Long, ByVal subkey As String, ByVal errNum As Long, ByVal errDescr As String)

'要引发该事件,请遵循下列语法使用 RaiseEvent:
'RaiseEvent DeleteError[(arg1, arg2, ... , argn)]
Public Event EnumError(ByRef parentNodes() As String, ByVal parentNodeLevel As Long, ByVal errNum As Long, ByVal errDescr As String)


'保持属性值的局部变量
Private mvarHKEY_CURRENT_USER As String '局部复制
Private mvarHKEY_LOCAL_MACHINE As String '局部复制
Private mvarHKEY_CLASSES_ROOT As String '局部复制
Private mvarHKEY_CURRENT_CONFIG As String '局部复制
Private mvarHKEY_USERS As String '局部复制
'保持属性值的局部变量
Private mvarRunningNum As Integer '局部复制


Public Property Get RunningNum() As Integer
'检索属性值时使用,位于赋值语句的右边。
'Syntax: Debug.Print X.RunningNum
    RunningNum = mvarRunningNum
End Property

'Const HKEY_CURRENT_USER = "HKEY_CURRENT_USER"
'Const HKEY_LOCAL_MACHINE = "HKEY_LOCAL_MACHINE"
'Const HKEY_CLASSES_ROOT = "HKEY_CLASSES_ROOT"
'Const HKEY_CURRENT_CONFIG = "HKEY_CURRENT_CONFIG"
'Const HKEY_USERS = "HKEY_USERS"
'======================================================
'如果根返对应根名称不是则返回其值
'======================================================
Public Function GetRegKeyName(ByVal keyValue As Long) As String
    'On Error GoTo GetValueErr
    Select Case keyValue
    Case &H80000001
        GetRegKeyName = "HKEY_CURRENT_USER"
    Case &H80000002
    GetRegKeyName = "HKEY_LOCAL_MACHINE"
    Case &H80000000
    GetRegKeyName = "HKEY_CLASSES_ROOT"
    Case &H80000005
    GetRegKeyName = "HKEY_CURRENT_CONFIG"
    Case &H80000003
    GetRegKeyName = "HKEY_USERS"
    Case Else
        GetRegKeyName = CStr(keyValue)
     'Err.Raise vbObjectError + 1, , "不存在注册表根键名"
     
   End Select
   
'   Err.Clear
'GetValueErr:
'   rlngErrNum = Err.Number
'   rstrErrDescr = Err.Description
   'Debug.Print rstrErrDescr

End Function

'作用:枚举注册表项(及子项)
'此函数为递归函数
'会多次引发 EnumLeaf、 EnumNode、EnumFinished 等事件
Public Function EnumAll(hkey As Long, ByVal subkey As String)
   Dim dwIndex As Long, lType As Long, lBuffer As Long, sBuffer As String
   Dim sLeafKeyName       As String, lenLeafKeyName       As Long
   Dim sNodeKeyName       As String, lenNodeKeyName       As Long
   Dim LWT As FILETIME
   Dim hSubKey As Long '被打开子键句柄
   mvarRunningNum = mvarRunningNum + 1
   'MsgBox mvarRunningNum
   Debug.Print "=======>mvarRunningNum"; mvarRunningNum
   If Len(subkey) > 0 And mvarRunningNum = 1 Then
   parentNodes(mvarRunningNum - 1) = GetRegKeyName(hkey) + "\" + subkey
   ElseIf Len(subkey) > 0 Then
   parentNodes(mvarRunningNum - 1) = subkey
   Else
   parentNodes(mvarRunningNum - 1) = GetRegKeyName(hkey)
   End If
   
   If mCancelEnum Then
        Debug.Print "1取消枚举"
        'mvarRunningNum = mvarRunningNum - 1
        GoTo GetValueErr
    
   End If
   Const BUFFERLENTH = 1024
   On Error GoTo GetValueErr

   
   If RegOpenKeyEx(hkey, subkey, 0, KEY_READ, hSubKey) <> ERROR_SUCCESS Then
      'Debug.Print "打开注册表时出错"
      Err.Raise vbObjectError + 1, , "打开注册表时出错"
   End If
   Debug.Print "打开:", "父:"; hkey; "subkey:"; subkey, "子:"; hSubKey
   
   '确认是根
'    If Len(keyPath) <= 0 Then
'     keyPath = GetRegKeyName(hkey)
'   End If

    
   
   
   'Debug.Print keyPath + "\" + subkey + " 子键值:", hSubKey
   Dim NameMaxLenth As Long
   Dim leafCount As Long '叶子个数
   Dim nodeCount As Long '结点
    Dim bData() As Byte
    '定义变量lenbData表示键值的数据的字节数
    Dim lenbData As Long
    ReDim bData(BUFFERLENTH) As Byte
    lenbData = BUFFERLENTH
   Dim sClass As String, lClass As Long
   Dim lValueMaxBytes As Long '结点值的最大字节数
   
   
   lClass = BUFFERLENTH
   sClass = String(lClass, Chr(0))

   Dim outMaxSubKeyLen As Long
   Dim outlSubKey As Long
   
   outlSubKey = BUFFERLENTH
   outMaxSubKeyLen = BUFFERLENTH
   If RegQueryInfoKey(hSubKey, sClass, lClass, 0, nodeCount, outlSubKey, outMaxSubKeyLen, leafCount, NameMaxLenth, lValueMaxBytes, 0, LWT) <> ERROR_SUCCESS Then
      Err.Raise vbObjectError + 1, , "查询注册表信息时出错"
   End If
        'Debug.Print keyPath, "数据类型:", lClass
    dwIndex = 0
    
    For dwIndex = dwIndex + 1 To leafCount
       If mCancelEnum Then
        Debug.Print "2取消枚举";
        GoTo GetValueErr
       End If
        'Debug.Print "in:", dwIndex, leafCount
        sLeafKeyName = String(BUFFERLENTH, Chr(0))
        lenLeafKeyName = Len(sLeafKeyName)
        '方法1
        'leafCount - dwIndex 倒序枚举为了 在枚举事件中删除枚举项引起枚举下标变化导致接下的枚举失败
        If RegEnumValue(hSubKey, leafCount - dwIndex, sLeafKeyName, lenLeafKeyName, 0, lType, bData(0), lenbData) <> ERROR_SUCCESS Then
           Err.Raise vbObjectError + 1, , "枚举注册表值时出错"
        End If
        'Debug.Print "Type:", lType
        Dim sLeafValue As String
        sLeafValue = convertdata(hSubKey, sLeafKeyName, lType)
        RaiseEvent EnumLeaf(hSubKey, parentNodes(), mvarRunningNum - 1, subkey, Left(sLeafKeyName, lenLeafKeyName), sLeafValue, lType)
        lenLeafKeyName = BUFFERLENTH
        lenbData = BUFFERLENTH
    Next
    'Debug.Print "out:", dwIndex, leafCount
    
    dwIndex = 0
    For dwIndex = dwIndex + 1 To nodeCount
       If mCancelEnum Then
        Debug.Print "3取消枚举";
        GoTo GetValueErr
       End If
        'Debug.Print "in:", dwIndex, nodeCount
        'RegEnumKeyEx(lhSubKey, i, sKeyName, lenKeyName, 0, vbNullString, 0, tFT)
        sNodeKeyName = String(BUFFERLENTH, Chr(0))
        lenNodeKeyName = Len(sNodeKeyName)
        sClass = String(BUFFERLENTH, Chr(0))
        lClass = Len(sClass)
        If RegEnumKeyEx(hSubKey, nodeCount - dwIndex, sNodeKeyName, lenNodeKeyName, 0, sClass, lClass, LWT) <> ERROR_SUCCESS Then
            Err.Raise vbObjectError + 1, , "枚举注册表键时出错"
        End If
        
                
        DoEvents
        
        '在枚举前激发事件 如果进行删除操作 后面就没法枚举了
        Call EnumAll(hSubKey, Left(sNodeKeyName, lenNodeKeyName))
        
        '需要选择一合理的地方
        RaiseEvent EnumNode(hSubKey, parentNodes(), mvarRunningNum - 1, Left(sNodeKeyName, lenNodeKeyName))
        'lenKeyName会被修改
        lenNodeKeyName = BUFFERLENTH
    Next
    'Debug.Print "out:", dwIndex, nodeCount

'    Dim n As Long, i As Long
'    n = RegEnumKeyEx(hSubKey, i, sKeyName, lenKeyName, 0, vbNullString, 0, LWT)
'    '当n非0时,表示遍历结束
'    Do Until n <> 0
'        RaiseEvent EnumNode(GetRegMainKeyName(hSubKey), subkey, Left(sKeyName, lenKeyName), bData(0))
'        '提取实际的键名
'        Debug.Print Left(sKeyName, lenKeyName)
'        '重置缓冲区的大小
'        lenKeyName = 1024
'        i = i + 1
'        n = RegEnumKeyEx(hSubKey, i, sKeyName, lenKeyName, 0, vbNullString, 0, LWT)
'    Loop
    
   If RegCloseKey(hSubKey) <> ERROR_SUCCESS Then
      Err.Raise vbObjectError + 1, , "关闭注册表时出错"
   End If
   
   Debug.Print "关闭:", hSubKey
   Err.Clear
GetValueErr:
   rlngErrNum = Err.Number
   rstrErrDescr = Err.Description
   mvarRunningNum = mvarRunningNum - 1
   If mvarRunningNum <= 0 Then
        '重置取消标志
        mCancelEnum = False
        RaiseEvent EnumFinished
    End If
    
   If rlngErrNum <> 0 Then
    RaiseEvent EnumError(parentNodes(), mvarRunningNum - 1, rlngErrNum, rstrErrDescr)
   End If
   'MsgBox CStr(rlngErrNum) + "@:" + Err.Description
   Debug.Print "<======mvarRunningNum"; mvarRunningNum
   Debug.Print rstrErrDescr
End Function

Function convertdata(ByVal hkey As Long, ByVal subkey As String, ByVal lType As Long) As String
        Dim sValue As String
        Dim keyV As String
        Dim lBuffer As Long, sBuffer As String, ldata As Long

         Select Case lType
           Case iREG_SZ
              lBuffer = 1024
              sBuffer = Space(lBuffer)
              If RegQueryValueEx(hkey, subkey, 0, lType, ByVal sBuffer, lBuffer) <> ERROR_SUCCESS Then
                 Err.Raise vbObjectError + 1, , "获取注册表值时出错1"
              End If
              sValue = Left(sBuffer, InStr(sBuffer, Chr(0)) - 1)
           Case iREG_EXPAND_SZ
              lBuffer = 1024
              sBuffer = Space(lBuffer)
              If RegQueryValueEx(hkey, subkey, 0, lType, ByVal sBuffer, lBuffer) <> ERROR_SUCCESS Then
                 Err.Raise vbObjectError + 1, , "获取注册表值时出错2"
              End If
              sValue = Left(sBuffer, InStr(sBuffer, Chr(0)) - 1)
           Case iREG_DWORD
                lBuffer = 4
              If RegQueryValueEx(hkey, subkey, 0, lType, ldata, lBuffer) <> ERROR_SUCCESS Then
                 Err.Raise vbObjectError + 1, , "获取注册表值时出错3"
              End If
              sValue = ldata
           Case iREG_BINARY
                lBuffer = 4
              If RegQueryValueEx(hkey, subkey, 0, lType, ldata, lBuffer) <> ERROR_SUCCESS Then
                 Err.Raise vbObjectError + 1, , "获取注册表值时出错4"
              End If
              sValue = ldata
        End Select
        convertdata = sValue
End Function

Sub Class_Initialize()
    mCancelEnum = False
    mvarRunningNum = 0
    mvarHKEY_CURRENT_USER = "HKEY_CURRENT_USER"
    mvarHKEY_LOCAL_MACHINE = "HKEY_LOCAL_MACHINE"
    mvarHKEY_CLASSES_ROOT = "HKEY_CLASSES_ROOT"
    mvarHKEY_CURRENT_CONFIG = "HKEY_CURRENT_CONFIG"
    mvarHKEY_USERS = "HKEY_USERS"
    
End Sub
'放弃枚举
Sub CancelEnum()
 mCancelEnum = True
End Sub
'作用:删除注册表项(及子项)
'此函数为递归函数
'会多次引发DeletedNode事件
Public Function DeleteTreeKey(ByVal hkey As Long, ByVal subkey As String)
   Dim hSubKey As Long
   Const BUFFERLENTH = 1024
   
   Dim rlngErrNum As Long
   Dim rstrErrDescr As String
   
   On Error GoTo DeleteKeyErr
   
    If RegOpenKeyEx(hkey, subkey, 0, KEY_READ, hSubKey) <> ERROR_SUCCESS Then
        
        Err.Raise vbObjectError + 1, , "打开注册表时出错"
    End If
    Debug.Print "打开"; hSubKey, "subkey:"; subkey
    Debug.Print "====>"; subkey
    Dim LWT As FILETIME
    Dim NameMaxLenth As Long
    Dim nodeCount As Long, leafCount As Long '结点
    
    Dim sClass As String, lClass As Long
    Dim lValueMaxBytes As Long '结点值的最大字节数
   
    Debug.Print "查询:"; hSubKey, "subkey:"; subkey
    If RegQueryInfoKey(hSubKey, sClass, lClass, 0, nodeCount, 0, 0, leafCount, NameMaxLenth, lValueMaxBytes, 0, LWT) <> ERROR_SUCCESS Then
       Err.Raise vbObjectError + 1, , "查询注册表信息时出错"
    End If
        'Debug.Print keyPath, "数据类型:", lClass
    Debug.Print "检查是否有子目录"
    
    Dim deleted As Boolean
    deleted = False
    If nodeCount = 0 Then
        Debug.Print "准备删除:"; hSubKey, "subkey:"; subkey
        If RegDeleteKey(hSubKey, "") <> ERROR_SUCCESS Then
            Err.Raise vbObjectError + 1, , "删除注册表键时出错"
        Else
            deleted = True
            RaiseEvent DeletedNode(hSubKey, subkey)
            Debug.Print "已经删除:"; hSubKey, "subkey:"; subkey
        End If
        
    Else
        Dim dwIndex As Long
        Debug.Print "执行枚举"
        dwIndex = 0
        For dwIndex = nodeCount To 1 Step -1
        
            'Debug.Print "in:", dwIndex, nodeCount
            'RegEnumKeyEx(lhSubKey, i, sKeyName, lenKeyName, 0, vbNullString, 0, tFT)
            Dim sNodeKeyName As String, lenNodeKeyName As Long
            sNodeKeyName = String(BUFFERLENTH, Chr(0))
            lenNodeKeyName = Len(sNodeKeyName)
            sClass = String(BUFFERLENTH, Chr(0))
            lClass = Len(sClass)
            If RegEnumKeyEx(hSubKey, dwIndex - 1, sNodeKeyName, lenNodeKeyName, 0, sClass, lClass, LWT) <> ERROR_SUCCESS Then
                Err.Raise vbObjectError + 1, , "枚举注册表键时出错"
            End If
            
            DoEvents
            Debug.Print "执行回调start"; dwIndex, hSubKey, Left(sNodeKeyName, lenNodeKeyName)
            Call DeleteTreeKey(hSubKey, Left(sNodeKeyName, lenNodeKeyName))
            Debug.Print "执行回调end"; dwIndex, hSubKey, Left(sNodeKeyName, lenNodeKeyName)
            'lenKeyName会被修改
            lenNodeKeyName = BUFFERLENTH
        Next
    
    End If


    'Debug.Print "out:", dwIndex, nodeCount
    If Not deleted Then
        If RegDeleteKey(hSubKey, "") <> ERROR_SUCCESS Then
            Err.Raise vbObjectError + 1, , "删除注册表键时出错"
        Else
            RaiseEvent DeletedNode(hSubKey, subkey)
            Debug.Print "退出前已经删除:"; hSubKey, "subkey:"; subkey
        End If
    End If
    
   If RegCloseKey(hSubKey) <> ERROR_SUCCESS Then
      Err.Raise vbObjectError + 1, , "关闭注册表时出错"
   End If
   Debug.Print "关闭:"; hSubKey, "subkey:"; subkey
   Err.Clear
DeleteKeyErr:
   rlngErrNum = Err.Number
   rstrErrDescr = Err.Description
   If rlngErrNum <> 0 Then
    RaiseEvent DeleteError(hSubKey, subkey, rlngErrNum, rstrErrDescr)
   End If
   Debug.Print rstrErrDescr
   Debug.Print "<===="; subkey
End Function

封装使用

vb enum regis,VB,windows,java,microsoft文章来源地址https://www.toymoban.com/news/detail-781292.html

Option Explicit
Dim WithEvents enumReg As CEnumReg

Dim sum As Long

Dim rlngErrNum As Long, rstrErrDescr As String

Dim exitApp As Boolean


Dim t As Integer
'开始按钮
Private Sub cmdClean_Click()
    'MsgBox (enumReg Is Nothing)
    If enumReg Is Nothing Then
        Set enumReg = New CEnumReg
        'MsgBox (enumReg Is Nothing)
    End If
    sum = 0
    
    'MsgBox CStr(enumReg.RunningNum)
    If enumReg.RunningNum <= 0 Then
        Call enumReg.EnumAll(Combo1.ItemData(Combo1.ListIndex), Trim(Text1.Text))
        Debug.Print "**********"
    Else
       Call enumReg.CancelEnum
    End If
    
End Sub


Private Sub cmdClear_Click()
 List1.Clear
End Sub

Private Sub enumReg_DeletedNode(ByVal hkey As Long, ByVal subkey As String)
    Dim k As String
    k = enumReg.GetRegKeyName(hkey)
    List1.AddItem ("已删除 " + k + "\" + subkey + " hkey:" + CStr(hkey))
End Sub

Private Sub enumReg_DeleteError(ByVal hkey As Long, ByVal subkey As String, ByVal errNum As Long, ByVal errDescr As String)
    List1.AddItem (CStr(hkey) + "\" + subkey + Chr(9) + "错误:" + errDescr + Chr(9) + CStr(errNum))
End Sub

Private Sub enumReg_EnumError(ByRef parentNodes() As String, ByVal parentNodeLevel As Long, ByVal errNum As Long, ByVal errDescr As String)
    Dim s As String, i As Long
    For i = 0 To parentNodeLevel
    
        s = s + parentNodes(i) + "\"
    Next
    List1.AddItem (s + Chr(9) + "错误:" + errDescr + Chr(9) + CStr(errNum))
End Sub

Private Sub enumReg_EnumFinished()
   If exitApp Then
    Unload Me
   Else
    Label2.Caption = "已完成"
   End If
End Sub

Private Sub enumReg_EnumLeaf(ByVal hkey As Long, ByRef parentNodes() As String, ByVal parentLevel As Long, ByVal subkey As String, _
                                ByVal keyName As String, keyValue As Variant, keyValueType As Long)
       Dim rtn As Long, newValue As String
       Dim i As Long, kpath As String
       
       For i = 0 To parentLevel
        kpath = kpath + "\" + parentNodes(i) + "\"
       Next
        Label2.Caption = kpath + Chr(9) + keyName + "=" + CStr(keyValue)
        
        Const s = "2345Pic"
        
        '键名含指定字符
        If InStr(1, CStr(keyName), s) Then
            
            If DeleteValue(hkey, "", keyName) Then
                List1.AddItem ("删除成功" + Chr(9) + kpath + Chr(9) + keyName)
            Else
                
                List1.AddItem ("删除失败:" + Chr(9) + kpath + Chr(9) + keyName)
            End If
        End If
        
       Select Case keyValueType
          Case iREG_NONE '默认
          
          Case iREG_SZ
             'lBuffer = LenB(keyValue)
                
                
                If InStr(1, CStr(keyValue), s) Then
                    newValue = Replace(CStr(keyValue), s, "Pic")
                    
                    Debug.Print "event:", kpath + "\" + subkey + "\", Chr(9), keyName + "=" + CStr(keyValue)
                    'SetValue函数是返 布尔值的
                    If SetValue(hkey, keyName, "", keyValueType, newValue) Then
                       Debug.Print "修改注册表时成功", "原值:", CStr(keyValue), "新值:", newValue
                       List1.AddItem (kpath + "\" + "    原值:" + CStr(keyValue) + "    新值:" + newValue)
                    End If
                    
                    sum = sum + 1

                Else
                    'List1.AddItem (kpath + Chr(9) + keyName + "=" + CStr(keyValue))

                End If
                
                  Const s1 = "看图王 "
                  
                If InStr(1, CStr(keyValue), s1) Then
                
                    newValue = Replace(CStr(keyValue), s1, "")
                    'SetValue函数是返 布尔值的
                    If SetValue(hkey, "", "", keyValueType, newValue) Then
                       Debug.Print "修改注册表时成功", "原值:", CStr(keyValue), "新值:", newValue
                       List1.AddItem (kpath + "\" + subkey + "    原值:" + CStr(keyValue) + "    新值:" + newValue)
                    End If
                    
                    sum = sum + 1
                End If
          Case iREG_EXPAND_SZ
             'lBuffer = LenB(sValue)
    
          Case iREG_DWORD
             'lBuffer = 4
    
          Case iREG_BINARY
             'lBuffer = 4
    
          Case Else
             'Err.Raise vbObjectError + s1, , "不支持该参数类型"
             Debug.Print "不支持该参数类型" + CStr(keyValueType)
       End Select
   

    'Debug.Print "共计:", sum, "条"
    Label1.Caption = "共计:" + CStr(sum) + "条"
    Debug.Print "leaf event:", kpath + "\" + subkey + "\", Chr(9), keyName + "=" + CStr(keyValue)
End Sub

Private Sub enumReg_EnumNode(ByVal hkey As Long, ByRef parentNodes() As String, ByVal parentLevel As Long, ByVal subkey As String)
    Dim fullkeys As String, i As Long
    
    For i = 0 To parentLevel
     fullkeys = fullkeys + "\" + parentNodes(i)
    Next
    Debug.Print "node event:", fullkeys, CStr(subkey)
    Debug.Print "node hkey:", hkey, "subkey:", subkey
           Dim rtn As Long, newValue As String
       Label2.Caption = fullkeys + "\" + subkey
       Select Case iREG_SZ
          Case iREG_NONE '默认
          
          Case iREG_SZ
             'lBuffer = LenB(keyValue)
                Const s = "2345Pic"  '垃圾软件之王2345   
                If InStr(1, subkey, s) Then
                    newValue = Replace(subkey, s, "Pic")
                    
                    Debug.Print "event:", fullkeys + "\", 0, subkey
                    'SetValue函数是返 布尔值的
                    List1.AddItem ("准备删除键:" + fullkeys + "\" + subkey)
                    Call enumReg.DeleteTreeKey(hkey, subkey)
'                    If RegRenameKey(hkey, subkey, newValue) = 0 Then
'                       Debug.Print "修改注册表时成功", "原值:", subkey, "新值:", newValue
'                       List1.AddItem (kpath + "\" + subkey + "    原值:" + subkey + "    新值:" + newValue)
'                    End If
                    
                    sum = sum + 1

                End If
                
                  Const s1 = "看图王 "
                  
                If InStr(1, subkey, s1) Then
                
                    newValue = Replace(subkey, s1, "")
                    'SetValue函数是返 布尔值的
                    'Call enumReg.DeleteTreeKey(hkey, subkey)
                       'Debug.Print "修改注册表时成功", "原值:", subkey, "新值:", newValue
                       'List1.AddItem (kpath + "\" + subkey + "    原值:" + subkey + "    新值:" + newValue)

                    
                    sum = sum + 1
                End If
          Case iREG_EXPAND_SZ
             'lBuffer = LenB(sValue)
    
          Case iREG_DWORD
             'lBuffer = 4
    
          Case iREG_BINARY
             'lBuffer = 4
    
          Case Else
             'Err.Raise vbObjectError + s1, , "不支持该参数类型"
             Debug.Print "不支持该参数类型" + 0
       End Select
   

    Debug.Print "共计:", sum, "条"
    Label1.Caption = "共计:" + CStr(sum) + "条"
    
    
End Sub

Private Sub Form_Load()

   Combo1.AddItem "HKEY_CLASSES_ROOT"
   Combo1.ItemData(Combo1.NewIndex) = &H80000000
   Combo1.AddItem "HKEY_CURRENT_USER"
   Combo1.ItemData(Combo1.NewIndex) = &H80000001
   Combo1.AddItem "HKEY_LOCAL_MACHINE"
   Combo1.ItemData(Combo1.NewIndex) = &H80000002
   Combo1.AddItem "HKEY_USERS"
   Combo1.ItemData(Combo1.NewIndex) = &H80000003
   Combo1.AddItem "HKEY_CURRENT_CONFIG"
   Combo1.ItemData(Combo1.NewIndex) = &H80000005
   
   Combo1.ListIndex = 0
    
  'Call test(iHKEY_CLASSES_ROOT, ".3g2")
End Sub


'删除按钮
Private Sub Command1_Click()
Debug.Print "---------------------------------------------------------------------------------------------------------"
    If enumReg Is Nothing Then
        Set enumReg = New CEnumReg
    End If
    If Len(Trim(Text1.Text)) <= 0 Then Exit Sub
    Call enumReg.DeleteTreeKey(Combo1.ItemData(Combo1.ListIndex), Trim(Text1.Text))

    
    
End Sub



Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
 
 If Not enumReg Is Nothing Then
    Call enumReg.CancelEnum
    exitApp = True
 End If
End Sub

Private Sub Form_Resize()
    List1.Width = Me.Width - 4 * List1.Left
    Label2.Width = List1.Width
    
    List1.Height = Me.Height - List1.Top - cmdClear.Height - 500
    
    cmdClear.Top = List1.Top + List1.Height
    cmdClear.Left = Me.Width - cmdClear.Width - 3 * List1.Left
End Sub

到了这里,关于VB6 注册表的递归访问与面象对象模块化封装的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Reg注册表读写

    在Windows 95及其后继版本中,采用了一种叫做“注册表”的数据库来统一进行管理,将各种信息资源集中起来并存储各种配置信息。按照这一原则,Windows各版本中都采用了将应用程序和计算机系统全部配置信息容纳在一起的注册表,用来管理应用程序和文件的关联、硬件设备

    2024年02月09日
    浏览(38)
  • 玩转注册表

           很多人都认识注册表,但是几乎没人搞懂过注册表。我来带大家玩转注册表,做这篇文章就想记录一下注册表里的一些路径(难找,记不住!),本文中我会介绍一些实用的利用注册表进行内网权限维持的一个思路和方法。没学网安的,会更了解注册表;大佬就复习

    2024年02月05日
    浏览(43)
  • Unity 注册表操作

    内容将会持续更新,有错误的地方欢迎指正,谢谢!   Unity 注册表操作       TechX 坚持将创新的科技带给世界! 拥有更好的学习体验 —— 不断努力,不断进步,不断探索 TechX —— 心探索、心进取! 助力快速掌握 Registry 注册表操作 为初学者节省宝贵的学习时间,避免困惑

    2024年02月02日
    浏览(38)
  • Windows注册表清理

    伴随着系统运行时间不断增长,我们的电脑 注册表 中累积了许多垃圾文件。这些垃圾文件都是我们平常安装与卸载程序所留下的无用注册表信息,时间一长,垃圾文件与信息越来越多,我们电脑的运行速度越来越慢。 ​ 而且部分软件由于删除方式不对,导致一些残留注册表

    2024年02月08日
    浏览(50)
  • 深入注册表监控

    注册表是windows的重要数据库,存放了很多重要的信息以及一些应用的设置,对注册表进行监控并防止篡改是十分有必要的。在64位系统下微软提供了 CmRegisterCallback 这个回调函数来实时监控注册表的操作,那么既然这里微软提供了这么一个方便的接口,病毒木马自然也会利用

    2024年02月08日
    浏览(39)
  • 注册表操作01

    注册表的组织方式主要分为 根键 、 子键 和 键值项 三部分。 (1)根键,可以把它们理解成磁盘的五个分区。 1.HKEY_CLASSES_ROOT; 2.HKEY_CURRENT_USER; 3.HKEY_LOCAL_MACHINE; 4.HKEY_USERS; 5.HKEY_CURRENT_CONFIG; (2)子键,可以有多个子键和键值项。 (3)键值项由三部分组成,分别为:名称

    2024年02月03日
    浏览(38)
  • 【Windows基础】注册表

    注册表是Windows操作系统、硬件设备以及客户应用程序得以正常运行和保存设置的 核心\\\"数据库\\\" ,也可以说是一个非常巨大的 树状分层结构 的 数据库系统 注册表记录了用户安装在计算机上的软件和每个程序的相互关联信息,它包括了计算机的硬件配置,包括自动配置的即插

    2024年02月04日
    浏览(56)
  • MFC 注册表

    2024年02月08日
    浏览(43)
  • DOS下操作注册表

    下面以彻底关闭window10 操作为背景,通过命令行对注册表进行操作. 执行命令需要管理员权限 如果目录中存在空格 需要双引号 hklm为 HKEY_LOCAL_MACHINE 的缩写 查询: QUERY 添加: ADD 删除: DELETE 复制: COPY 保存: SAVE /t 表示 类型 如下 /v 表示 键名 效果如下图 /d 表示 键值 效果如

    2024年02月10日
    浏览(42)
  • windows注册表启动项

    实际应急响应案例时,发现很多非常规的启动项以及ARK工具未涵盖的启动项,故收集资料对注册表有关的启动项进行总结,以后处置病毒无从下手时可以考虑从启动项排查。 1.Load注册键 介绍该注册键的资料不多,实际上它也能够自动启动程序。位置: HKEY_CURRENT_USERSoftwareMi

    2024年02月05日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包