# 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

If Ive just helped you ... miracles do happen. Chimaera

##### Share on other sites

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.

√-1 2^3 ∑ π, and it was delicious!

##### 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

If Ive just helped you ... miracles do happen. Chimaera

##### Share on other sites

Yes, in here you have some useful keys:

[HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionUninstall]

[HKEY_LOCAL_MACHINESOFTWAREWow6432NodeMicrosoftWindowsCurrentVersionUninstall]

Spoiler

Paster - Main function is to paste text, but has more functions. (No longer mantained, switched to String Trigger)

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.

Firefox Profile Backup - Backup/restore previously saved profile.

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

##### Share on other sites

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

√-1 2^3 ∑ π, and it was delicious!

##### 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 #### Share this post ##### Link to post ##### 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\"

If Ive just helped you ... miracles do happen. Chimaera

##### 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.

##### 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

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

##### 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.

## 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