Link to home
Start Free TrialLog in
Avatar of npnp
npnp

asked on

Retrieving info from registry

Using VB6.  How do I retrieve the full path of an installed executable?  Something like:

Dim strPath As String
strPath = GetSetting(foo.exe, "Settings")

What should "Settings" be?

I appreciate any help. -- Norm
Avatar of tWiZtEr
tWiZtEr

You want to find the full path of an executable which is normally in a certain place, or definatly has a registry entrry pointing to its most current location?
Avatar of npnp

ASKER

Yes.  This application installs normally in a default location.  However, the user may have elected to install the application somewhere else.

After installation, here comes a "customization" floppy which is customer-specific.  The setup.exe on the floppy needs to know where the application was installed.

How do I do that? -- Norm
ASKER CERTIFIED SOLUTION
Avatar of kanithi
kanithi

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
If the executable has a file extension associated with it you can use the FindExecutable API.

This example will create a temp file with an .html extension,then use that file to get the .exe associated with it. The temp file will then be deleted.

'------------------

Private Declare Function FindExecutable Lib "shell32.dll" Alias "FindExecutableA" (ByVal lpFile As String, ByVal lpDirectory As String, ByVal lpResult As String) As Long

' this will return the executable that is associated with an html extension
Private Sub Command1_Click()
Dim strEXE As String * 255
' create temp file with extension to check
Open "C:\temp.html" For Output As #1
Close #1
Call FindExecutable("C:\temp.html", "", strEXE)
MsgBox strEXE
Kill "C:\temp.html"
End Sub

'----------

if the app does not have an extension associated,then disregard this comment.
Avatar of npnp

ASKER

vinnyd79:
When I run your code, the message box exhibits:

"C:\Program Files\Internet Explorer\iexplore.exe"

??? -- Norm
Yes,that is the full path to the executable that is associated with an ".html" file. If you changed it to ".txt" it should return the full path to notepad. That's why I was saying it would work if the ".exe" you wanted to locate had a file extension associated with it.
Norm,

I don't think you're going to get what you need doing it this way with "GetSetting".  Try using the function and example below to get it done.

'PLACE THIS CODE IN A MODULE

' Declarations and Function to get strings from registry
'*******************************************************************************


Private Const REG_SZ                    As Long = 1

Public Const HKEY_LOCAL_MACHINE = &H80000002

Private Const BASE_KEY                  As String = "SOFTWARE"
Private Const BASE_KEY2                 As String = "SYSTEM"

Private Const ERROR_NONE                As Long = 0
Private Const ERROR_KEY_DOES_NOT_EXIST  As Long = 2

Private Const READ_CONTROL              As Long = &H20000
Private Const STANDARD_RIGHTS_READ      As Long = (READ_CONTROL)
Private Const STANDARD_RIGHTS_ALL       As Long = &H1F0000
Private Const KEY_QUERY_VALUE           As Long = &H1
Private Const KEY_SET_VALUE             As Long = &H2
Private Const KEY_CREATE_SUB_KEY        As Long = &H4
Private Const KEY_ENUMERATE_SUB_KEYS    As Long = &H8
Private Const KEY_NOTIFY                As Long = &H10
Private Const KEY_CREATE_LINK           As Long = &H20
Private Const SYNCHRONIZE               As Long = &H100000
Private Const KEY_ALL_ACCESS            As Long = ((STANDARD_RIGHTS_ALL Or _
                                                    KEY_QUERY_VALUE Or _
                                                    KEY_SET_VALUE Or _
                                                    KEY_CREATE_SUB_KEY Or _
                                                    KEY_ENUMERATE_SUB_KEYS Or _
                                                    KEY_NOTIFY Or _
                                                    KEY_CREATE_LINK) _
                                                    And (Not SYNCHRONIZE))
Private Const KEY_READ                  As Long = ((STANDARD_RIGHTS_READ Or _
                                                    KEY_QUERY_VALUE Or _
                                                    KEY_ENUMERATE_SUB_KEYS Or _
                                                    KEY_NOTIFY) _
                                                    And (Not SYNCHRONIZE))

Private Declare Function RegCloseKey _
    Lib "advapi32.dll" _
    (ByVal hKey As Long) As Long
   

     
Private 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
     
Private Declare Function RegQueryValueExString _
    Lib "advapi32.dll" Alias "RegQueryValueExA" _
    (ByVal hKey As Long, _
     ByVal lpValueName As String, _
     ByVal lpReserved As Long, _
     lpType As Long, _
     ByVal lpData As String, _
     lpcbData As Long) As Long
     
Private Declare Function RegQueryValueExNULL _
    Lib "advapi32.dll" Alias "RegQueryValueExA" _
    (ByVal hKey As Long, _
     ByVal lpValueName As String, _
     ByVal lpReserved As Long, _
     lpType As Long, _
     ByVal lpData As Long, _
     lpcbData As Long) As Long




'*******************************************************************************
' Gets the string value from the registry key, as explained below.
'
'
' Allows string passing from registry of the following key
' HKEY_LOCAL_MACHINE\SOFTWARE or if BASE_KEY2 then it allows from HKLM\SYSTEM (for services information and such)
' This can be changed to account for multiple keys within the registry.
'
' PARAMETERS:
' (In) - sAppName - String - The first level
' (In) - sSection - String - The second level
' (In) - sKey     - String - The key in the second level
' (In) - sDefault - String -
'
' RETURN VALUE:
' String - The value stored in the key or sDefault if not found
'
'*******************************************************************************
Public Function GetStringSetting(ByVal sAppName As String, _
                                 ByVal sSection As String, _
                                 ByVal sKey As String, _
                                 Optional ByVal sDefault As String) As String
 
    Dim lRetVal         As Long
    Dim sFullKey        As String
    Dim lHandle         As Long
    Dim lType           As Long
    Dim lLength         As Long
    Dim sValue          As String
    Dim lErrNumber      As Long
    Dim sErrDescription As String
    Dim sErrSource      As String
   
    On Error GoTo ERROR_HANDLER

    If Trim(sAppName) = "" Then
        Err.Raise vbObjectError + 1000, , "AppName may not be empty"
    End If
    If Trim(sSection) = "" Then
        Err.Raise vbObjectError + 1001, , "Section may not be empty"
    End If
    If Trim(sKey) = "" Then
        Err.Raise vbObjectError + 1002, , "Key may not be empty"
    End If
   
    sFullKey = BASE_KEY & "\" & Trim(sAppName) & "\" & Trim(sSection)

    ' Open the key first
    lRetVal = RegOpenKeyEx(HKEY_LOCAL_MACHINE, sFullKey, 0, KEY_READ, lHandle)
    If lRetVal <> ERROR_NONE Then
        If lRetVal = ERROR_KEY_DOES_NOT_EXIST Then
            GetStringSetting = sDefault
            Exit Function
        Else
            Err.Raise vbObjectError + 2000 + lRetVal, , _
                "Could not open registry section"
        End If
    End If
   
    ' Get information about key (size/type)
    lRetVal = RegQueryValueExNULL(lHandle, sKey, 0, lType, 0, lLength)
    If lRetVal <> ERROR_NONE Then
        GetStringSetting = sDefault
        Exit Function
    End If
   
    ' Is value a string?  So far I've only gotten it to return strings.  But I am working on dword, etc. values
    If lType = REG_SZ Then
        sValue = String(lLength, 0)
       
        If lLength = 0 Then
            GetStringSetting = ""
        Else
            lRetVal = RegQueryValueExString(lHandle, sKey, 0, lType, _
                sValue, lLength)
           
            If lRetVal = ERROR_NONE Then
                GetStringSetting = Left(sValue, lLength - 1)
            Else
                GetStringSetting = sDefault
            End If
        End If
    Else
        Err.Raise vbObjectError + 2000 + lType, , _
            "Registry data not a string"
    End If
   
TIDY_UP:
    On Error Resume Next
   
    RegCloseKey lHandle
   
    If lErrNumber <> 0 Then
        On Error GoTo 0
       
        Err.Raise lErrNumber, sErrSource, sErrDescription
    End If
Exit Function

ERROR_HANDLER:
    lErrNumber = Err.Number
    sErrSource = Err.Source
    sErrDescription = Err.Description
    Resume TIDY_UP
End Function

'######################################################
'PLACE THIS CODE IN A FORM

Private Sub Command_click()

HomeDirectory = GetStringSetting("Microsoft", "Windows NT\CurrentVersion", "PathName")

msgbox HomeDirectory

End Sub

This should show you the directory in which Windows is installed.

Good luck!

m.

Avatar of npnp

ASKER

Public Function GetStringSetting _
   (ByVal sAppName As String, _
    ByVal sSection As String, _
    ByVal sKey As String, _
    Optional ByVal sDefault As String) As String

ediqui: In the above, I don't know what to use for sSection and sKey.

Assume I am trying to locate the path to "foo.exe".  That's sAppName.  What is sSection?  What is sKey?
I presume sDefault will return a specific string if foo.exe is not found.  What is that "error" string?

I appreciate your help. -- Norm
 
Avatar of npnp

ASKER

Further comments:  I didn't expect this to be so complex.  I would think this function would come up frequently enough to be a solved problem.

Again in brief:  User may have installed the application at a location other than the default.  After installing, there is a "license floppy" which installs some customer-specific files in the folder where the application was installed.  To this end, the setup.exe on the floppy needs to determine where that is.  That path may be identified by locating a certain file whose name is peculiar enough to warrant the assumption that it is unique.

How do I determine the path to a specified file name which may be anywhere in the tree? -- Norm
Avatar of npnp

ASKER

I believe I found what I am looking for at that site.
Thank you! -- Norm