我建议删除所有出现的On Error Resume Next
WMI 方法并坚持使用。此外,您当前的代码不使用递归,因此您只能在cRegKeyStartingPath
. 您需要递归来遍历任意深度的树。
用于EnumValues
枚举给定键的值:
rc = reg.EnumValues(HKLM, key, names, types)
该方法在成功时返回 0,因此您可以通过评估返回码来检查错误。调用完成后,变量names
包含一个数组,其中包含值的名称key
,或者Null
如果键不包含任何值(即缺少默认值)。因此,用于检查给定键中是否存在特定值的代码可能如下所示:
reg.EnumValues HKLM, key, names, types
If Not IsNull(names) Then
For Each name In names
If name = "foo" Then
reg.GetStringValue HKLM, key, name, data
If data = "bar" Then
'delete key here
Exit For
End If
End If
Next
End If
您可以通过枚举给定键的子键EnumKey
并递归到这些子键中来遍历注册表:
Sub TraverseRegistry(root, key)
reg.EnumKey root, key, subkeys
If Not IsNull(subkeys) Then
For Each sk In subkeys
TraverseRegistry root, key & "\" & sk
Next
End If
End Sub
要删除密钥,请使用该DeleteKey
方法。必须删除哪个键的信息是您已经拥有的信息:它是key
值枚举例程中的变量值,当found
它为真时。但是,您不能删除具有子键的键,因此您必须先删除这些子键。您可以从上面重复使用遍历例程的东西:
Sub DelKey(root, key)
reg.EnumKey root, key, subkeys
If Not IsNull(subkeys) Then
For Each sk In subkeys
DelKey root, key & "\" & sk 'delete subkeys first
Next
End If
'at this point all subkeys have already been deleted, so we can
'now delete the parent key
reg.DeleteKey root, key
End Sub
把所有东西放在一起,你会得到这样的东西:
Const HKLM = &h80000002
Const StartKey = "SOFTWARE\Wow...ion\Uninstall"
Const SearchValue = "DisplayName"
Const MatchData = "Ossec HIDS"
Set reg = GetObject("winmgmts://./root/default:StdRegProv")
FindAndDeleteKey HKLM, StartKey, SearchValue, MatchData
Sub FindAndDeleteKey(root, key, value, data)
reg.EnumValues HKLM, key, names, types
If Not IsNull(names) Then
For Each name In names
If name = value Then
reg.GetStringValue HKLM, key, name, regdata
If regdata = data Then
DelKey root, key
Exit Sub
End If
End If
Next
End If
'value not found in current key => continue search in subkeys
reg.EnumKey root, key, subkeys
If Not IsNull(subkeys) Then
For Each sk In subkeys
FindAndDeleteKey root, key & "\" & sk, value, data
Next
End If
End Sub
Sub DelKey(root, key)
reg.EnumKey root, key, subkeys
If Not IsNull(subkeys) Then
For Each sk In subkeys
DelKey root, key & "\" & sk 'delete subkeys first
Next
End If
'at this point all subkeys have already been deleted, so we can
'now delete the parent key
reg.DeleteKey root, key
End Sub
由于您正在寻找具有特定数据的特定值,您甚至可以简化FindAndDeleteKey()
为:
Sub FindAndDeleteKey(key)
'Try to read the value directly. If the value doesn't exist this will
'simply return a non-zero return code and set data to Null.
reg.GetStringValue HKLM, key, SearchValue, data
If Not IsNull(data) Then
'value does exist
If data = MatchData Then
DelKey HKLM, key
Exit Sub
End If
End If
'value not found in current key => continue search in subkeys
reg.EnumKey HKLM, key, subkeys
If Not IsNull(subkeys) Then
For Each sk In subkeys
FindAndDeleteKey key & "\" & sk
Next
End If
End Sub
编辑:下面是生成一些调试输出的版本。通过在命令提示符下运行它cscript debug_sample.vbs
。请注意,由于您要删除 HKLM 中的内容,因此必须在启用 UAC 时“以管理员身份”运行脚本。
Const HKLM = &h80000002
Const StartKey = "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
Const SearchValue = "DisplayName"
Const MatchData = "Ossec HIDS"
Set reg = GetObject("winmgmts://./root/default:StdRegProv")
FindAndDeleteKey StartKey
Sub FindAndDeleteKey(key)
WScript.Echo "[HKLM\" & key & "]"
rc = reg.GetStringValue(HKLM, key, SearchValue, data)
If Not IsNull(data) Then
WScript.Echo """" & SearchValue & """=""" & data & """"
If data = MatchData Then
DelKey HKLM, key
Exit Sub
End If
Else
WScript.Echo "'" & SearchValue & "' not found in [HKLM\" & key & "], rc=" & rc
End If
reg.EnumKey HKLM, key, subkeys
If Not IsNull(subkeys) Then
For Each sk In subkeys
FindAndDeleteKey key & "\" & sk
Next
End If
End Sub
Sub DelKey(root, key)
reg.EnumKey root, key, subkeys
If Not IsNull(subkeys) Then
For Each sk In subkeys
DelKey root, key & "\" & sk
Next
End If
rc = reg.DeleteKey(root, key)
WScript.Echo "Deleting [HKLM\" & key & "], rc=" & rc
End Sub
我能够使用无效hDefKey
值重现返回代码 6(句柄无效),例如&h8000002
(只有 7 位数字)或h80000002
(缺少 & 号)。