Jump to content
Sign in to follow this  
leomoon

Running UninstallString after checking if it exists

Recommended Posts

leomoon

Hi, I found this code by Zinthose. This code will search all installed programs for the given string and if it exists, it will return true. Now I was wondering how to make it instead of returning true, run the UninstallString one after another (RunWait). I tried n I can't figure it out.

;#include <AddRemove.au3>

    Const $SearchFor_1 = "Adobe AIR"
    Const $SearchFor_2 = "Google Toolbar for Internet Explorer"

    MsgBox(0, "Search Results", "Search for '" & $SearchFor_1 & "' AddRemove Programs entry result: " & @CRLF & _IsInstalled($SearchFor_1))
    MsgBox(0, "Search Results", "Search for '" & $SearchFor_2 & "' AddRemove Programs entry result: " & @CRLF & _IsInstalled($SearchFor_2))

#Region #include <AddRemove.au3>
    #include-once

    Func _IsInstalled($DisplayName)

        Local $i = 1

        If @OSArch = "X64" Then; Adjust for x64 process
            Local $RegPath = "\Microsoft\Windows\CurrentVersion\Uninstall"
            Local $RegRoot86 = "HKLM\SOFTWARE\Wow6432Node"
            Local $RegRoot64 = "HKLM64\SOFTWARE"
        Else; Adjust for x86 process
            Local $RegPath = "\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
            Local $RegRoot86 = "HKLM"
            Local $RegRoot64 = "HKLM64"
        EndIf

        $IsSoftwareFound = __RegBranchSearch($RegRoot86 & $RegPath, 'DisplayName', $DisplayName);   <== Search the 32 bit registry

        If $IsSoftwareFound Then Return True
        If @OSArch = "X86" Then Return False;    <== We are done if OS Arch is x86

        ;## If we are here then the current OS Arch is 64 bit and the script is running as a 32 bit process.

        $IsSoftwareFound = __RegBranchSearch($RegRoot64 & $RegPath, 'DisplayName', $DisplayName);   <== Search the 64 bit registry

        If $IsSoftwareFound Then Return True
        Return False
    EndFunc   ;==>_IsInstalled

    #Region Internal Use Only
        Func __RegBranchSearch($RegPath, $RegName, $RegValue)
            Local $RegKey, $ThisRegValue
            Local $i = 1

            Do
                $RegKey = RegEnumKey($RegPath, $i)
                If @error <> 0 Then ExitLoop

                $ThisRegValue = RegRead($RegPath & '\' & $RegKey, $RegName)

                If StringInStr($ThisRegValue, $RegValue) <> 0 Then Return True

                $i += 1
            Until @error <> 0
            Return False
        EndFunc
    #EndRegion Internal Use Only
#EndRegion #include <AddRemove.au3>

Share this post


Link to post
Share on other sites
FlyinRiz

Instead of...

If StringInStr($ThisRegValue, $RegValue) <> 0 Then Return True

...use...

If StringInStr($ThisRegValue, $RegValue) <> 0 Then
    RunWait(RegRead($RegPath & '\' & $RegKey, "UninstallString"))
EndIf

Right?

-Aaron

Edited by FlyinRiz

Share this post


Link to post
Share on other sites
leomoon

AWESOME! Thank you. Everything is working and it's getting all the uninstall strings.

If the uninstall string is something like the code below, autoit can not run it for some reason.

RunWait('"C:\Program Files (x86)\SlySoft\AnyDVD\AnyDVD-uninst.exe" /D="C:\Program Files (x86)\SlySoft\AnyDVD"')

I tried using RunWait and _RunDOS. None of them can run strings like above. I pasted the string directly in CMD and it works fine!

Anybody knows how run strings like that in AutoIt?

Share this post


Link to post
Share on other sites
FlyinRiz

AWESOME! Thank you. Everything is working and it's getting all the uninstall strings.

If the uninstall string is something like the code below, autoit can not run it for some reason.

RunWait('"C:\Program Files (x86)\SlySoft\AnyDVD\AnyDVD-uninst.exe" /D="C:\Program Files (x86)\SlySoft\AnyDVD"')

I tried using RunWait and _RunDOS. None of them can run strings like above. I pasted the string directly in CMD and it works fine!

Anybody knows how run strings like that in AutoIt?

Did you also try

RunWait(@ComSpec & " /c " & RegRead($RegPath & '\' & $RegKey, "UninstallString"))

Not sure if it's any different than the _RunDOS command, but it doesn't hurt...

EDIT:

I looked at the function and it looks like it's identical to the _RunDOS. Using the manual method above would at least let you see what the error is on the DOS window.

-Aaron

Edited by FlyinRiz

Share this post


Link to post
Share on other sites
leomoon

The new way won't work. I tested for hours. Here is what I found out.

This script will definitely find if a program is installed or not.

Windows has different kinds of uninstall strings. 4 of them works fine by just calling it and 5 of them won't work.

Here are the different kinds of uninstall strings that works by just calling it(using RunWait):

"C:\Program Files (x86)\Common Files\Adobe AIR\Versions\1.0\Resources\Adobe AIR Updater.exe" -arp:uninstall
C:\Program Files (x86)\Common Files\Adobe AIR\Versions\1.0\Resources\Adobe AIR Updater.exe -arp:uninstall
MsiExec.exe /X{A2BCA9F1-566C-4805-97D1-7FDC93386723}
RunDll32 C:\PROGRA~2\COMMON~1\INSTAL~1\PROFES~1\RunTime\10\50\Intel32\Ctor.dll,LaunchSetup "C:\Program Files (x86)\InstallShield Installation Information\{950174DD-FA73-448C-BDD3-A86B0F588EE8}\setup.exe" -l0x9  -removeonly

Here are the ones that won't work by just calling it (using RunWait):

"C:\Program Files (x86)\Foxit Software\Foxit Reader\Uninstall.exe"
C:\Program Files (x86)\Foxit Software\Foxit Reader\Uninstall.exe
"C:\Program Files (x86)\SlySoft\AnyDVD\AnyDVD-uninst.exe" /D="C:\Program Files (x86)\SlySoft\AnyDVD"
C:\PROGRA~2\Yahoo!\MESSEN~1\UNWISE.EXE /U C:\PROGRA~2\Yahoo!\MESSEN~1\INSTALL.LOG
C:\Program Files (x86)\HTML Help Workshop\setup.exe Uninstall

Never thought automating uninstall would be this hard!

Share this post


Link to post
Share on other sites
Danny35d

Like FlyinRiz said use @ComSpec.

RunWait(@ComSpec & ' /c ""C:\Program Files\SlySoft\AnyDVD\AnyDVD-uninst.exe" /D="C:\Program Files\SlySoft\AnyDVD""', @TempDir, @SW_HIDE)

Or

RunWait(@ComSpec & ' /c "' & RegRead($RegPath & '\' & $RegKey, "UninstallString") & '"', @TempDir, @SW_HIDE)

AutoIt Scripts:NetPrinter - Network Printer UtilityRobocopyGUI - GUI interface for M$ robocopy command line

Share this post


Link to post
Share on other sites
FlyinRiz

Like FlyinRiz said use @ComSpec.

RunWait(@ComSpec & ' /c ""C:\Program Files\SlySoft\AnyDVD\AnyDVD-uninst.exe" /D="C:\Program Files\SlySoft\AnyDVD""', @TempDir, @SW_HIDE)

Or

RunWait(@ComSpec & ' /c "' & RegRead($RegPath & '\' & $RegKey, "UninstallString") & '"', @TempDir, @SW_HIDE)

And if you want to actually see the string in a CMD window, get rid of the

,@SW_HIDE)

at the end.

-Aaron

Share this post


Link to post
Share on other sites
leomoon

Thanks for your replies.

I tried your commands and the one below works on most uninstall strings:

RunWait(@ComSpec & ' /c "' & RegRead($RegPath & '\' & $RegKey, "UninstallString") & '"', @TempDir, @SW_HIDE)

These strings still won't work:

C:\Program Files (x86)\ProgramName\remove.exe -LOG= C:\Program Files (x86)\ProgramName\install.log -OEM=

C:\Program Files (x86)\ProgramName\remove.exe Uninstall

I'll be testing more. If I found something, I'll post here.

Share this post


Link to post
Share on other sites
leomoon

Ok here is an updated version. Before that I'm gonna write here why I'm making this. I'm making this to use it as an automated uninstall tool. Because I setup lots of computers, and they all have preloaded applications. I want to list all the applications that I remove by hand in here and use the silent switch if it exists. This way they will be removed silently or popped up one after another which makes my life SO MUCH EASIER.

So here is the updated script. In this version I made it that if it finds " /I" replace it with " /X". That switch is usually used by MSI uninstalls and to uninstall it should be /X and the switch /passive is used to make MSI silent... I have to add more search and or replace strings with specified switch. I'll post more updates soon.

;#include <AddRemove.au3>

Const $SearchFor_1 = "Toolbar"
Const $SearchFor_2 = "ScreenSaver"

_IsInstalled($SearchFor_1)
_IsInstalled($SearchFor_2)

Func _IsInstalled($DisplayName)
    Local $i = 1
    If @OSArch = "X64" Then;Adjust for x64 process
        Local $RegPath = "\Microsoft\Windows\CurrentVersion\Uninstall"
        Local $RegRoot86 = "HKLM\SOFTWARE\Wow6432Node"
        Local $RegRoot64 = "HKLM64\SOFTWARE"
    Else;Adjust for x86 process
        Local $RegPath = "\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
        Local $RegRoot86 = "HKLM"
        Local $RegRoot64 = "HKLM64"
    EndIf
    $IsSoftwareFound = _RegBranchSearch($RegRoot86 & $RegPath, 'DisplayName', $DisplayName);   <== Search the 32 bit registry
    If $IsSoftwareFound Then Return True
    If @OSArch = "X86" Then Return False;    <== We are done if OS Arch is x86
    ;## If we are here then the current OS Arch is 64 bit and the script is running as a 32 bit process.
    $IsSoftwareFound = _RegBranchSearch($RegRoot64 & $RegPath, 'DisplayName', $DisplayName);   <== Search the 64 bit registry
    If $IsSoftwareFound Then Return True
    Return False
EndFunc   ;==>_IsInstalled

Func _RegBranchSearch($RegPath, $RegName, $RegValue)
    Local $RegKey, $ThisRegValue
    Local $i = 1
    Do
        $RegKey = RegEnumKey($RegPath, $i)
        If @error <> 0 Then ExitLoop
        $ThisRegValue = RegRead($RegPath & '\' & $RegKey, $RegName)
        If StringInStr($ThisRegValue, $RegValue) <> 0 Then
;~          $unString = RegRead($RegPath & '\' & $RegKey, "UninstallString")
;~          RunWait($unString)
;~          RunWait(@ComSpec & " /c " & RegRead($RegPath & '\' & $RegKey, 'UninstallString'))
;~          RunWait(@ComSpec & ' /c "' & RegRead($RegPath & '\' & $RegKey, "UninstallString"&" /S /s /q /qb /x /Silent /passive") & '"', @TempDir, @SW_HIDE)
;~          RunWait(@ComSpec & ' /c "' & RegRead($RegPath & '\' & $RegKey, "UninstallString") & '"'&" /x /S /s /Silent /q /qb /qn /quiet /passive /NORESTART /NoUserInput /unattended", @TempDir, @SW_HIDE)
            $uninstallString = RegRead($RegPath & '\' & $RegKey, "UninstallString")
            If StringInStr($uninstallString, " /I") <> 0 Then
                $uninstallString = StringReplace($uninstallString, " /I", " /X")
                $switch = " /passive"
            Else
                $switch = " /S /s /q /qb /x /Silent /passive"
            EndIf
            MsgBox(0, "", @ComSpec & ' /c "' & RegRead($RegPath & '\' & $RegKey, "UninstallString") & '"'&$switch, @TempDir, @SW_HIDE)
        EndIf
        $i += 1
    Until @error <> 0
    Return False
EndFunc

Any suggestions are welcome. ;)

Share this post


Link to post
Share on other sites
mdwerne

The code above works very well, except that in some cases it runs the uninstalls in parallel instead of in series. The comsec calls the uninstaller and then it seems that another process is spawned. Here is my uninstall string, any idea how to get a handle on the spawned uninstall process so I can wait for it to complete before starting the next uninstaller?

Local $PID = RunWait(@ComSpec &amp; ' /c "' &amp; RegRead($RegPath &amp; '' &amp; $RegKey, "UninstallString") &amp; '"' &amp; $switch, @TempDir, @SW_HIDE)
ProcessWaitClose($PID)

Thanks for any thouights.

-Mike

P.S. Thanks for the code thus far, its been very helpful!

Edited by mdwerne

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  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.