首页 > 未分类 > 用VB操作注册表 (二)

用VB操作注册表 (二)

2007年7月14日 岩岩魂   访问量: 430 发表评论 阅读评论
a-->数据类型为REG_SZ
这种方式最简单,只需要在上面的语句结束之后使用以下语句就可以得到正确的字符串。eg:
ret = RegQueryValueEx(hKey, Name, 0, typeData, ByVal vbNullString, lenData)
S=String(lenData,Chr(0))
RegQueryValueEx hKey, Name, 0, typeData, ByVal S, lenData '注意ByVal千万别忘了
S=Left(S,InStr(S,Chr(0))-1)

b-->数据类型为REG_EXPAND_SZ
所谓REG_EXPAND_SZ类型的字符串是指字符串中可能含有%WinDir%之类的字符串[%WinDir%表示Windows所在目录我们可以在Ms-Dos方式下使用set命令来看看这类字符串,我们也许还会看到诸如TMP,PATH,WINBOOTDIR这些和WinDir类似的具有特殊意义的字符串。],遇到这类字符串,我们还必须调用另一个API函数ExpandEnvironmentStrings来将它展开[比如%WinDir%就展开为C:\WINDOWS]。以下是ExpandEnvironmentStrings的描述和用法:
Declare Function ExpandEnvironmentStrings Lib "kernel32" Alias "ExpandEnvironmentStringsA" (ByVal lpSrc As String, ByVal lpDst As String, ByVal nSize As Long) As Long
参数 类型及说明
lpSrc String,欲扩充的字串
lpDst String,扩充过后的字串
nSize Long,lpDst的长度。
注意预先对lpDst进行初始化,使其与这个长度相符
函数调用例:
Dim S2 As String
'先利用RegQueryValueEx函数获得某个value的数据类型和数据的长度
ret = RegQueryValueEx(hKey, Name, 0, typeData, ByVal vbNullString, lenData)
S = String(lenData, Chr(0))
RegQueryValueEx hKey, Name, 0, typeData, ByVal S, lenData
S = Left(S, InStr(S, Chr(0)) - 1) 'S为读取出来的字符串
S2 = String(Len(S) + 256, Chr(0))'S2为扩展之后的字符串
ExpandEnvironmentStrings S, S2, Len(S2)
S2= Left(S2, InStr(S2, Chr(0)) - 1)

c-->数据类型为REG_MULTI_SZ
REG_MULTI_SZ为多重字符串,其结构如下:

字符串1 chr(0) 字符串2 chr(0) ... 字符串N chr(0) chr(0)

下面的自定义子程序的功能是取得多重字符串中每一个字符串。
Sub MultiStringToStringArray(S As String, S2() As String)
'S为我们读取出来的多重字符串
'S2为转换后的字符串数组
Dim count As Integer, pos As Integer, pos2 As Integer, idx As Integer
pos = InStr(S, Chr(0))

While pos > 0 count = count + 1
pos = InStr(pos + 1, S, Chr(0))
Wend
'取得多重字符串中的字符串个数
count = count - 1

ReDim S2(0 To count - 1)
pos = 1
For idx = 0 To count - 1
pos2 = InStr(pos, S, Chr(0))
S2(idx) = Mid(S, pos, pos2 - pos)
pos = pos2 + 1
Next
End Sub
在调用MultiStringToStringArray之前,要先定义一个不含任何元素的字符串数组。子程序调用例子如下:
S= "WGL"+chr(0)+"LOVE"+chr(0)+"MEISHAN"+chr(0)+chr(0)
Dim S2() As String
MultiStringToStringArray S,S2
那么执行之后,S2(0)="WGL",S2(1)="LOVE",S2(2)="MEISHAN"

d-->数据类型为REG_DWORD,REG_DWORD_BIG_ENDIAN
'先利用RegQueryValueEx函数获得某个value的数据类型和数据的长度
Dim L As Long
ret = RegQueryValueEx(hKey, Name, 0, typeData, ByVal vbNullString, lenData)
RegQueryValueEx hKey, Name, 0, typeData, L, lenData

e-->数据类型为REG_BINARY
'先利用RegQueryValueEx函数获得某个value的数据类型和数据的长度
ret = RegQueryValueEx(hKey, Name, 0, typeData, ByVal vbNullString, lenData)
ReDim bArr(0 To lenData - 1) As Byte
RegQueryValueEx hKey, Name, 0, typeData, bArr(0), lenData

一个完整的例子请下载后自行研究。

登录数据库Registry的Value的存取--读取某个Key下的所有名称的值(Value)

有时候我们需要读取某个Key下的所有名称的值,找到特定的或者全部名称的值以作它用,比如我在编写清除著名的"木马冰河" 服务器端程序时,就需要查找HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run下的所有可疑的加载程序项目然后删除之。

要用到的API函数RegEnumValue,其详细描述:
VB声明
Declare Function RegEnumValue Lib "advapi32.dll" Alias "RegEnumValueA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpValueName As String, lpcbValueName As Long, lpReserved As Long, lpType As Long, lpData As Byte, lpcbData As Long) As Long
'以下的两个函数是经过王国荣老师改编过的函数,与此相关,也一并列出.并且在我们的例子程序中要用到它们。RegEnumValueAsAny可以传入长整数和字符串;RegEnumValueAsAny2中lpData参数被改成Any后,可以使用Byte数组,由于Byte数组是采用”传地址方式来传递参数的,可以省下复制字符串数据的时间,使得程序变得更加高效。
Declare Function RegEnumValueAsAny Lib "advapi32.dll" Alias "RegEnumValueA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpValueName As String, lpcbValueName As Long, lpReserved As Long, lpType As Long, lpData As Any, lpcbData As Long) As Long

Declare Function RegEnumValueAsAny2 Lib "advapi32.dll" Alias "RegEnumValueA" (ByVal hKey As Long, ByVal dwIndex As Long, lpValueName As Any, lpcbValueName As Long, lpReserved As Long, lpType As Long, lpData As Any, lpcbData As Long) As Long
参数说明:
hKey:Key Handle
dwIndex:欲读取之名称的顺序
lpValueName:返回所读取的名称
lpcbValueName:传入lpValueName参数的长度,返回所读取的名称的长度,注意这一长度不含chr(0)
lpReserved:保留参数,实际使用时传入ByVal 0即可
lpType:返回所读取的数据类型
lpData:返回所读取的数据
lpcbData:传入lpData,返回所读取的数据长度
返回值: =0,表示成功;≠0,表示失败。

调用例子:
ret=0
myindex=0
while ret=0
ret=RegEnumValue(hkey,myindex,Name,ByVal 0, typeData, ByVal vbNullString, lenData)
myindex=myindex+1
wend
一个完整的例子如下:
'*************EnumVal2.bas***************

Option Explicit
Public Const
HKEY_CLASSES_ROOT = &H80000000
Public Const HKEY_CURRENT_USER = &H80000001
Public Const HKEY_LOCAL_MACHINE = &H80000002
Public Const HKEY_USERS = &H80000003
Public Const HKEY_PERFORMANCE_DATA = &H80000004
Public Const HKEY_CURRENT_CONFIG = &H80000005
Public Const HKEY_DYN_DATA = &H80000006

Public Const REG_NONE = 0
Public Const REG_SZ = 1
Public Const REG_EXPAND_SZ = 2
Public Const REG_BINARY = 3
Public Const REG_DWORD = 4
Public Const REG_DWORD_BIG_ENDIAN = 5
Public Const REG_MULTI_SZ = 7
'注意以下的函数声明须在一行内写完
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 RegQueryValue Lib "advapi32.dll" Alias "RegQueryValueA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal lpValue As String, lpcbValue As Long) As Long

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

Declare Function RegEnumValue Lib "advapi32.dll" Alias "RegEnumValueA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpValueName As String, lpcbValueName As Long, lpReserved As Long, lpType As Long, lpData As Byte, lpcbData As Long) As Long

Declare Function RegEnumValueAsAny Lib "advapi32.dll" Alias "RegEnumValueA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpValueName As String, lpcbValueName As Long, lpReserved As Long, lpType As Long, lpData As Any, lpcbData As Long) As Long

Declare Function RegEnumValueAsAny2 Lib "advapi32.dll" Alias "RegEnumValueA" (ByVal hKey As Long, ByVal dwIndex As Long, lpValueName As Any, lpcbValueName As Long, lpReserved As Long, lpType As Long, lpData As Any, lpcbData As Long) As Long

Declare Function ExpandEnvironmentStrings Lib "kernel32" Alias "ExpandEnvironmentStringsA" (ByVal lpSrc As String, ByVal lpDst As String, ByVal nSize As Long) As Long

Sub MultiStringToStringArray(S As String, S2() As String)
'S为我们读取出来的多重字符串
'S2为转换后的字符串数组
Dim count As Integer, pos As Integer, pos2 As Integer, idx As Integer
pos = InStr(S, Chr(0))

While pos > 0 count = count + 1
pos = InStr(pos + 1, S, Chr(0))
Wend
'取得多重字符串中的字符串个数
count = count - 1

ReDim S2(0 To count - 1)
pos = 1
For idx = 0 To count - 1
pos2 = InStr(pos, S, Chr(0))
S2(idx) = Mid(S, pos, pos2 - pos)
pos = pos2 + 1
Next
End Sub

'在form中添加command按钮和text文本框

'************EnumVal2.frm****************

'以下的Command1_Click事件中我们将列举出'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run下的所有name及其Value.
Private Sub Command1_Click()
Dim hKey As Long, ret As Long, lenData As Long, typeData As Long Dim Name As String
Dim lenName As Long
Dim idx As Integer, j As Integer Dim bName(256) As Byte
ret = RegOpenKey(HKEY_LOCAL_MACHINE, "Software\Microsoft\Windows\CurrentVersion\Run", hKey)
If ret <> 0 Then Exit Sub

ret = 0
idx = 0
While ret = 0
lenName = 256

ret=RegEnumValueAsAny2(hKey,idx,bName(0),lenName,ByVal 0,typeData,ByVal vbNullString, lenData)
If ret <> 0 Then
RegCloseKey hKey
Exit Sub
End If
'上面的RegEnumValueAsAny2调用得到了第一个Name的长度lenName,不含chr(0)
Name = String(lenName + 1, Chr(0))
lenName = Len(Name)
Select Case typeData
Case REG_SZ, REG_EXPAND_SZ, REG_MULTI_SZ
Dim S As String
S = String(lenData, Chr(0))
RegEnumValueAsAny hKey, idx, Name, lenName, ByVal 0, typeData, ByVal S, lenData
If typeData = REG_SZ Then
S = Left(S, InStr(S, Chr(0)) - 1)
Text1.SelText=IIf(lenName=0, "(预设值)",Left(Name,InStr(Name,Chr(0))-1)) & "=" & S & vbCrLf
ElseIf typeData = REG_EXPAND_SZ Then
Dim S2 As String
S2 = String(Len(S) + 256, Chr(0))
ExpandEnvironmentStrings S, S2, Len(S2)
S = Left(S2, InStr(S2, Chr(0)) - 1)
Text1.SelText = Left(Name, InStr(Name, Chr(0)) - 1) & " = " & S & vbCrLf
ElseIf typeData = REG_MULTI_SZ Then
Dim SArr() As String
MultiStringToStringArray S, SArr
For j = 0 To UBound(SArr)
Text1.SelText = Left(Name, InStr(Name, Chr(0)) - 1) & "(" & j & ") = " & SArr(j) & vbCrLf
Next
End If
Case REG_DWORD, REG_DWORD_BIG_ENDIAN
Dim L As Long
RegEnumValueAsAny hKey, idx, Name, lenName, ByVal 0, typeData, L, lenData
Text1.SelText = Left(Name, InStr(Name, Chr(0)) - 1) & " = " & L & vbCrLf
Case REG_BINARY
ReDim bArr(0 To lenData - 1) As Byte
RegEnumValueAsAny hKey, idx, Name, lenName, ByVal 0, typeData, bArr(0), lenData
Text1.SelText = Left(Name, InStr(Name, Chr(0)) - 1) & " = "
For j = 0 To UBound(bArr)
Text1.SelText = Hex(bArr(j)) & " "
Next
Text1.SelText = vbCrLf
End Select
idx = idx + 1
Wend
RegCloseKey hKey
End Sub

登录数据库Registry的Value的存取--写入某个Key指定名称的值

要完成Value的写入,需要用到API函数RegSetValueEx。下面是它的一些说明。
VB声明
Declare Function RegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, lpData As Any, ByVal cbData As Long) As Long
参数:
hKey:Key Handle
lpValueName:Value名称
Reserved:保留参数,具体使用时置为0即可
dwType:数据类型
lpData:所设置的数据,注意这一参数被定义成lpData As Any,所以要传入字符串数据时别忘了在参数前加保留字ByVal
cbData:数据的长度。注意:如果写入的数据属于REG_SZ、REG_EXPAND_SZ、REG_MULTI_SZ类型时,则这个长度应该包含chr(0)字符。
返回值: =0,表示成功;≠0,表示失败。

由于RegSetValueEx的参数和RegQueryValueEx完全一样,他们的使用方式也差不多,因此,在这里我只是举出下面的例子来简略地说一下就行。
'下面的例子在HKEY_CURRENT_USER\Software\SetValue下建立
'Default Value-->REG_SZ "VB操作注册表"
'str1 -->REG_SZ "我爱我的祖国"
'str2 -->REG_EXPAND_SZ "%WinDir%Command"
'str3 -->REG_MULTI_SZ "hongqt" + Chr(0) + "lstc" + Chr(0) + "edu" + Chr(0) + "cn" + Chr(0) + Chr(0)
'LongData -->REG_DWORD 99999
'BinaryData -->REG_BINARY 11,22,33,44,aa,bb,cc,dd

'*******************setvalue.bas ************************

Option Explicit
Public Const HKEY_CLASSES_ROOT = &H80000000
Public Const HKEY_CURRENT_USER = &H80000001
Public Const HKEY_LOCAL_MACHINE = &H80000002
Public Const HKEY_USERS = &H80000003
Public Const HKEY_PERFORMANCE_DATA = &H80000004
Public Const HKEY_CURRENT_CONFIG = &H80000005
Public Const HKEY_DYN_DATA = &H80000006

Public Const REG_NONE = 0
Public Const REG_SZ = 1
Public Const REG_EXPAND_SZ = 2
Public Const REG_BINARY = 3
Public Const REG_DWORD = 4
Public Const REG_DWORD_BIG_ENDIAN = 5
Public Const REG_MULTI_SZ = 7
'注意下面的函数声明要在一行内写完
Declare Function RegCreateKey Lib "advapi32.dll" Alias "RegCreateKeyA" (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 RegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, lpData As Any, ByVal cbData As Long) As Long

Sub Main()
Dim hKey As Long
RegCreateKey HKEY_CURRENT_USER, "Software\SetValue", hKey
RegSetValueEx hKey, "", 0, REG_SZ, ByVal "VB操作注册表", 13
RegSetValueEx hKey, "Str1", 0, REG_SZ, ByVal "我爱我的祖国", 13
RegSetValueEx hKey, "Str2", 0, REG_EXPAND_SZ, ByVal "%WinDir%Command", 16
Dim S As String
S = "hongqt" + Chr(0) + "lstc" + Chr(0) + "edu" + Chr(0) + "cn" + Chr(0) + Chr(0)
RegSetValueEx hKey, "Str3", 0, REG_MULTI_SZ, ByVal S, 20

Dim L As Long
L = 99999
RegSetValueEx hKey, "LongData", 0, REG_DWORD, L, 4

Dim bArr(0 To 7) As Byte
bArr(0) = &H11: bArr(1) = &H22: bArr(2) = &H33: bArr(3) = &H44
bArr(4) = &HAA: bArr(5) = &HBB: bArr(6) = &HCC: bArr(7) = &HDD
RegSetValueEx hKey, "BinaryData", 0, REG_BINARY, bArr(0), 8

MsgBox "已完成 RegSetValueEx! 请检查 HKEY_CURRENT_USER\Software\SetValue 的内容。"
RegCloseKey hKey

End Sub

登录数据库Registry的Value的存取--删除某Key的Value

这个功能很容易实现。主要是要调用相应的API函数--RegDeleteValue,以下是它的一些描述:
VB声明
Declare Function RegDeleteValue Lib "advapi32.dll" Alias "RegDeleteValueA" (ByVal hKey As Long, ByVal lpValueName As String) As Long
参数:
hKey:Key Handle
lpValueName: Value名称,如果想删除默认值的话,传入""[空字符串]即可。

返回值: =0,表示成功;≠0,表示失败。

函数调用例:
'我们假设在HKEY_CURRENT_USER\Software\SetValue有:
'预设值--VB操作注册表
'str1--我爱我的祖国
'我们要删除这两个Value
ret = RegOpenKey(HKEY_CURRENT_USER, "Software\SetValue", hKey)
If ret = 0 Then
RegDeleteValue hKey, "Str1"
MsgBox "已删除 HKCU\Software\SetValue SubKey Str1 Value"
RegDeleteValue hKey, ""
MsgBox "已删除HKCU\Software\SetValue SubKey‘预设值’"
End If

登录数据库Registry的Key的存取

相对于注册表中Value的存取,Key的存取要简单得多。要用到的API函数,除了前面提到的RegOpenKey、RegCreateKey之外,主要就还有RegEnumKey、RegDeleteKey。

Key的建立,可以采用前面提到的RegCreateKey完成,此处不再举例。

********************************************************************************

Key的读取:
单个Key的读取利用RegOpenKey显然已经足够。
我们这里要讲的是列出某个Key下的所有SubKey。比如:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows这个Key下面一般就只有两个SubKey-->CurrentVersion 和Help。要实现这个功能,需要用到RegEnumKey函数。下面是它的描述:
VB声明
Declare Function RegEnumKey Lib "advapi32.dll" Alias "RegEnumKeyA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpName As String, ByVal cbName As Long) As Long
参数说明:
hKey:Key Handle
dwIndex:欲读取的SubKey的顺序
lpName:返回所读取的SubKey的名称
cbName:传入lpName的字符串长度。
返回值: =0,表示成功;≠0,表示失败。
调用例:
Dim hKey As Long, ret As Long, Name As String, Idx As Long
List1.Clear
Idx = 0
Name = String(256, Chr(0))
Do
ret = RegEnumKey(HKEY_CURRENT_USER, Idx, Name, Len(Name))
If ret = 0 Then
List1.AddItem Left(Name, InStr(Name, Chr(0)) - 1)
Idx = Idx + 1
End If
Loop Until ret <> 0

********************************************************************************

Key的删除:会用到RegDeleteKey函数,其描述如下:
VB声明
Declare Function RegDeleteKey Lib "advapi32.dll" Alias "RegDeleteKeyA" (ByVal hKey As Long, ByVal lpSubKey As String) As Long
参数:
hKey:Key Handle
lpSubKey:SubKey名称或者路径,若传入""[空字符串],表示删除Key本身。
返回值: =0,表示成功;≠0,表示失败。

eg:
Dim hKey,ret As Long
ret = RegCreateKey(HKEY_LOCAL_MACHINE, "SOFTWARE\Hongqt\xiaoyuer", hKey)
ret = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\Hongqt", hKey)
ret = RegDeleteKey(hKey, "xiaoyuer")'删除HKEY_LOCAL_MACHINE\SOFTWARE\Hongqt\xiaoyuer
注意:
如果我们利用RegDeleteKey函数删除一个含有SubKey的Key时,对于Windows98和Winnt来讲是不一样的。比如我们把上面的删除调用改成ret = RegDeleteKey(hKey, ""),则在windows98下,它会连hongqt下的xiaoyuer一起删除,而在winnt下则会报错。

下面的一个子函数可以在WinNt下递归删除某个Key和它下面的所有SubKey.

Function DeleteSubkeyTree(ByVal hKey As Long, ByVal Subkey As String) As Boolean
Dim ret As Long, Index As Long, Name As String
Dim hSubKey As Long
ret = RegOpenKey(hKey, Subkey, hSubKey)
If ret <> 0 Then
DeleteSubkeyTree = False
Exit Function
End If
ret = RegDeleteKey(hSubKey, "")
If ret <> 0 Then
Name=String(256,chr(0))
If ret <> 0 Then
'RegDeleteKey无法删除,用于Winnt下。
Name = String(256, Chr(0))
While RegEnumKey(hSubkey, 0, Name, Len(Name)) = 0 And DeleteSubkeyTree(hSubkey, Name)
'递归删除Subkey的Subkey
Wend
ret = RegDeleteKey(hSubkey, "")
End If
DeleteSubkeyTree = (ret = 0)
RegCloseKey hSubkey
End Function

相关文章:

  1. 用VB操作注册表 (一)
  2. 自制控件方面的有关知识
  3. 在Vb下实现多线程
  4. 用内存映射判断应用程序是否运行多次
  5. VB 类按键精灵源码
分类: 未分类 标签:
  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.