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
Dim strPath As String
strPath = GetSetting(foo.exe, "Settings")
What should "Settings" be?
I appreciate any help. -- Norm
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?
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
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.ht ml", "", strEXE)
MsgBox strEXE
Kill "C:\temp.html"
End Sub
'----------
if the app does not have an extension associated,then disregard this comment.
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.ht
MsgBox strEXE
Kill "C:\temp.html"
End Sub
'----------
if the app does not have an extension associated,then disregard this comment.
ASKER
vinnyd79:
When I run your code, the message box exhibits:
"C:\Program Files\Internet Explorer\iexplore.exe"
??? -- Norm
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\SOFTWAR E 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_MA CHINE, 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(lHandl e, 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(lHan dle, 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("Microsof t", "Windows NT\CurrentVersion", "PathName")
msgbox HomeDirectory
End Sub
This should show you the directory in which Windows is installed.
Good luck!
m.
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\SOFTWAR
' 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_MA
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(lHandl
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(lHan
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("Microsof
msgbox HomeDirectory
End Sub
This should show you the directory in which Windows is installed.
Good luck!
m.
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
(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
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
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
ASKER
I believe I found what I am looking for at that site.
Thank you! -- Norm
Thank you! -- Norm