Jump to content

Working with different uninstallers is getting really complicated


Recommended Posts

So is there a better solution to the problem?

Ive been throwing together some code for a multiple uninstaller, which started simply enough but is getting out of control rapidly.

The problem stems from having different types of uninstallers like this

Local $sProgramString = ""
$sProgramString = "|C:\Program Files\Program1\uninstall.exe|C:\Program Files (x86)\Program2\uninstall.exe|C:\Program Files (x86)\Program3\uninstall.exe|C:\Program Files (x86)\Program4\ExtCapUninstall\hpzscr01.exe|C:\Program Files (x86)\Program5\uninstal.exe|C:\PROGRA~1\Program6\bar\1.bin\mwsbar.dll

Which starts them fine but then i ran across MSI and other types with switches so i added this

Local $aProgramArray = StringSplit($sProgramString, "|")

For $i = 0 To UBound($aProgramArray) - 1
    If FileExists($aProgramArray[$i]) Then
        Local $UninCheck = $aProgramArray[$i]

        Select
            Case $UninCheck = "C:\Program Files (x86)\Program4\ExtCapUninstall\hpzscr01.exe" 
                ShellExecuteWait('C:\Program Files (x86)\Program4\ExtCapUninstall\hpzscr01.exe', '-datfile hpqhsc01.dat')
                Sleep(1000)

And these

Case $UninCheck = 'C:\Program Files (x86)\Program5\uninstal.exe'
                ShellExecuteWait('MsiExec.exe', '/X{C28D96C0-6A90-459E-A077-A6706F4EC0FC} /qb')
                Sleep(1000)

And these

Case $UninCheck = "C:\PROGRA~1\Program6\bar\1.bin\mwsbar.dll" 
                ShellExecuteWait('rundll32', 'C:\PROGRA~1\Program6\bar\1.bin\mwsbar.dll,O')
                Sleep(1000

And to close it off

Case Else
                ShellExecuteWait($aProgramArray[$i], "")
                Sleep(1000)
        EndSelect
    Else
        ContinueLoop
    EndIf
Next

Obviously i have to have the program in the top array as well as an individual Case just in case it has switches or msi etc

One problem i have also noticed is that sometimes it opens multiple ones at the same time which i was using the shellexecute wait to control... i guess the program opening cancels the wait?

So is there an easier way to manage this stuff than im doing it already? And i would like some way of trigger the program name in and error msg when it fails on an uninstaller

All it does is run them one after another until there is no more on that machine

Edited by Chimaera
Link to comment
Share on other sites

  • Moderators

Have you thought about using the registry? Loop through the HKLMSOFTWAREMicrosoftWindowsCurrentVersionUninstall key, checking the DisplayName value. If it matches what you're wanting to uninstall, read the UninstallString or QuietUninstallString value in that subkey, and use that as the parameters for a RunWait line.

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

Ok thanks ill have a look into that

The Quiet one seems to already have the switches set (when available)

Im sure i saw a find in registry type of code somewhere so ill have a look

Link to comment
Share on other sites

Yes, in here you have some useful keys:

[HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionUninstall]

[HKEY_LOCAL_MACHINESOFTWAREWow6432NodeMicrosoftWindowsCurrentVersionUninstall]
 

Spoiler

Renamer - Rename files and folders, remove portions of text from the filename etc.

GPO Tool - Export/Import Group policy settings.

MirrorDir - Synchronize/Backup/Mirror Folders

BeatsPlayer - Music player.

Params Tool - Right click an exe to see it's parameters or execute them.

String Trigger - Triggers pasting text or applications or internet links on specific strings.

Inconspicuous - Hide files in plain sight, not fully encrypted.

Regedit Control - Registry browsing history, quickly jump into any saved key.

Time4Shutdown - Write the time for shutdown in minutes.

Power Profiles Tool - Set a profile as active, delete, duplicate, export and import.

Finished Task Shutdown - Shuts down pc when specified window/Wndl/process closes.

NetworkSpeedShutdown - Shuts down pc if download speed goes under "X" Kb/s.

IUIAutomation - Topic with framework and examples

Au3Record.exe

Link to comment
Share on other sites

  • Moderators

You could also skip the registry altogether and go with WMI:

#include <MsgBoxConstants.au3>

$wbemFlagReturnImmediately = 0x10
$wbemFlagForwardOnly = 0x20

$sName = InputBox("App Uninstall", "Please enter the product name")
$WMI = ObjGet("winmgmts:\\" & @ComputerName & "\root\CIMV2")
$aItems = $WMI.ExecQuery("SELECT * FROM Win32_Product", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)

For $product In $aItems
    If StringInStr($product.Name, $sName) Then$
          uninst = MsgBox($MB_YESNO, $product.Name, "Would you like to uninstall?")
            If $uninst = $IDYES Then $product.Uninstall
    EndIf
Next

With a slight tweak (and the proper access of course) this works for remote machines as well.

Edited by JLogan3o13

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

Here is what I use

$Log ="C:\Script.log"
_FileWriteLog ($Log, "Log Started")

If @OSArch = "X86" Then
   $Keyroot = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";uninstall keyroot for X86 machines
   _FileWriteLog ($Log, "This is a 32bit machine")
EndIf

If @OSArch = "X64" Then
   $Keyroot = "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall";uninstall keyroot for X64 machines
    _FileWriteLog ($Log, "This is a 64bit machine")
   EndIf



;Uninstall Routine
_FileWriteLog ($Log, "Searching for previous installations")
SplashTextOn ("", "Searching for Software",300,50,-1,-1,1); shows text
Sleep (1500);wait, showing text



$index = 1
$subkey = "***START***"; we use this because "" will make our While loop exit
While $subkey <> ""
    $subkey = RegEnumKey($keyroot, $index)
    If StringInStr(RegRead($keyroot & "\" & $subkey, "DisplayName"), _
    "NAME HERE") Then
        $GUID = $subkey  ; Record the GUID
        $subkey = ""    ; Force the While to exit
     Else
        $GUID = ""
    EndIf
    $index = $index + 1
 WEnd
 SplashOff(); text off





If $GUID <> "" Then; if GUID is found
   _FileWriteLog ($Log, "Already Installed")
SplashTextOn ("", "Found Successfully",300,50,-1,-1,1); show text
Sleep (1500); wait with text
SplashTextOn ("", "Uninstalling",300,50,-1,-1,1); text on

_FileWriteLog ($Log, "Uninstalling....")
RunWait ("MsiExec.exe /x" & $GUID & " /quiet"); run uninstaller
_FileWriteLog ($Log, "Uninstall Finished")
SplashOff(); text off
Else
   SplashTextOn ("", "Not Installed",300,50,-1,-1,1); show text
   _FileWriteLog ($Log, "Not Previously Installed")
   Sleep (1500); wait with text
   SplashOff()
   EndIf
Link to comment
Share on other sites

@JLogan3o13 i tried that but it would find somethings but not others, CCleaner was a deffo it couldnt get, strange but thanks anyway. It was good as all i needed was the name in control panel which saves work

@wisem2540 that ran but only gave 4 lines on the log with no uninstall files did i miss something?

I think im going to have to try and rethink how i started as the uninstall keys i have are valid just need a simpler way to run them

Just for info these are the main keys for all uninstallers

$path_1 = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall\"
$path_2 = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\"
$path_3 = "HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\"
$path_4 = "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\"
$path_5 = "HKCU64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\"
Link to comment
Share on other sites

Chimaera,

Did you change the display name to match the app you are trying to uninstall?  Did the log say it found the app?  If so, the uninstall string is wrong.  If not the display name is wrong..

Either way, look at the regkey....

See this line?

RunWait ("MsiExec.exe /x" & $GUID & " /quiet"); run uninstaller

 Make sure this is the uninstall string from the regkey.  You may want to do a regread and capture it once the guid is returned.  Let me know if I can help.
 

Link to comment
Share on other sites

 

try my script in the spoiler there, ive had some installers without a "quiet" option and some without an uninstallkey entry, but those were few.

Edited by boththose

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

Link to comment
Share on other sites

Unfortunately, there are as many uninstallers as there are installers, so you will probably have to have more than one method.  WMI is the most universal method, but there are sometimes apps that don't register themselves properly to uninstall that way, and it tends to be slower in my experience.  For my uninstallers, I use the following order:

1. Scan the registry for QuietUninstallString strings, then for UninstallString.

2. Check if it can be removed using WMI

3. Use a custom uninstaller for that app (only known apps, obviously)

As far as not waiting for uninstall to complete before proceeding, some unistallers will launch other processes to do the uninstall work, then close the main process.  The only way around that, that I have found is to find some key file that the uninstaller will remove, and use While FileExists(file) to wait for it.  This works best with method #1, since there is often (though not always) an executable name somewhere in the same registry key.

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...