Solved

Using RegOpenKeyEx to enumerate through registry on 64bit office/64 bit windows

Posted on 2013-12-06
9
1,207 Views
Last Modified: 2016-09-30
The main objective is to see if an ODBC driver has been installed. I've been doing this by enumerating through the registry using RegOpenKeyEx . No problem using 32 bit Office on 64 Bit windows.
But won't work on 64Bit Office on 64bit  windows.

The code below shows the many things I tried. Only line 10 works when testing on 32 bit office. otherwise none of the other lines work for either 32 or 64 bit. Any ideas?

John

Option Compare Database
Option Explicit

#If VBA7 Then
    'For Office 64Bit
    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
#Else
    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
#End If
              
Function CheckForMySQlDriverInstallTest() As Boolean

'*********BEGIN CODE HERE ********
Dim strKeyPath As String, key As String
Dim i As Long, lrc As Long
Dim hkey As Long, lRetval As Long

'Various key constants
Const KEY_ALL_ACCESS = &H3F
Const KEY_WOW64_64KEY As Long = &H100& '32 bit app to access 64 bit hive
Const KEY_WOW64_32KEY As Long = &H200& '64 bit app to access 32 bit hive
Const KEY_QUERY_VALUE = &H1

'Check if642bit office
If IsOffice64Bit() Then
    strKeyPath = "SOFTWARE\ODBC\ODBCINST.INI"
Else
    strKeyPath = "SOFTWARE\Wow6432Node\ODBC\ODBCINST.INI"
End If

hkey = 0

'Try various keys. Only line 10 below works, and only for 32bit office
10 lRetval = RegOpenKeyEx(HKEY_LOCAL_MACHINE, strKeyPath, 0, KEY_ALL_ACCESS, hkey)
'20 lRetval = RegOpenKeyEx(HKEY_LOCAL_MACHINE, strKeyPath, 0, KEY_WOW64_64KEY, hkey)
'30 lRetval = RegOpenKeyEx(HKEY_LOCAL_MACHINE, strKeyPath, 0, KEY_WOW64_32KEY, hkey)
'40 lRetval = RegOpenKeyEx(HKEY_LOCAL_MACHINE, strKeyPath, 0, KEY_QUERY_VALUE, hkey)

If (lRetval = 0) Then
    lrc = 0
    i = 0
    'Request all keys
    While lrc = 0
        lrc = EnumKey(hkey, i, key)
        Debug.Print key
        
        'If the version is found, set function to TRUE and exit
        If InStr(1, key, "MySQL ODBC 5.2 ANSI Driver") > 0 Then
            Exit Function
        End If
        
        If (lrc = 0) Then
            i = i + 1
        End If
    Wend
End If

If (hkey <> 0) Then
    RegCloseKey hkey
End If

End Function

Open in new window

0
Comment
Question by:askolits
  • 5
  • 2
  • 2
9 Comments
 
LVL 9

Expert Comment

by:Beartlaoi
ID: 39702233
Make sure that the name of the driver is as you expect it to be on the 64 bit systems.  Some drivers differentiate their name between 32 and 64 bit so that matching processes dont find the wrong one.
Also make sure that IsOffice64Bit() absolutely means you will always have the 64-bit version of the MySQL driver.  If we are talking about MS office then I dont see this as guaranteed since I'm not sure that MySQL drivers come with MS Office.  
On your Office 64-bit system search the registry just for "MySQL ODBC" and see whats installed.  Was the 64-bit driver installed yet?
0
 

Author Comment

by:askolits
ID: 39702262
MYSQL 64Bit?
Yes, I already have a routine that will install the proper driver and I do see the key in the registry when I use regedit. So I know it's there (See image)


ODBC Reginfo For MySql
0
 
LVL 9

Expert Comment

by:Beartlaoi
ID: 39702338
On a 64-bit OS the 64-bit part of the registry is not in the Wow6432Node subkey, this subkey is actually for 32-bit stuff on the 64-bit system.
On a 64-bit OS the 64-bit part of the registry is in the same place as it would be on a 32-bit system.

If (NOT IsWindow64Bit() ) OR IsOffice64Bit() Then
    strKeyPath = "SOFTWARE\ODBC\ODBCINST.INI"
Else '32-bit office on 64-bit windows
    strKeyPath = "SOFTWARE\Wow6432Node\ODBC\ODBCINST.INI"
End If

Open in new window

0
 

Author Comment

by:askolits
ID: 39702354
Actually, I removed the logic and tried both those paths and it still didn't work.
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Accepted Solution

by:
askolits earned 0 total points
ID: 39709711
Figured it out.

Have to use the key "KEY_READ = &H20019" and use it in the following line:
lRetval = RegOpenKeyEx(HKEY_LOCAL_MACHINE, strKeyPath, 0, KEY_READ, hkey)
0
 

Author Closing Comment

by:askolits
ID: 39719752
I finally figured it out for myself and the code would be of value to others having the same problem.
0
 

Expert Comment

by:CrazyBrit
ID: 41822807
Registry Entry@askolits

What does the KEY_READ = &H20019 values mean?  Are there other values, how do I find what the available values and what they are used for?
 I'm trying to get list of available printers:

Code I'm using is from [http://www.cpearson.com/excel/GetPrinters.aspx]

Declare PtrSafe Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" ( _
      ByVal hKey As LongPtr, _
      ByVal lpSubKey As String, _
      ByVal ulOptions As Long, _
      ByVal samDesired As Long, _
      phkResult As LongPtr) As Long

Declare PtrSafe Function RegEnumValue Lib "advapi32.dll" Alias "RegEnumValueA" ( _
      ByVal hKey As LongPtr, _
      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

Sub get_printers()

Dim Printers()          As String       ' array of names to be returned
Dim PNdx                As Long         ' index into Printers()
Dim hKey                As LongPtr      ' registry key handle
Dim Res                 As LongPtr      ' result of API calls
Dim Ndx                 As Long         ' index for RegEnumValue
Dim ValueName           As String       ' name of each value in the printer key
Dim ValueNameLen        As Long         ' length of ValueName
Dim DataType            As Long         ' registry value data type
Dim ValueValue()        As Byte         ' byte array of registry value value
Dim ValueValueS         As String       ' ValueValue converted to String
Dim CommaPos            As Long         ' position of comma character in ValueValue
Dim ColonPos            As Long         ' position of colon character in ValueValue
Dim M                   As Long         ' string index

Const HKEY_CURRENT_USER As Long = &H80000001
Const HKCU = HKEY_CURRENT_USER
Const KEY_QUERY_VALUE = &H1&
Const ERROR_NO_MORE_ITEMS = 259&
Const ERROR_MORE_DATA = 234

Const PRINTER_KEY = "Software\Microsoft\Windows NT\CurrentVersion\Devices"

Const maxPrinters As Long = 100

ReDim ValueValue(0 To maxPrinters - 1)
ReDim Printers(1 To maxPrinters)

Ndx = 0
ValueName = String$(256, Chr(0))
ValueNameLen = Len(ValueName) - 1

Res = RegOpenKeyEx(HKCU, PRINTER_KEY, 0&, KEY_QUERY_VALUE, hKey)
MsgBox "RegOpenKeyEx Result = " & Res
'* Returns 0

Res = RegEnumValue(hKey, Ndx, ValueName, ValueNameLen, 0&, DataType, ValueValue(0), 100)
MsgBox "RegEnumValue Result = " & Res
'* Returns 87

End Sub
0
 

Author Comment

by:askolits
ID: 41823278
&H20019 - Permission for general read access.
Essentially allows you to read the info.

I found this info at:
http://www.jasinskionline.com/windowsapi/ref/r/regopenkeyex.html

I use Microsoft Access to get a list of active printers through VBA.
So, I don't read the registry. If you want the VBA code I use, I can post it.
1
 

Expert Comment

by:CrazyBrit
ID: 41824036
Thanks askolits - the link has what I needed!
1

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

This script will sweep a range of IP addresses (class c only, 255.255.255.0) and report to a log the version of office installed. What it does: 1.)      Creates log file in the directory the script is run from (if it doesn't already exist) 2.)      Sweep…
I originally created this report in Crystal Reports 2008 where there is an option to underlay sections. I initially came across the problem in Access Reports where I was unable to run my border lines down through the entire page as I was using the P…
In Microsoft Access, learn how to use Dlookup and other domain aggregate functions and one method of specifying a string value within a string. Specify the first argument, which is the expression to be returned: Specify the second argument, which …
In Microsoft Access, when working with VBA, learn some techniques for writing readable and easily maintained code.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now