您好,VV。这是一个那种最终搞得我们焦头烂额的问题。因为它:a) 看起来很简单,b) 而且似乎有许多方式可获取此信息。例如,在 Windows XP 计算机上有不少于八个 WMI 类在类名中某处包括缩写词 ODBC。其中的一个类肯定将返回安装的驱动程序的列表,对吧?
不对。我们要获得的是 ODBC Data Source Administrator 对话框中的 Drivers 选项卡中的信息:
但是 WMI 类似乎都不返回该信息,至少不直接返回。(可能有一种错综复杂的方法可得到此信息,但是我们脚本专家任何时候都尽可能避免使用复杂的方法。)所有希望似乎都已破灭,但是其中一个脚本专家决定对此问题应用“楼上密室”理论。在此特定的“脚本之家”中,任何时候只要丢失什么东西,您几乎都可以打赌在楼上密室中能找到,即使从未将它扔入密室,即使房间里所有的人都郑重发誓他们没有将它放到那里。
|
注意。摆着父亲的姿态,这个脚本专家过去常常讽刺着说:“它不是自己走到那里的,是吧?”如今 11 年后,他开始认为丢失的东西可能真的是自己走过去的。 |
注册表(您肯定知道)就是操作系统的楼上密室:如果愿意查找,几乎可以在注册表中找到任何信息。而且,千真万确,我们就是从那里在 HKEY_LOCAL_MACHINE/SOFTWARE/ODBC/ODBCINST.INI/ODBC Drivers 中找到安装的 ODBC 驱动程序的列表。(很奇怪,我们还找到了一双鞋、我们一直喜欢的那件夹克、还有消失五六年的一把钢锯。)
知道了可以从注册表取出此信息后,编写检索所有已安装 ODBC 驱动程序的列表的脚本立即就变得非常容易。
Const HKEY_LOCAL_MACHINE = &H80000002
strComputer = "."
Set objRegistry = GetObject("winmgmts://" & strComputer & "/root/default:StdRegProv")
strKeyPath = "SOFTWARE/ODBC/ODBCINST.INI/ODBC Drivers"
objRegistry.EnumValues HKEY_LOCAL_MACHINE, strKeyPath, arrValueNames, arrValueTypes
For i = 0 to UBound(arrValueNames)
strValueName = arrValueNames(i)
objRegistry.GetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
Wscript.Echo arrValueNames(i) & " -- " & strValue
Next
我们首先定义一个名为 HKEY_LOCAL_MACHINE 的常量并将值设定为 &H80000002;我们将用此常量指示我们要使用 HKEY_LOCAL_MACHINE 注册表配置单元。连接到 WMI 服务和标准的注册表提供程序 (root/default:StdRegProv),然后使用此代码行将注册表在 HKEY_LOCAL_MACHINE 内的路径赋值给变量 strKeyPath:
strKeyPath = "SOFTWARE/ODBC/ODBCINST.INI/ODBC Drivers"
结果,安装的 ODBC 驱动程序存储为此注册表项中的单个注册表值,与此类似:
因此,若要检索所有这些注册表值的集合,需要调用 EnumValues 方法,此方法会自动获取指定项中的所有值:
objRegistry.EnumValues HKEY_LOCAL_MACHINE, strKeyPath, arrValueNames, arrValueTypes
调用 EnumValues 时,需要提供两个输入参数和两个输出参数。“输入参数”是向方法提供的值;在此脚本中,传递常量 HKEY_LOCAL_MACHINE 和变量 strKeyPath。这些参数一起告诉脚本我们正在使用哪个注册表项。
“输出参数”表示方法提供给我们的信息。要获取此信息,只需提供一对变量名。在我们的脚本中,变量 arrValueNames 最终将保存在 SOFTWARE/ODBC/ODBCINST.INI/ODBC Drivers 中找到的所有注册表值名称的数组;变量 arrValueTypes 将保存每个注册表值的数据类型数组。(之所以包括此特定参数,只是因为它是必需的。因为我们的所有注册表值都具有相同的数据类型 - REG_SZ - 我们不必担心数据类型,因而不会使用 arrValueTypes。)
调用 EnumValues 之后,所有单个注册表值名称都将(以一个数组的形式)存储在变量 arrValueNames 中。要访问这些值,需要设置一个在数组中从 0 运行到最后一个项(上限或 UBound)的 For-Next 循环。(如您所知,VBScript 中数组的第一个项始终为项 0。)这就是下述代码行的作用:
For i = 0 to UBound(arrValueNames)
在此循环内,将第一个注册表值的名称赋值给名为 strValueName 的变量:
strValueName = arrValueNames(i)
之所以这么做,是因为此时我们只有单个注册表值的名称。要实际获取为这些注册表项赋予的值,需要调用 GetStringValue 方法,类似我们此处执行的功能:
objRegistry.GetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
您可以看到,我们将四个参数传递给 GetStringValue:
| • |
HKEY_LOCAL_MACHINE,表示注册表配置单元。 |
| • |
strKeyPath,HKEY_LOCAL_MACHINE 中的注册表路径。 |
| • |
strValueName,表示单个注册表值。 |
| • |
strValue,将存储注册表项的值的输出参数。 |
然后,只需使用此代码行回显注册表值的名称及赋予它的值:
Wscript.Echo arrValueNames(i) & " -- " & strValue
而且我们运行脚本时,将得到如下输出:
SQL Server -- Installed
Microsoft Access Driver (*.mdb) -- Installed
Microsoft Text Driver (*.txt; *.csv) -- Installed
Microsoft Excel Driver (*.xls) -- Installed
Microsoft dBase Driver (*.dbf) -- Installed
Microsoft Paradox Driver (*.db ) -- Installed
可能不象我们喜欢的那么直接,但是您知道他们说了什么:已安装 ODBC 驱动程序的列表是已安装 ODBC 驱动程序的列表。(我们不确定它们为何这样说,但是至少在本例中有些意义。)