在各种程序设计语言当中,Visual Basic 是最容易上手的了。我本人就是从QBASIC 语言直接转移过来的。我曾经做过一个实验:将原先在QBASIC 语言中编写的代码,原封不动的移植到VB上来,居然有多数能够运行。其他的代码也基本上只作微量调整(如把QBASIC中的“INPUT”语句统一换成VB中的“InputBox”),就可以在VB中直接使用了。另外,考虑到各种语言之间的相通性,这里以VB编程为主,对VC,Delphi,VFP只在后面给出几个实例,敬请高手指教。
● 使用 Visual Basic 来操作注册表
在VB中处理注册表,通常有两种途径:一是利用VB自身的函数;二是调用 Windows API 函数来操作注册表。
一、 MicroSoft Visual Basic 中对于注册表的操作函数
说明:在 Visual Basic 6.0 内部,为了存储创建于 VB 的应用程序的程序信息,已经提供了一个标准的注册位置(如图1):HKEY_CURRENT_USER\Software\VB and VBA Program settings\(为了叙述简单,以下将这一位置简称“标准位置”)。
![]() |
MicroSoft Visual Basic 中对于注册表的操作函数共有4个,它们是 SaveSetting, GetSetting, GetAllSettings, DeleteSettings等。
1、SaveSetting 在 Windows 注册表中保存或建立应用程序项目
语法 SaveSetting appname, section, key, setting
参数 appname:字符串表达式,包含应用程序或工程的名称,是标准位置下的一个子键。
section:字符串表达式,包含区域名称,是 appname 下的一个子键。
key:字符串表达式,标准位置\appname\section子键的键名(Value Name)。
setting:字符串表达式,包含 key 的设置值。 www.xker.com(小新技术网)
函数示例 下列示例先使用 SaveSetting 语句,来建立Windows标准位置(或 16位 Windows 平台的 ini 文件)里 “我的工程”应用程序的项目,然后使用 DeleteSetting 语句将之删除。因为没有指定 key参数,整个子键都会被删除掉,包括子键名称及其所有的键值(key)。
’ 在标准位置中添加一些设置值。
SaveSetting appname := “我的工程”, section := “我的子键”, key := “Top”, setting := 75
SaveSetting “我的工程”,”我的子键”, “Left”, 50
’ 删除子键及所有的设置值。
DeleteSetting “我的工程”, “我的子键” ①在注册表中添加一些设置值。用 SaveSetting 语句在标准位置下建立名为“我的工程\我的子键”的子键。
SaveSetting appname := “我的工程”, section := “我的子键”, key := “Top”, setting := 75
SaveSetting “我的工程”, “我的子键”, “Left”, 50
②删除子键及所有的设置值。
DeleteSetting “我的工程”, “我的子键”
2、GetSetting 从 Windows 注册表中的应用程序项目返回注册表项设置值
语法 GetSetting appname, section, key[, default]
参数 appname:字符串表达式,包含应用程序或工程的名称。
section:字符串表达式,包含区域名称,要求该区域有注册表项设置。
key:字符串表达式,返回注册表项设置的名称。
default:可选。表达式,如果注册表项设置中没有设置值,则返回缺省值。如果省略,则 default 取值为长度为零的字符串 (“”)。
说明 如果 GetSetting 无参数,则 GetSetting 返回 default 的值
函数示例 使用 SaveSetting 语句建立 appname 应用程序的项目,然后使用 GetSetting 函数得到其中一项设置并显示出来。因为有传入参数 default,GetSetting 函数一定会有返回值。请注意,section 名称不能用 GetSetting 函数取得。最后,使用 DeleteSetting 语句将该应用程序项删除。
①定义保存 GetSetting 函数返回之二维数组数据的变量
Dim MySettings As Variant
②在注册表中添加项目
SaveSetting “我的工程”,”我的子键”, “Top”, 75
SaveSetting “我的工程”,”我的子键”, “Left”, 50
Debug.Print GetSetting(appname := “我的工程”, section := “我的子键”, key := “Left”, default := “25”)
③删除注册表中项目
DeleteSetting “我的工程”, “我的子键”
3、GetAllSettings 从 Windows 注册表中返回应用程序项目的所有注册表项设置及其相应值
语法 GetAllSettings(appname, section)
参数 appname 必要。字符串表达式,应用程序或工程的名称。
#p#副标题#e#
section 必要。字符串表达式,包含区域名称,并要求该区域有注册表项设置。GetAllSettings 返回 Variant,其内容为字符串的二维数组,该二维数组包含指定区域中的所有注册表项设置及其对应值。
说明 如果 appname 或 section 不存在,则 GetAllSettings 返回未初始化的 Varian
函数示例 本示例首先使用 SaveSetting 语句来建立 Windows标准位置里 appname 应用程序的项目,然后再使用 GetAllSettings 函数来取得设置值并显示出来。请注意,应用程序名和 section 名称不能用 GetAllSettings 函数取得。最后,使用 DeleteSetting 语句将该应用程序项删除。
’ 用来保存 GetAllSettings 函数所返回之二维数组数据的变量
’ 整型数是用来计数用。
Dim MySettings As Variant, intSettings As Integer
’ 在注册表中添加设置值。
SaveSetting appname := “我的工程”, section := “我的子键”, key := “Top”, setting := 75
SaveSetting “我的工程”,”我的子键”, “Left”, 50
’ 取得输入项的设置值。
MySettings = GetAllSettings(appname := “我的工程”, section := “我的子键”) For intSettings = LBound(MySettings, 1) To UBound(MySettings, 1) Debug.Print MySettings(intSettings, 0), MySettings(intSettings, 1) Next intSettings DeleteSetting “我的工程”, “我的子键” |
4、DeleteSetting 从应用程序项目里删除区域或注册表项设置
语法 DeleteSetting appname, section[, key]
参数 appname 必需的。字符串表达式,应用程序或工程的名称。
section 必要。字符串表达式,包含要删除注册表项设置的区域名称。如果只有 appname 和 section,则将指定的区域连同所有有关的注册表项设置都删除。
key 可选。字符串表达式,包含要删除的注册表项设置。
说明 如果提供了所有参数,则删除指定的注册表项设置。如果试图使用不存在的区域或注册表项设置上的 DeleteSetting 语句,则发生一个运行时错误。
函数示例 见SaveSetting函数示例
二、 调用 Windows API 函数来操作注册表
虽然VB本身提供了四个关于注册表的函数,但是这四个函数只能在标准位置即“HKEY_CURRENT_USER\Software\VB and VBA ProgramSettings”下读取、删除、修改键值。对于一般的应用程序,利用它们就可以达到您的目的,对于特殊的要求利用它们就显得无能为力了。在 Visual Basic 中除了使用这四个内部语句或函数外,还可以调用 Windows API 函数来操作注册表。
所谓 API(Application Programing Interface) 是 Windows 提供的一个32位环境下的应用程序编程接口,其中包括了众多的函数,提供了相当丰富的功能。我们在编制应用程序时,可以调用其中的注册表函数来对注册表进行操作以实现我们需要的功能。Windows API 中可用于注册表的函数一共有二十多个,根据其功能不同可以分为如下几类:
1.键管理类
RegCloseKey() RegCreateKey() RegCreateKeyEx() RegDeleteKey() RegDeleteKeyEx() RegOpenKey() RegOpenKeyEx()
2.值管理类
RegDeleteValue() RegQueryValue() RegQueryValueEx() RegSetValue() RegSetValueEx()
3.查询计数类
RegQueryInfoKey() RegEnumKey() RegEnumKeyEx() RegEnumValue()
4.备份/恢复类
RegLoadKey() RegReplaceKey() RegRestoreKey() RegSaveKey()
5.实用类
RegConnectRegistry() RegNotifyChangeKeyValue() RegUnloadKey()
6.安全类(仅适用于NT)
RegGetKeySecurity() RegSetKeySecurity()
下面详细介绍这几个Windows API 函数的用法:
1. RegOpenKey——取得SubKey的Hkey
#p#副标题#e#
RegOpenKeyEx():同RegOpenKey()
VB声明 Declare Function RegOpenKey Lib “advapi32.dll” Alias “RegOpenKeyA” (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long
参数类型及说明:
hKey:Key Handle
lpSubKey:SubKey名称或路径
phkResult:若RegOpenKey执行成功,则这一参数返回Subkey的hKey.
返回值: =0,表示成功;≠0,表示失败。[注意这一点与别的API函数不太一样]
示例:
ret = RegOpenKey(HKEY_LOCAL_MACHINE, “SOFTWARE\Microsoft”, hKey) |
2.RegCreateKeyEx、RegCreateKey函数:建立SubKey
VB声明 Declare Function RegCreateKey Lib “advapi32.dll” Alias “RegCreateKeyA” (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long |
它的参数用法与RegOpenKey一样。所不同的是RegOpenKey只能打开已经有的SubKey,而RegCreateKey则可以建立SubKey,比较特别的是,如果调用RegCreateKey所建立的SubKey是一个已经存在的SubKey,则它的功能和RegOpenKey相同。由于RegCreateKey的这种特性,有的程序员干脆不用RegOpenKey,而用RegCreateKey来统一代替RegOpenKey。
示例:
ret = RegCreateKey(HKEY_LOCAL_MACHINE, “SOFTWARE\Hongqt”, hKey) |
3.RegClose函数:关闭SubKey
Declare Function RegCloseKey Lib “advapi32.dll” (ByVal hKey As Long) As Long |
当我们不再存取Registry时,将打开或建立的SubKey关闭是一个比较好的习惯,就正如我们在使用C语言的文件打开函数后必须要关闭一样。
示例:
ret = RegOpenKey(HKEY_LOCAL_MACHINE, “SOFTWARE\Microsoft”, hKey) …… RegClose hkey |
VB声明
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 hKey: Key Handle |
lpSubKey:SubKey名称路径
lpValue:返回读取的Default Value
lpcbValue:传入lpValue参数的长度,若成功读取了默认值default value,则返回default value字符串的长度(含chr(0))这个和C语言中字符串的处理相似,都是以chr(0)作为结束符。
返回值: =0,表示成功;≠0,表示失败。
示例:
ret = RegQueryValue(hKey, Subkey, “”, lenS) |
5.RegSetValue——删除某Key的默认值(default value)
VB声明
Declare Function RegSetValue Lib “advapi32.dll” Alias “RegSetValueA” (ByVal hKey As Long, ByVal lpSubKey As String, ByVal dwType As Long, ByVal lpData As String, ByVal cbData As Long) As Long |
hKey:Key Handle
lpSubKey:Subkey名称或路径
dwType:数据类型,但在这里只能接受REG_SZ[字符串类型]
lpData:所设置的字符串
cbData:lpData字符串的长度,这一长度包括chr(0)字符。
关于dwType的可能取值
Enum ValueType
REG_NONE = 0
REG_SZ = 1
REG_EXPAND_SZ = 2
REG_BINARY = 3
REG_DWORD = 4
REG_DWORD_BIG_ENDIAN = 5
REG_MULTI_SZ = 7
End Enum
示例:
Function SetDefaultValue(ByVal hKey As Long, ByVal Subkey As String, ByVal Value As String) As Boolean Dim ret As Long, lenS As Long, S As String ret = RegSetValue(hKey, Subkey, REG_SZ, Value, LenB(StrConv(Value, vbFromUnicode)) + 1) SetDefaultValue = (ret = 0) End Function |
6.RegQueryValueEx——读取某Key的特定名称的值(Value)
#p#副标题#e#
VB声明和参数解释:
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 |
hkey:Key Handle
lpValueName:Value Name
lpReserved:保留参数,调用时设置为0即可
lpType:返回读取的数据类型
lpData:返回读取的数据
lpcbData:传入lpData数据的长度,若成功读取数据,则返回所读取的数据的长度。
返回值: =0,表示成功;≠0,表示失败。
说明:
① 这一函数除了可读取指定名称的值之外,也可以读取default value。如果要读取default value,只需要将参数lpValueName设置为””[空字符串]即可。
②lpType 的可能取值
Enum ValueType
REG_NONE = 0
REG_SZ = 1 ——>字符串
REG_EXPAND_SZ = 2 ——>可展开式字符串
REG_BINARY = 3 ——>Binary数据
REG_DWORD = 4 ——>长整数
REG_DWORD_BIG_ENDIAN = 5 ——>BIG_ENDIAN长整数
REG_MULTI_SZ = 7 ——>多重字符串
End Enum
示例:
Dim hKey As Long, ret As Long, lenData As Long, typeData As Long Dim Name As String ‘读取HKEY_LOCAL_MACHINE\Software\Microsoft ‘\Windows\CurrentVersion\Run的internat.exe的value. Name=”internat.exe” ret=RegOpenKey(HKEY_LOCAL_MACHINE, ”Software\Microsoft\Windows\CurrentVersion\Run”, hKey) if ret=0 then ret = RegQueryValueEx(hKey, Name, 0, typeData, ByVal vbNullString, lenData)’注意ByVal千万别忘了 end if |
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 |
参数说明:
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 |
8.RegSetValueEx——设置某Key特定名称的值(Value)
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,表示失败。
示例:
Dim hKey As Long Dim L As Long L = 99999 RegCreateKey HKEY_CURRENT_USER, “Software\SetValue”, hKey RegSetValueEx hKey, “LongData”, 0, REG_DWORD, L, 4 |
9.RegDeleteValue——删除某Key的某一名称
#p#副标题#e#
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\SetValueSubKeyStr1Value” RegDeleteValue hKey, “” MsgBox “已删除HKCU\Software\SetValueSubKey‘预设值’” End If |
RegEnumKeyEx():返回注册表键及其子键的详细信息。
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 |
11.RegDeleteKey——删除Key或者SubKey
RegDeleteKeyEx():同RegDeleteKeyEx() 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,表示失败。
示例
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下则会报错。
12.RegQueryInfoKey():返回注册表键的信息,包括类名、子键数量、最长子键名、值的数量、最长值数据、安全描述符的长度以及上一次写入的时间等。
RegQueryInfoKey(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) |
参数:hKey–键句柄 lpClass–类型名称,仅使用于NT。若不使用则传入Null
lpcbClass–传入lpClass参数长度,返回读取的长度 lpReserved–保留参数补0
lpSubKeys–返回子键的数目 lpcbMaxSubKeyLen–返回最长的子键长度
lpcbMaxClassLen–返回最长的类长度 lpcValues–返回值的数目
#p#副标题#e#
lpcbMaxValueName–返回最长的值项名称的长度
lpcbMaxValueLen–返回最长的值的长度
lpcbSecurityDescriptor–返回安全描述,仅适用于 NT
lpftLastWriteTime–返回键最后被写入的时间,仅适用于 NT
返回值:=0 成功 ≠0 失败
13.RegLoadKey():从指定的文件恢复注册表键的子键信息到注册表。
RegLoadKey(ByVal hKey As Long, ByVal lpSubKey As String, ByVal lpFile As String) |
RegReplaceKey(ByVal hKey As Long, ByVal lpSubKey As String, ByVal lpNewFile As String, ByVal lpOldFile As String) |
15.RegRestoreKey():仅适用于Windows NT。从指定的文件中读取注册表键的信息并覆盖注册表中原有的值。
RegRestoreKey(ByVal hKey As Long, ByVal lpFile As String, ByVal dwFlags As Long) |
16. RegSaveKey():保存键及其子键信息到指定的文件。
RegSaveKey(ByVal hKey As Long, ByVal lpFile As String, lpSecurityAttributes As SECURITY_ATTRIBUTES) |
17. RegConnectRegistry():连接到远程系统的注册表。
RegConnectRegistry(ByVal lpMachineName As String, ByVal hKey As Long, phkResult As Long) |
18. RegNotifyChangeKeyValue():当修改指定的注册表对象时提供通知。
RegNotifyChangeKeyValue(ByVal hKey As Long, ByVal bWatchSubtree As Long, ByVal dwNotifyFilter As Long, ByVal hEvent As Long, ByVal fAsynchronus As Long) |
19. RegUnloadKey():删除注册表键及其所有的子键。
RegUnLoadKey(ByVal hKey As Long, ByVal lpSubKey As String) |
20. RegGetKeySecurity():检索指定键的安全信息。
RegGetKeySecurity(ByVal hKey As Long, ByVal SecurityInformation As Long, pSecurityDescriptor As SECURITY_DESCRIPTOR, lpcbSecurityDescriptor As Long) |
21. RegSetKeySecurity():设置指定键的安全信息。
RegSetKeySecurity(ByVal hKey As Long, ByVal SecurityInformation As Long, pSecurityDescriptor As SECURITY_DESCRIPTOR) |
最后给出两个函数是经过王国荣老师改编过的函数,与此相关,也一并列出。并且在我们的例子程序中要用到它们。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,表示失败。
#p#副标题#e#
调用例子:
ret=0 myindex=0 while ret=0 ret=RegEnumValue(hkey,myindex,Name,ByVal 0, typeData, ByVal vbNullString, lenData) myindex=myindex+1 wend |