amin84 Posted August 12, 2010 Posted August 12, 2010 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. expandcollapse popup;#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>
FlyinRiz Posted August 12, 2010 Posted August 12, 2010 (edited) 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 August 12, 2010 by FlyinRiz
amin84 Posted August 12, 2010 Author Posted August 12, 2010 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?
FlyinRiz Posted August 12, 2010 Posted August 12, 2010 (edited) 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 August 12, 2010 by FlyinRiz
amin84 Posted August 13, 2010 Author Posted August 13, 2010 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!
Danny35d Posted August 13, 2010 Posted August 13, 2010 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)OrRunWait(@ComSpec & ' /c "' & RegRead($RegPath & '\' & $RegKey, "UninstallString") & '"', @TempDir, @SW_HIDE) AutoIt Scripts:NetPrinter - Network Printer UtilityRobocopyGUI - GUI interface for M$ robocopy command line
FlyinRiz Posted August 13, 2010 Posted August 13, 2010 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
amin84 Posted August 15, 2010 Author Posted August 15, 2010 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.
amin84 Posted August 15, 2010 Author Posted August 15, 2010 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. expandcollapse popup;#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.
mdwerne Posted December 2, 2012 Posted December 2, 2012 (edited) 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 & ' /c "' & RegRead($RegPath & '' & $RegKey, "UninstallString") & '"' & $switch, @TempDir, @SW_HIDE) ProcessWaitClose($PID) Thanks for any thouights. -Mike P.S. Thanks for the code thus far, its been very helpful! Edited December 3, 2012 by mdwerne
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now