Rough explanation you just supply it the reg key name and it checks the registry against 4 subkeys where the data we need is held, it does them in this order
as not all keys are present its the only way ive found that gives half a chance of getting the info, It trys the most common first then onto the less good but seems to do the job
#cs ----------------------------------------------------------------------------
AutoIt Version: 3.3.6.1
Author: Chimaera
Script Function: Find Software Path From Registry Key Name
Credits goto guinness, GeoSoft and PsaltyDS for functions
#ce ----------------------------------------------------------------------------
#RequireAdmin
Global $soft_path
;<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>
Global $sRegKeyName = "\" & "Malwarebytes' Anti-Malware_is1" ; e.g. "{2ACBF1FA-F5C3-4B19-A774-B22A31F231B9}_is1" Or "CCleaner" Or "Malwarebytes' Anti-Malware_is1" copy filename from registry key
;<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>
Global $sRegValue0 = "InstallLocation", $sRegValue1 = "Inno Setup: App Path", $sRegValue2 = "DisplayIcon", $sRegValue3 = "UninstallString"
;~ InstallLocation - generally but not always available
;~ Inno Setup: App Path - less common but sometimes available
;~ DisplayIcon: Generally available ( deducts from end of string back and including first \)
;~ UninstallString Generally available ( deducts from end of string back and including first \)
;<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>
Global $sUninstallKey = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" & $sRegKeyName
;<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>
If _IsRegistryExist
($sUninstallKey, $sRegValue0) = 1 Or _IsRegistryExist
($sUninstallKey, $sRegValue1) = 1 Or _IsRegistryExist
($sUninstallKey, $sRegValue2) = 1 Or _IsRegistryExist
($sUninstallKey, $sRegValue3) = 1 Then
If _IsRegistryExist
($sUninstallKey, $sRegValue0) = 1 Then
$sValName = $sRegValue0
$aUninstallKeys = _RegSearch
($sUninstallKey, $sValName, 2, True)
_ArrayStart
()
$sInstallLocation = _GetDirectoryFormat
($soft_path, 0) ; <<<<<< removes \ from registry keys <<<<<<
ConsoleWrite("1/0 " & $sInstallLocation & @CRLF) ; <<<<<< error checking <<<<<<
ElseIf _IsRegistryExist
($sUninstallKey, $sRegValue1) = 1 Then
$sValName = $sRegValue1
$aUninstallKeys = _RegSearch
($sUninstallKey, $sValName, 2, True)
_ArrayStart
()
$sInstallLocation = _GetDirectoryFormat
($soft_path, 0) ; <<<<<< removes \ from registry keys <<<<<<
ConsoleWrite("1/1 " & $sInstallLocation & @CRLF) ; <<<<<< error checking <<<<<<
ElseIf _IsRegistryExist
($sUninstallKey, $sRegValue2) = 1 Then
$sValName = $sRegValue2
$aUninstallKeys = _RegSearch
($sUninstallKey, $sValName, 2, True)
_ArrayStart
()
$sInstallLocation = StringRegExpReplace($soft_path, "^(.*)\\.*$", "$1") ; <<<<<< removes \ from registry keys <<<<<<
ConsoleWrite("1/2 " & $sInstallLocation & @CRLF) ; <<<<<< error checking <<<<<<
ElseIf _IsRegistryExist
($sUninstallKey, $sRegValue3) = 1 Then
$sValName = $sRegValue3
$aUninstallKeys = _RegSearch
($sUninstallKey, $sValName, 2, True)
_ArrayStart
()
$sInstallLocation = StringRegExpReplace($soft_path, "^(.*)\\.*$", "$1") ; <<<<<< removes filename from the end of the registry key e.g. <<<<<<
ConsoleWrite("1/3 " & $sInstallLocation & @CRLF) ; <<<<<< error checking <<<<<<
Else
$sInstallLocation = "File Not Found"
ConsoleWrite("error 1" & @CRLF)
EndIf
EndIf
;<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>
ConsoleWrite("Install Location = " & $sInstallLocation & @CRLF) ; <<<<<< display file location <<<<<<
;<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>
Func _ArrayStart
()
Global $aUninstallStrings[UBound($aUninstallKeys)][2] = [[$aUninstallKeys[0], ""]]
For $n = 1 To $aUninstallKeys[0]
$aUninstallStrings[$n][0] = $aUninstallKeys[$n]
$aUninstallStrings[$n][1] = RegRead(StringTrimRight($aUninstallStrings[$n][0], StringLen($sValName)), $sValName)
$sSoftPathCheck = $aUninstallStrings[$n][1]
$soft_path = StringReplace($sSoftPathCheck, '"', "") ; <<<<<< removes " from registry keys <<<<<<
ConsoleWrite($sSoftPathCheck & @CRLF) ; <<<<<< error checking <<<<<<
Next
EndFunc ;==>_ArrayStart
;<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>
Func _IsRegistryExist
($sKeyName, $sValueName); 0 = Doesn't Exist / 1 = Exists [Author guinness]
RegRead($sKeyName, $sValueName)
Return Number(@error = 0)
EndFunc ;==>_IsRegistryExist
;<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>
; #FUNCTION# =========================================================================================================
; Name...........: _GetDirectoryFormat()
; Description ...: Formats a directory string with either the trailing "\" removed or included. It can also check whether the directory exists and create if not present.
; Syntax.........: _GetDirectoryFormat(ByRef $sDirectory, [$iAppend = 1, [$iFlag = 0]])
; Parameters ....: $sDirectory - A directory string with either the trailing "\" included or excluded.
; $iAppend - [Optional] Add trailing "\" to the end of the directory string. [Default = 1 - add trailing "\" or 0 - remove trailing "\"]
; $iFlag - [Optional] Check if the directory exists and create if not present. [Default = 0 - don't check if directory exists or 1 - check directory exists and create if not present.]
; Requirement(s).: v3.2.2.0 or higher
; Return values .: Success - Returns directory string with correct format.
; Failure - none
; Author ........: guinness
; Example........; Yes
;=====================================================================================================================
Func _GetDirectoryFormat
(ByRef $sDirectory, $iAppend = 1, $iFlag = 0)
Local $sAppend = ""
If $iAppend Then
$sAppend = "\"
EndIf
$sDirectory = StringRegExpReplace($sDirectory, "[\\/]+\z", "") & $sAppend
If FileExists($sDirectory) = 0 And $iFlag Then
DirCreate($sDirectory)
EndIf
Return SetError(0, 0, $sDirectory)
EndFunc ;==>_GetDirectoryFormat
;<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>
;*****************************************************
; Function: _RegSearch
;
; Purpose: Performs a recursive search of the registry starting at $sStartKey, looking for $sSearchVal
;
; Syntax: _RegSearch($sStartKey, $sSearchVal, $iType = 0x07, $fArray = False)
;
; Where: $sStartKey = Reg path at which to begin search
; $sSearchVal = The string to search for, or RegExp pattern to use if $iType bit 3 is set
; $iType = Matching types to return:
; 1 = Key names
; 2 = Value names
; 4 = Value data
; 8 = $sSearchVal is a RegExp pattern (default is StringInStr)
; Add bits together for multiple match types, default is 7 (all types, StringInStr matching)
; $fArray = Return an array of results vice the string ([0] = count)
;
; Return value: On success, returns a string containing a @LF delimited list of matching key names and values:
; Where a key name matches, it is listed as a reg path with trailing backslash:
; i.e. HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\
; Where a value name matches, it is listed as a reg path without trailing backslash:
; i.e. HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WallPaperDir
; Where the data matches, the format is path = data:
; i.e. HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WallPaperDir = %SystemRoot%\Web\Wallpaper
; On failure, returns 0 and sets @error.
;
; Notes: No matches is not an error, returns "" or an array with [0] = 0 depending on $fArray
; Default StringInStr() matches are not case sensitive.
;*****************************************************
; Change Log:
; v1.0.0.0 | 03/17/05 | Original SearchReg() by Holger
; v2.0.0.0 | 08/10/06 | Native AutoIt version by PsaltyDS
; v2.0.0.1 | 08/16/06 | Fixed bug reported by markloman
; v2.0.1.0 | 07/30/08 | Added $iType and $fArray parameters
; v2.0.2.0 | 11/12/08 | Fixed bug returning array [0] = 1 vice 0 for none found
; v2.0.3.0 | 06/22/10 | Fixed bug appending some result strings together reported by squid808
; v2.1.0.0 | 06/23/10 | Added $iType option for RegExp patterns, and pseudo wildcard "*"
;*****************************************************
Func _RegSearch
($sStartKey, $sSearchVal, $iType = 0x07, $fArray = False)
Local $v, $sVal, $k, $sKey, $sFound = "", $sFoundSub = "", $avFound[1] = [0]
; Trim trailing backslash, if present
If StringRight($sStartKey, 1) = "\" Then $sStartKey = StringTrimRight($sStartKey, 1)
; Generate type flags
If Not BitAND($iType, 0x07) Then Return SetError(1, 0, 0); No returns selected
Local $fKeys = BitAND($iType, 0x1), $fValue = BitAND($iType, 0x2), $fData = BitAND($iType, 0x4), $fRegExp = BitAND($iType, 0x8)
; Check for wildcard
If (Not $fRegExp) And ($sSearchVal == "*") Then
; Use RegExp pattern "." to match anything
$iType += 0x8
$fRegExp = 0x8
$sSearchVal = "."
EndIf
; This checks values and data in the current key
If ($fValue Or $fData) Then
$v = 1
While 1
$sVal = RegEnumVal($sStartKey, $v)
If @error = 0 Then
; Valid value - test its name
If $fValue Then
If $fRegExp Then
If StringRegExp($sVal, $sSearchVal, 0) Then $sFound &= $sStartKey & "\" & $sVal & @LF
Else
If StringInStr($sVal, $sSearchVal) Then $sFound &= $sStartKey & "\" & $sVal & @LF
EndIf
EndIf
; test its data
If $fData Then
$readval = RegRead($sStartKey, $sVal)
If $fRegExp Then
If StringRegExp($readval, $sSearchVal, 0) Then $sFound &= $sStartKey & "\" & $sVal & " = " & $readval & @LF
Else
If StringInStr($readval, $sSearchVal) Then $sFound &= $sStartKey & "\" & $sVal & " = " & $readval & @LF
EndIf
EndIf
$v += 1
Else
; No more values here
ExitLoop
EndIf
WEnd
EndIf
; This loop checks subkeys
$k = 1
While 1
$sKey = RegEnumKey($sStartKey, $k)
If @error = 0 Then
; Valid key - test it's name
If $fKeys Then
If $fRegExp Then
If StringRegExp($sKey, $sSearchVal, 0) Then $sFound &= $sStartKey & "\" & $sKey & "\" & @LF
Else
If StringInStr($sKey, $sSearchVal) Then $sFound &= $sStartKey & "\" & $sKey & "\" & @LF
EndIf
EndIf
; Now search it
$sFoundSub = _RegSearch
($sStartKey & "\" & $sKey, $sSearchVal, $iType, False) ; use string mode to test sub keys
If $sFoundSub <> "" Then $sFound &= $sFoundSub & @LF
Else
; No more keys here
ExitLoop
EndIf
$k += 1
WEnd
; Return results
If StringRight($sFound, 1) = @LF Then $sFound = StringTrimRight($sFound, 1)
If $fArray Then
If StringStripWS($sFound, 8) <> "" Then $avFound = StringSplit($sFound, @LF)
Return $avFound
Else
Return $sFound
EndIf
EndFunc ;==>_RegSearch