精华区 [关闭][返回]

当前位置:月光软件>>讨论区精华>>〖电脑技术〗>>● WinNT系统>>WIN 家族注册表大全>>使用Visual Basic读取和修改Windows注册库

主题:使用Visual Basic读取和修改Windows注册库
发信人: gui8848(尖牙小鬼)
整理人: gui8848(2001-11-20 15:35:02), 站内信件
在过去,在进行Microsoft_Visual Basic 应用程序的开发时,感到在两次应用程序的运行之间保留状态信息是非常困难的。这是因为基于Microsoft Windows的应用程序(包括Visual Basic)需要将应用程序的状态信息写入到一个文本文件(*.INI文件)中,并且需要经常对这些文件中的文本进行分析,以包含有用的状态信息。

  现在,随着Windows 95以及Windows NT等32位操作系统的出现,应用程序可以通过使用一个叫做Windows注册库的存储场所来保留应用程序的状态信息,并且将它们自己注册在系统之中。通过位于ADVAPI32.DLL中的C语言应用程序编程接口(APIs),使得对注册库的提取和修改变得非常容易。

  这对于使用C和C++的程序员来说真是太好了,不过对于那些使用其它编程语言,例如Visual Basic版本4.0的程序员来说,使用这些编程接口还需要进行许多额外的工作。

  作为一个Visual Basic 4.0程序员,你首先必须在一个*.BAS文件中定义注册库函数的原形,这些函数原形必须同存储在ADVAPI32.DLL中的所需要的注册库APIs相兼容。你还需要添加那些对调用这些APIs所需要的结构和常量的声明。这些对函数原形,结构以及常量的声明全部包含在VBREG.BAS文件中,该文件是VBREG,本文的配套样例代码的一部分。要在任何32位的Visual Basic 4.0工程中使用这些注册库APIs,只需要简单地将VBREG.BAS文件包含在工程中。

  注意:如果你决定在VBREG.BAS文件中添加额外的APIs,结构或常量,在对它们进行声明的时候需要格外小心(特别是这些函数的参数)。要想这些在你的Visual Basic代码中被调用的APIs按照你所预想的工作,正确声明这些函数的参数是非常重要的。许多这类声明的例子可以在WIN32API.TXT文件中找到,该文件作为Visual Basic 4.0系统的一部分同时被安装,但是你可能需要对这些声明进行修改,以便使它们能够正常工作。你还可以在WINNT.H文件中找到额外的一些有用的注册库常量,在WINERROR.H文件中找到额外的一些有用的错误常量。

  一旦你将一个文件,例如VBREG.BAS包括在你的工程中,你就可以在你的Visual Basic代码中调用这些注册库APIs。要记住的是你所转递的参数必须有效且包含有效的值。另外,当STRING值被返回时,必须为此字符串创建一个空间来容纳它。这些APIs,结构以及常量在VBREG样例应用程序中都有说明。

  Windows注册库通过四个主要注册关键字来组织:HKEY_CLASSES_ROOT,HKEY_CURRENT_ USER,HEKY_LOCAL_MACHINE,以及HKEY_USERS。在本文中假设你对于这些关键字已经非常熟悉,已经知道如何使用子关键字,以及已经了解在注册库中所包含的值的类型。子关键字可以用"HighestSubkey \NextLevelSubkey\LowerLevelSubkey\"(不包括引号)的形式来表示。其中"HighestSubkey"是最高级的子关键字,它直接位于四个主关键字之下。

  注册关键字可以被创建,删除,打开,关闭。正如你可能所想到的,一个注册关键字在能够使用之前需要首先创建它,在对一个注册关键字进行修改之前必须要首先打开它。在应用程序执行期间,你应该关闭所有的当前未被使用的关键字,并且你应该仅仅只删除那些你能确定将来绝对不会再使用的关键字。

  注册值可以被创建,查询,修改以及删除。一个值在它能够被查询之前必须已经被创建或是修改(通过使用RegSetValueEx来完成)。同注册关键字一样,如果你想删除它,你需要确定它将来绝对不会再被使用。

  另外,注册关键字和值可以被枚举,以助你决定当前的那些输入是可以使用的。如果你在编译期间不能够确定对哪些关键字或值感兴趣,枚举功能就非常有用了。

  有一点很有趣的注意事项是RegDeleteKeyAPI在没有子关键字的情况下将只删除注册关键字。由于这个原因,VBREG不允许删除一个带有子关键字的关键字。不过你能够很容易的添加删除关键字以及子关键字的功能,你只需要创建一个过程,该过程枚举你需要操作的关键字下的所有子关键字(以及这些子关键字的子关键字),并且在删除该关键字之前首先删除所有的子关键字。对于每个子关键字都应该在RegDeleteKey函数中检查ERROR_ACCESS_DENIED标志,这样的有效的递归进程能工作得很好。

  VBREG使用HKEY_LOCAL_MACHINE,在如下的VBREG Form_Load()过程中被设置:

  hKey = HKEY_LOCAL_MACHINE

  通过将此变量设置为其它的四个主注册关键字之一,你能够很容易的使用它们。更进一步,你能够从用户或是一个已知的注册库位置获取这些信息。

  当使用这些注册库APIs,一个比较好的方法是检查函数所返回的值以确定函数的调用是否成功(如果函数调用成功,它将会返回ERROR_SUCCESS标志)。如果不成功,你还可以检查错误值,基于错误发生的类型,你可以决定你的应用程序接下来该怎么做。还有一个比较好的方法是使用注册库APIs(例如在VBREG样例中的CreateRegKey函数)来为错误设置陷井,以决定你的应用程序在错误发生后的行为。

  VBREG创建和修改的值都是REG_SZ类型(Unicode空结束字符串)的值。这里还有几种其它类型的值可以在注册库中使用,例如REG_BINARY,REG_LINK,以及REG_DWORD。例如,要写一个REG_DWORD类型来替换REG_SZ类型,则SetRegValue过程的RegSetValueEx调用应该被改为:

  lResult = RegSetValueEx(phkResult, sSetValue, 0, REG_DWORD, CInt(sValue), 4&)

  这里假设该"sValue"包含一个可以被转化为一个整数的值。你可能会需要在代码中进行更深入的修改以使用这些其它类型的值。

  在你能够使用一个注册库关键字之前,该关键字必须被创建。RegCreateKeyEx API提供了运行时刻的这个功能。如果关键字不存在,则RegCreateKeyEx 将创建一个新的关键字,而如果关键字已经存在,则将只简单地将它打开。下面是在VBREG的CreateRegKey过程中对RegCreateKeyEx的调用。

  CreateRegKey = (RegCreateKeyEx(hKey, SubKey & NewSubKey, 0, "", _

  REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, _

  SA, phkResult, Create) = ERROR_SUCCESS)

  如果RegCreateKeyEx函数返回了ERROR_SUCCESS标志,则你可以为REG_CREATED_NEW_KEY或REG_OPENED_EXISTING_KEY检查Create参数,以确定是否有一个新的关键字被创建。在上面的调用中,REG_OPTION_NON_VOLATILE创建一个持久的关键字,KEY_ALL_ACCESS则给予所有的用户对此关键字的完整的访问权利。其它的选项也同样能够被指定。这些选项在Visual C++所带的Windows API参考中有更深入的解释。

  一旦你有需要的注册库关键字,你可以使用RegOpenKey或RegKeyCreateEx来在将来需要的时候打开它们。你可能会注意到在VBREG中在看上去应该使用RegOpenKey的地方使用了RegKeyCreateEx。我发现如果不使用RegKeyCreateEx来打开此关键字,则有一些操作将会返回ERROR_ACCESS_DENIED标志。这可能会构成额外的开支;如果该关键字不存在的话它将会真正地创建此关键字。如果这不是你所需要的,你应该试着在调用RegCreateKeyEx之前首先调用RegOpenKey,然后看看它的调用是否成功。

  一旦一个关键字被打开,你可以使用RegSetValueEx来设置它的值,如果需要的话,你也可以创建它。如果一个值还不存在,而你又不想创建它,你应该在调用RegSetValueEx之前首先调用RegQueryValueEx,然后测试它的返回值是不是ERROR_SUCCESS。下面是在VBREG的SetRegValue过程中对RegSetValueEx的调用:

  lResult = RegSetValueEx(phkResult, sSetValue, 0, REG_SZ, sValue, _

  CLng(Len(sValue) + 1))

  在上面的调用中,REG_SZ是被写入的值的类型。正如在前面所提到过的,如果你正确转递参数,你也可以写入其它类型的值。

  你还可以通过使用RegQueryValueEx来在注册库中查询一个存在的值。如果此函数调用成功,它将会返回ERROR_SUCCESS标志。下面是VBREG的GetRetValue过程中的代码段:



  ' Creat the buffer.

szBuffer = Space(255)

lBuffSize = Len(szBuffer)

  ' Open the key.

RegOpenKeyEx(hKey, lpszSubKey, 0, 1, phkResult)

  ' Query the value

lResult = RegQueryValueEx( phkResult, szKey, 0, 0, szBuffer, lBuffSize)



  在这里需要注意的最为重要的事情是要为缓冲创建足够的空间。使用C语言APIs返回一个STRING值作为一个输出(out)参数(例如RegQueryValueEx的第5个参数),你必须显式地为此参数定义一个空间。如果这项操作失败,将会导致产生一个不可预料的结果值。

  这篇文章意图告诉你在Visual Basic 4.0应用程序中如何使用Windows注册库APIs。如果你希望看到更多的有关Windows注册库或注册库APIs的信息,请参考Visual C++所带的Windows API参考,以及在Microsoft 开发库(Microsoft Development Library)中有关的文字。

[关闭][返回]






转载请注明:转载自 月光程序代码网 [ http://www.moon-soft.com ]