Sign in to follow this  
Followers 0
engjcowi

Basic Uninstall assistance [SOLVED]

18 posts in this topic

#1 ·  Posted (edited)

Hi guys i need some help if someone would oblige.

I am using this small code below to make a very basic uninstaller. It displays everything thats installed with no problems however under the uninstall string field it shows some strings with " " around them and others without. The strings with " " around them, when i right click and select uninstall they work with no issue but the ones without the quotes come up with an error.

can anyone help please? im using a 64bit of windows 7 and wondering if thats whats causing the issue.

i originally go this script from here -

thanks in advance

jamie

#include <GuiListView.au3>
;Opt("TrayAutoPause", 0)
Opt('GUIOnEventMode', 1)
Opt('GUICloseOnEsc' , 1)
 
Global $i
Local $JamLVitem
Global $sGui = GUICreate('Currently Installed Software', 810, 650, -1, -1)
Global $jamUninsLvw = GUICtrlCreateListView('#|Installed Software|Display Version|Publisher|Uninstall String', 5, 5, 800, 600)
_ComputerGetSoftwareuninst($JamLVitem)
 
For $i = 1 To ubound($JamLVitem) - 1
    GUICtrlCreateListViewItem($i & '|' & $JamLVitem[$i][0] & '|' & $JamLVitem[$i][1] & '|' & $JamLVitem[$i][2] & '|' & $JamLVitem[$i][3], $jamUninsLvw)
Next
;GUICtrlSendMsg($jamUninsLvw, 0x101E, 1, 175)
;GUICtrlSendMsg($jamUninsLvw, 0x101E, 2, 65)
;GUICtrlSendMsg($jamUninsLvw, 0x101E, 3, 150)
;GUICtrlSendMsg($jamUninsLvw, 0x101E, 4, 350)
Local $mMen = GUICtrlCreateContextMenu($jamUninsLvw)
Local $CopI = GUICtrlCreateMenuItem('Uninstall Current Selection', $mMen)
GUICtrlSetOnEvent($CopI, '_Uninstall')
Local $exp = GUICtrlCreateButton('  Expand  ', 720, 615)
;GUICtrlSetOnEvent($exp, '_Expand')
GUISetOnEvent(-3, '_AllExit')
_GUICtrlListView_SetColumnWidth($jamUninsLvw, 1, $LVSCW_AUTOSIZE)
    _GUICtrlListView_SetColumnWidth($jamUninsLvw, 2, $LVSCW_AUTOSIZE)
    _GUICtrlListView_SetColumnWidth($jamUninsLvw, 3, $LVSCW_AUTOSIZE)
    _GUICtrlListView_SetColumnWidth($jamUninsLvw, 4, $LVSCW_AUTOSIZE)
GUISetState(@SW_SHOW, $sGui)
 
While 1
    Sleep(10)
WEnd
;
Func _AllExit()
    GUIDelete($sGui)
    Exit
EndFunc
;
Func _Uninstall()
    Local $proc = StringSplit(GUICtrlRead(GUICtrlRead($jamUninsLvw)), '|', 1)
    If $proc[1] == 0 Then Return -1
    If $proc[5] Then ShellExecuteWait ($proc[5])
       ; exit
  
EndFunc
;
Func _Copy2Clip()
    Local $proc = StringSplit(GUICtrlRead(GUICtrlRead($jamUninsLvw)), '|', 1)
    If $proc[1] == 0 Then Return -1
    If $proc[5] Then ClipPut($proc[5])
EndFunc
;
; Author JSThePatriot - Modified June 20, 2010 by ripdad
Func _ComputerGetSoftwareuninst(ByRef $aSoftwareInfoUninstbasic)
    Local Const $UnInstKey = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
    Local $i = 1
    Dim $aSoftwareInfoUninstbasic[1][4]
    $input = "ALL";inputbox ("Which Software" , "You are running " & @OSVersion & " " & @OSARCH & @CRLF & @CRLF & "Which Software would you like to view?", 'ALL')
    If @Error = 1 Then Exit
    If $input = 'ALL' Then
    For $j = 1 To 500
        $AppKey = RegEnumKey($UnInstKey, $j)
        If @error <> 0 Then Exitloop
        If RegRead($UnInstKey & "\" & $AppKey, "DisplayName") = '' Then ContinueLoop
        ReDim $aSoftwareInfoUninstbasic[UBound($aSoftwareInfoUninstbasic) + 1][4]
        $aSoftwareInfoUninstbasic[$i][0] = StringStripWS(StringReplace(RegRead($UnInstKey & "\" & $AppKey, "DisplayName"), " (remove only)", ""), 3)
        $aSoftwareInfoUninstbasic[$i][1] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "DisplayVersion"), 3)
        $aSoftwareInfoUninstbasic[$i][2] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "Publisher"), 3)
        $aSoftwareInfoUninstbasic[$i][3] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "UninstallString"), 3)
        $i = $i + 1
    Next
    $aSoftwareInfoUninstbasic[0][0] = UBound($aSoftwareInfoUninstbasic, 1) - 1
    If $aSoftwareInfoUninstbasic[0][0] < 1 Then SetError(1, 1, 0)
MsgBox(4096,"tt",$aSoftwareInfoUninstbasic[0][0] )
    Return _ArraySort($aSoftwareInfoUninstbasic)
Else
    For $j = 1 To 500
        $AppKey = RegEnumKey($UnInstKey, $j)
        If @error <> 0 Then Exitloop
        $Reg = RegRead($UnInstKey & "\" & $AppKey, "DisplayName")
        $string = stringinstr($Reg, $input)
        If $string = 0 Then Continueloop
        ReDim $aSoftwareInfoUninstbasic[UBound($aSoftwareInfoUninstbasic) + 1][4]
        $aSoftwareInfoUninstbasic[$i][0] = StringStripWS(StringReplace(RegRead($UnInstKey & "\" & $AppKey, "DisplayName"), " (remove only)", ""), 3)
        $aSoftwareInfoUninstbasic[$i][1] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "DisplayVersion"), 3)
        $aSoftwareInfoUninstbasic[$i][2] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "Publisher"), 3)
        $aSoftwareInfoUninstbasic[$i][3] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "UninstallString"), 3)
        $i = $i + 1
    Next
    $aSoftwareInfoUninstbasic[0][0] = UBound($aSoftwareInfoUninstbasic, 1) - 1
    If $aSoftwareInfoUninstbasic[0][0] < 1 Then SetError(1, 1, 0)
    Return _ArraySort($aSoftwareInfoUninstbasic)
    Endif
EndFunc
;
Func _Expand()
EndFunc
Edited by engjcowi

Drunken Frat-Boy Monkey Garbage

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

in the _ComputerGetSoftware(). This should add quotes to the keys that do not have them.

...... $aSoftwareInfo[$i][0] = StringStripWS(StringReplace(RegRead($UnInstKey & "\" & $AppKey, "DisplayName"), " (remove only)", ""), 3)
        $aSoftwareInfo[$i][1] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "DisplayVersion"), 3)
        $aSoftwareInfo[$i][2] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "Publisher"), 3)
        $aSoftwareInfo[$i][3] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "UninstallString"), 3)
       If stringleft ($aSoftwareInfo[$i][3] , 1) <> '"' Then
           $aSoftwareInfo[$i][3] = '"' & $aSoftwareInfo[$i][3] & '"'
         Endif
        $i = $i + 1....
Edited by boththose

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites

in the _ComputerGetSoftware(). This should add quotes to the keys that do not have them.

Did you test that before and after with a relevant install? Whatever, I'll post my try, and have egg in my face if yours was enough... :graduated:

@engjcowi

I just took a stab at the ask toolbar i apparently had on this puter... not mine.

and this ---> MsiExec.exe /X{86D4B82A-ABED-442A-BE86-96357B70F4FE}

didnt work.

putting a space after the x, did... though windows installer asked me if I was sure, without showing me what I was uninstalling... Some switch should be added and the question be put by the script instead, or notatall...


Yes i rush things! (I sorta do small bursts inbetween doing nothing.) Things I have rushed and reRushed:* ProDLLer - Process manager - Unload viri modules (dll) and moore...* _WinAPI_ProcessListOWNER_WTS() - Get Processes owner list...* _WinAPI_GetCommandLineFromPID() - Get commandline of target process...* _WinAPI_ThreadsnProcesses() Much info if expanded - optional Indented "Parent/Child"-style Processlist. Moore to come... eventually...

Share this post


Link to post
Share on other sites

If I try to uninstall the orbicam... I get this:

RunDll32 C:\Program\DELADE~1\INSTAL~1\PROFES~1\RunTime\09\01\Intel32\Ctor.dll,LaunchSetup "C:\Program\InstallShield Installation Information\{76AC1AEB-1167-4ABC-8861-4E58392A5B7F}\setup.exe" -l0x1d

It doesn't work... I looked at _Uninstall() function it uses ShellExecuteWait which wants "parameters" separate... this causes problems... I tried runwait and uninstall worked for all cases i tried. no problem with space after /x or "" around strings...


Yes i rush things! (I sorta do small bursts inbetween doing nothing.) Things I have rushed and reRushed:* ProDLLer - Process manager - Unload viri modules (dll) and moore...* _WinAPI_ProcessListOWNER_WTS() - Get Processes owner list...* _WinAPI_GetCommandLineFromPID() - Get commandline of target process...* _WinAPI_ThreadsnProcesses() Much info if expanded - optional Indented "Parent/Child"-style Processlist. Moore to come... eventually...

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Did you test that before and after with a relevant install?

Nope, didnt even try and guess what was going wrong. Figured if quotes were added, and it still failed, then at least the OP could eliminate them as the culprit.

The runwait indeed works, and i will adjust the script in the thread he references accordingly. -- Though where I got those pieces from still eludes me.

Edited by boththose

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites

@boththose: Ha! Sorry, never followed that link... well, I just ran the script on my win7 x32 laptop, and it doesnt show all installed software... (Not SO many since win7 was quite recently installed so I could test in win7...) Haven't looked into it. Just wanted to give a headsup about it...

/Manko


Yes i rush things! (I sorta do small bursts inbetween doing nothing.) Things I have rushed and reRushed:* ProDLLer - Process manager - Unload viri modules (dll) and moore...* _WinAPI_ProcessListOWNER_WTS() - Get Processes owner list...* _WinAPI_GetCommandLineFromPID() - Get commandline of target process...* _WinAPI_ThreadsnProcesses() Much info if expanded - optional Indented "Parent/Child"-style Processlist. Moore to come... eventually...

Share this post


Link to post
Share on other sites

Hi guys

Thanks the change of shellexecutewait to runwait has done the trick. cant beleive i missed that. guess ive been starting at the code for too long lol

jamie


Drunken Frat-Boy Monkey Garbage

Share this post


Link to post
Share on other sites

Yeah a couple of folks noticed the issue with it not returning 7-zip at the top of list, but I hadnt noticed any other items in the uninstall key that dont display. You have any specific examples I can try?


,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites

As I'm at work, I could not fully reproduce the omissions... But I found one.

And the explanation is that you need to also scan the same path under HKEY_CURRENT_USER.

This might have been the explanation for all the omissions at home too... will check tonight.

Perhaps one should scan under all users, but the above is minimum...

/Manko


Yes i rush things! (I sorta do small bursts inbetween doing nothing.) Things I have rushed and reRushed:* ProDLLer - Process manager - Unload viri modules (dll) and moore...* _WinAPI_ProcessListOWNER_WTS() - Get Processes owner list...* _WinAPI_GetCommandLineFromPID() - Get commandline of target process...* _WinAPI_ThreadsnProcesses() Much info if expanded - optional Indented "Parent/Child"-style Processlist. Moore to come... eventually...

Share this post


Link to post
Share on other sites

If you going after all possible uninstalls

Then you need to check these keys from some work on a similar thread ive been helped with

"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall"

"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"

"HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"

"HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"

Is there a way to make the above script check them all?

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

@chimaera: Yes, ofcourse. I think you could do it. I believe in you!

@boththose: Also I found case like 7-zip. "µTorrent" is in regpath in script, but isn't displayed... or was 7-zip just a sorting thing?

[EDIT: below...]

The problem with 7-zip and "µTorrent" is in the arraysort-call, the $aSoftwareInfo[0] that contains number of items is sorted too.

Sollution: Change this:

Return _ArraySort($aSoftwareInfo)

into this:

Return _ArraySort($aSoftwareInfo,0,1) ; sort from $aSoftwareInfo[1]

/Manko

Edited by Manko

Yes i rush things! (I sorta do small bursts inbetween doing nothing.) Things I have rushed and reRushed:* ProDLLer - Process manager - Unload viri modules (dll) and moore...* _WinAPI_ProcessListOWNER_WTS() - Get Processes owner list...* _WinAPI_GetCommandLineFromPID() - Get commandline of target process...* _WinAPI_ThreadsnProcesses() Much info if expanded - optional Indented "Parent/Child"-style Processlist. Moore to come... eventually...

Share this post


Link to post
Share on other sites

thanks manko, i updated my original effort in case anybody stumbles upon it.


,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites

Hey guys

Heres an addition to the script that will show more if not hopefully all the uninstall keys. Im pretty sure that the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall location will show the same as the "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" location.

With the function below i get all the uninstall keys on my comp which is 64bit win 7.

Just add the function to the original code.

Thanks

; Author JSThePatriot - Modified June 20, 2010 by ripdad
Func _ComputerGetSoftware(ByRef $aSoftwareInfo)
    Local $UnInstKey = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
    Local $i = 1
    Dim $aSoftwareInfo[1][4]
    $input = inputbox ("Which Software" , "You are running " & @OSVersion & " " & @OSARCH & @CRLF & @CRLF & "Which Software would you like to view?", 'ALL')
    If @Error = 1 Then Exit
    If $input = 'ALL' Then
    For $j = 1 To 500
        $AppKey = RegEnumKey($UnInstKey, $j)
        If @error <> 0 Then Exitloop
        If RegRead($UnInstKey & "\" & $AppKey, "DisplayName") = '' Then ContinueLoop
        ReDim $aSoftwareInfo[UBound($aSoftwareInfo) + 1][4]
        $aSoftwareInfo[$i][0] = StringStripWS(StringReplace(RegRead($UnInstKey & "\" & $AppKey, "DisplayName"), " (remove only)", ""), 3)
        $aSoftwareInfo[$i][1] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "DisplayVersion"), 3)
        $aSoftwareInfo[$i][2] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "Publisher"), 3)
        $aSoftwareInfo[$i][3] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "UninstallString"), 3)
        $i = $i + 1
    Next
 ;delete from here
 Local $UnInstKey = "HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
 ;Local $UnInstKey = "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
 For $j = 1 To 500
        $AppKey = RegEnumKey($UnInstKey, $j)
        If @error <> 0 Then Exitloop
        If RegRead($UnInstKey & "\" & $AppKey, "DisplayName") = '' Then ContinueLoop
        ReDim $aSoftwareInfo[UBound($aSoftwareInfo) + 1][4]
        $aSoftwareInfo[$i][0] = StringStripWS(StringReplace(RegRead($UnInstKey & "\" & $AppKey, "DisplayName"), " (remove only)", ""), 3)
        $aSoftwareInfo[$i][1] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "DisplayVersion"), 3)
        $aSoftwareInfo[$i][2] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "Publisher"), 3)
        $aSoftwareInfo[$i][3] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "UninstallString"), 3)
        $i = $i + 1
    Next
 ;to here
    $aSoftwareInfo[0][0] = UBound($aSoftwareInfo, 1) - 1
    If $aSoftwareInfo[0][0] < 1 Then SetError(1, 1, 0)
    Return _ArraySort($aSoftwareInfo,0,1)
Else
    For $j = 1 To 500
        $AppKey = RegEnumKey($UnInstKey, $j)
        If @error <> 0 Then Exitloop
        $Reg = RegRead($UnInstKey & "\" & $AppKey, "DisplayName")
        $string = stringinstr($Reg, $input)
        If $string = 0 Then Continueloop
        ReDim $aSoftwareInfo[UBound($aSoftwareInfo) + 1][4]
        $aSoftwareInfo[$i][0] = StringStripWS(StringReplace(RegRead($UnInstKey & "\" & $AppKey, "DisplayName"), " (remove only)", ""), 3)
        $aSoftwareInfo[$i][1] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "DisplayVersion"), 3)
        $aSoftwareInfo[$i][2] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "Publisher"), 3)
        $aSoftwareInfo[$i][3] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "UninstallString"), 3)
        $i = $i + 1
    Next
    $aSoftwareInfo[0][0] = UBound($aSoftwareInfo, 1) - 1
    If $aSoftwareInfo[0][0] < 1 Then SetError(1, 1, 0)
    Return _ArraySort($aSoftwareInfo,0,1)
    Endif
EndFunc

Drunken Frat-Boy Monkey Garbage

Share this post


Link to post
Share on other sites

on an x86 (XP SP3) that results in duplicate entries for everybody unless I put it in an if statement. I suppose that the path's existence should be confirmed first on the original as well.

If RegRead ("HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" , "") Then
Local $UnInstKey = "HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
 ;Local $UnInstKey = "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
 For $j = 1 To 500
        $AppKey = RegEnumKey($UnInstKey, $j)
        If @error <> 0 Then Exitloop
        If RegRead($UnInstKey & "\" & $AppKey, "DisplayName") = '' Then ContinueLoop
        ReDim $aSoftwareInfo[UBound($aSoftwareInfo) + 1][4]
        $aSoftwareInfo[$i][0] = StringStripWS(StringReplace(RegRead($UnInstKey & "\" & $AppKey, "DisplayName"), " (remove only)", ""), 3)
        $aSoftwareInfo[$i][1] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "DisplayVersion"), 3)
        $aSoftwareInfo[$i][2] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "Publisher"), 3)
        $aSoftwareInfo[$i][3] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "UninstallString"), 3)
        $i = $i + 1
    Next
 ;to here
 Endif

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites

Im trying to go a different path just to throw a spanner in the works

Global $soft = "\CCleaner"
Global $sValue = "InstallLocation", $sValue1 = "UninstallString"
Global $sUninstallKey_1 = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall" & $soft
Global $sUninstallKey_2 = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" & $soft
Global $sUninstallKey_3 = "HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" & $soft
Global $sUninstallKey_4 = "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" & $soft
Global $sUninstallKey_5 = "" ;< user defined key..
 
 
If _IsRegistryExist($sUninstallKey_1, $sValue) = 1 Or _IsRegistryExist($sUninstallKey_1, $sValue1) = 1 Then
If _IsRegistryExist($sUninstallKey_1, $sValue) = 1 Then
  $sValName = $sValue
Else
  $sValName = $sValue1
EndIf
$aUninstallKeys = _RegSearch($sUninstallKey_1, $sValName, 2, True)
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)
  $sInstallLocation = $aUninstallStrings[$n][1]
Next
ElseIf ; next statement upto 5 times
 
;<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>
Func _IsRegistryExist($sKeyName, $sValueName); 0 = Doesn't Exist / 1 = Exists [Author guinness]
    RegRead($sKeyName, $sValueName)
    Return Number(@error = 0)
EndFunc   ;==>_IsRegistryExist
;<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>

Is there a way to simplify this section

If _IsRegistryExist($sUninstallKey_1, $sValue) = 1 Or _IsRegistryExist($sUninstallKey_1, $sValue1) = 1 Then
If _IsRegistryExist($sUninstallKey_1, $sValue) = 1 Then
  $sValName = $sValue
Else
  $sValName = $sValue1
EndIf
$aUninstallKeys = _RegSearch($sUninstallKey_1, $sValName, 2, True)
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)
  $sInstallLocation = $aUninstallStrings[$n][1]
Next
ElseIf ; next statement upto 5 times

Or a way to make it read $svalue against all the keys then $sValue1 against all the keys?

and then decide which is actually there?

because InstallLocation is not always present in the registry

Share this post


Link to post
Share on other sites

Ahhh cool. I like both ways lol. Ive not got xp or 32 bit system to test on at the moment but i like the check for the existence of the reg locations first. Hopefully we will get a nice complete knocked up between us :D


Drunken Frat-Boy Monkey Garbage

Share this post


Link to post
Share on other sites

even all 4 keys doesn't guarantee success some keys like addons for firefox are held elswehere in the registry

Ive just rewritten a new try and im testing atm more to come

Share this post


Link to post
Share on other sites

Ok here is the code hope you like it

Thx to all that helped especially guinness, Geosoft and PsaltyDS.

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

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 \) to give path

UninstallString Generally available ( deducts from end of string back and including first \) to give path

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

Lemme know if you have any thoughts

#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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0