关于winapi:在VBA中使用RegQueryValueEx不断出现错误2(注册表路径不存在)

Keep getting error 2 (Registry path does not exist) with RegQueryValueEx in VBA

我正在尝试让 VBA 查询注册表以查看是否安装了 ODBC 驱动程序,但在尝试读取键值时出现错误 2。我尝试了一个更简单的键/值,但没有雪茄。

编辑澄清

我在 32 位系统上进行开发,但这需要同时适用于 32 位和 64 位系统。问题是对 RegOpenKeyEx 的调用有效,但 RegQueryValueEx 返回错误 2:我的 32 位系统上不存在文件。我的语法似乎正确,我做错了什么?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Public Const HKEY_LOCAL_MACHINE = &H80000002
Public Const ERROR_SUCCESS = 0&                ' Successful
Public Const ERROR_FILE_NOT_FOUND = 2&         ' Registry path does not exist
Public Const ERROR_ACCESS_DENIED = 5&          ' Requested permissions not available
Public Const STANDARD_RIGHTS_READ = &H20000
Public Const SYNCHRONIZE = &H100000
Public Const KEY_ENUMERATE_SUB_KEYS = &H8
Public Const KEY_NOTIFY = &H10
Public Const KEY_QUERY_VALUE = &H1
Public Const KEY_READ = ((STANDARD_RIGHTS_READ Or KEY_QUERY_VALUE _
                        Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY) _
                        And (Not SYNCHRONIZE))
Public Const REG_SZ = 1 ' Unicode nul terminated string

Public Declare Function RegOpenKeyEx Lib"advapi32.dll" Alias"RegOpenKeyExA" _
    (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As _
    Long, ByVal samDesired As Long, phkResult As Long) As Long
Public Declare Function RegQueryValueEx Lib"advapi32.dll" Alias"RegQueryValueExA" _
    (ByVal hKey As Long, lpValueName As String, _
    ByVal lpReserved As Long, lpType As Long, _
    lpData As Any, lpcbData As Long) As Long
Public Declare Function RegCloseKey Lib"advapi32.dll" _
    (ByVal hKey As Long) As Long

Sub TestRegAPI()
  Dim KeyName As String, handle As Long, handle2 As String

  'KeyName ="SOFTWARE\\ODBC\\ODBCINST.INI\\ODBC Drivers"
  KeyName ="SOFTWARE\\7-Zip"
  r = RegOpenKeyEx(HKEY_LOCAL_MACHINE, KeyName, 0, KEY_READ, handle)
  If r Then
    MsgBox"Unable to open the specified Registry key, code" & r
    Else
    'r = RegQueryValueEx(handle,"MySQL ODBC 5.1 Driver", 0, 1&, handle2, length)
    r = RegQueryValueEx(handle,"Path", 0, REG_SZ, handle2, length)
    RegCloseKey handle
  End If
End Sub


从我在 Wikipedia 上可以找到的信息来看,Windows NT4 将 WMI 作为可下载的附加组件,而从 Windows 2000 来看,它是 Windows 的捆绑组件。这里我的示例是将安装路径加载到 Mozilla Thunderbird:

1
2
3
4
5
6
7
8
9
10
11
12
13
Const HKEY_LOCAL_MACHINE = &H80000002

Set objRegistry = GetObject("winmgmts:\\\\.\
oot\\default:StdRegProv")

strKey_Path ="SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\thunderbird.exe"

 ' here the value name is blank, because I want the default value for the key, otherwise it wouldn't be""
strValue_Name =""



objRegistry.GetStringValue HKEY_LOCAL_MACHINE, strKey_Path, strValue_Name, strThunderbird_Path

这适用于我在 64 位机器上。它来自 http://blogs.technet.com/b/heyscriptingguy/archive/2005/07/07/how-can-i-get-a-list-of-the-odbc-drivers-that-are-installed -on-a-computer.aspx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Const HKEY_LOCAL_MACHINE = &H80000002

strComputer ="."

Set objRegistry = GetObject("winmgmts:\" & strComputer &"\
oot\\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
    Debug.Print arrValueNames(i) &" --" & strValue
Next