damon Posted April 26, 2010 Posted April 26, 2010 I have built an installer for a crap load of software and it works good, I have built an uninstaller to remove this same package of software. Now I present you with the problem... I have add code to the reg during the setup.exe to add my uninstaller.exe to add/remove programs. here is the code. simple regwrite(this is not the problem I just want to make sure you understand what all is going on) RegWrite ("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\BlueTooth Scanner", "DisplayName", "REG_SZ", "Bluetooth Scanner Software Package (REMOVE ONLY)") RegWrite ("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\BlueTooth Scanner", "UninstallString", "REG_SZ", "C:\Temp\Scanner4.9.10\uninstall.exe") ;;RegWrite ("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Scanner", "URLInfoAbout", "REG_SZ", "") RegWrite ("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\BlueTooth Scanner", "DisplayIcon", "REG_SZ", "C:\Temp\Scanner4.9.10\setup.exe,0") RegWrite ("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\BlueTooth Scanner", "Publisher", "REG_SZ", "Damon Pence") RegWrite ("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\BlueTooth Scanner", "NoRepair", "REG_DWORD", "00000001") RegWrite ("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\BlueTooth Scanner", "NoModify", "REG_DWORD", "00000001") RegWrite ("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\BlueTooth Scanner", "DisplayVersion", "REG_SZ", "4.13.101") Now the Problem, The uninstall.exe(below) will run perfectly if I start it from the .exe, but when I start it from add/remove programs it will hang at the switch/case. I did have this problem in the past and had to change to an integer using int. but this is not numbers it is accually comparing words or phases i guess you would call it. expandcollapse popup#include <File.au3> If MsgBox(4, "Uninstall of BlueTooth Scanner", "Are you sure you want to Uninstall the software?") = 6 Then ;;codexml uninstall----- Only prompts for comfimation that you want to uninstall, cancel restart and OK ;;C:\WINDOWS\IsUninst.exe -f"C:\Program Files\CodeXML Router\Uninst.isu" -c"C:\Program Files\CodeXML Router\CCUninst.dll" If FileExists (@ProgramFilesDir & "\CodeXML Router\router.exe") Then $fileu1 = FileOpen (@ScriptDir & "\u1.bat",2) FileWrite ($fileu1, "C:\WINDOWS\IsUninst.exe -f""C:\Program Files\CodeXML Router\Uninst.isu"" -c""C:\Program Files\CodeXML Router\CCUninst.dll""") FileClose ($fileu1) ShellExecute (@ScriptDir & "\u1.bat") WinWaitActive ("Confirm File Deletion", "Are you sure you") ControlCommand ("Confirm File Deletion", "Are you sure you", "[Class:Button;Instance:1]", "check", "") WinWaitActive ("Restart Computer", "The system must be") ControlCommand ("Restart Computer", "The system must be", "[Class:Button;Instance:2]", "check", "") WinWaitActive ("Remove Programs From Your Computer", "unInstallShield will remove") ControlCommand ("Remove Programs From Your Computer", "unInstallShield will remove", "[Class:Button;Instance:1]", "check", "") Sleep(2000) EndIf ;;bluesoleil uninstall----- Only prompts for comfimation that you want to uninstall ;;C:\Program Files\IVT Corporation\BlueSoleil\ ;;MsiExec.exe /X{438BB9B4-65FE-4626-91D9-A8F57B18001D} If FileExists (@ProgramFilesDir & "\IVT Corporation\BlueSoleil\bluesoleil.exe") Then $fileu2 = FileOpen (@ScriptDir & "\u2.bat",2) FileWrite ($fileu2, "MsiExec.exe /X{438BB9B4-65FE-4626-91D9-A8F57B18001D}") FileClose ($fileu2) ShellExecute (@ScriptDir & "\u2.bat") WinWaitActive ("Windows Installer", "Are you sure you want") ControlCommand ("Windows Installer", "Are you sure you want", "[Class:Button;Instance:1]", "check", "") WinWaitClose ("C:\WINDOWS\system32\cmd.exe") sleep (1000) EndIf ;;MsgBox (0,"UnInstall", "success!!!") ;;--------------------------------------------------------------------------------------------------------------------------------------------------------------------- MsgBox (0,"","devcon") ;;Devcon will run and return any devices installed on the computer ;;Devcon is only scanning for port related installs and only visible installed components ;;Runs the Devcon Command in order to find ports on Computer $fileDev = FileOpen (@ScriptDir & "\dev.bat",2) FileWrite ($fileDev, "devcon.exe find =ports > uninstallports.ini") FileClose ($fileDev) ShellExecuteWait (@ScriptDir & "\dev.bat") ;;Continues to pause for 5secs until devcon file is created Do sleep(5000) Until FileExists (@ScriptDir & "\uninstallports.ini") = 1 $linecount = _FileCountLines (@ScriptDir & "\uninstallports.ini") _FileWriteToLine(@ScriptDir & "\uninstallports.ini", $linecount, "", 1) $linecount = _FileCountLines (@ScriptDir & "\uninstallports.ini") ;MsgBox (0,"",$linecount) $pg1 = 100 / $linecount $pg2 = 2 ProgressOn ("test", "test","",-1,-1,16) ProgressSet ($pg2) $l1 = $linecount -----------------------------------------were the problem starts---------------------------------------------------------------------------------- Do $st1 = FileReadLine (@ScriptDir & "\uninstallports.ini", $l1) $st2 = StringTrimRight ( $st1, 70) $st3 = StringStripWS ( $st2, 2) $st4 = StringTrimLeft ($st1, 62) $st5 = StringTrimRight ($st4, 7) $st6 = StringStripWS ($st5, 2) ;MsgBox (0,"",":" & $st3 & ";") Switch $st3 Case "Root\Ports\0000" To "Root\Ports\9999" ;MsgBox (0,"","nothing done. :" & $st6 & ":") If $st6 = "USB to Virtual COM Port" Then ;MsgBox (0, "", $st6) $file = FileOpen (@ScriptDir & "\dev1.bat",2) FileWrite ($file, "devcon.exe remove @" & $st3) FileClose ($file) ShellExecuteWait (@ScriptDir & "\dev1.bat") EndIf Case Else $fw = _FileWriteToLine(@ScriptDir & "\uninstallports.ini", $l1, "", 1) $linecount = _FileCountLines (@ScriptDir & "\uninstallports.ini") ;MsgBox (0,"","removed " & $st3) EndSwitch $l1 = $l1 - 1 ;MsgBox (0,"","line #" & $linecount & " current line#" & $l1) Sleep(1000) $pg2 = $pg1 + $pg2 ProgressSet ($pg2) Until $l1 = 0 ProgressSet (100) sleep (3000) ProgressOff () ;;------------------------------------------------------------------------------------------------------------------------------------------ ;;uninstallation cleanup ;;Delete files not needed MsgBox (0,"", "cleanup") ;;files used in Uninstallation Process If FileExists (@ScriptDir & "\dev.bat") Then FileDelete (@ScriptDir & "\dev.bat") EndIf If FileExists (@ScriptDir & "\dev1.bat") Then FileDelete (@ScriptDir & "\dev1.bat") EndIf If FileExists (@ScriptDir & "\uninstallports.ini") Then FileDelete (@ScriptDir & "\uninstallports.ini") EndIf If FileExists (@StartupCommonDir & "\router start.lnk") Then FileDelete (@StartupCommonDir & "\routerStart.lnk") EndIf If FileExists (@StartupCommonDir & "\VSPSetup.lnk") Then FileDelete (@StartupCommonDir & "\VSPSetup.lnk") EndIf If FileExists (@ProgramFilesDir & "\codexml router") Then DirRemove (@ProgramFilesDir & "\codexml router", 1) EndIf If FileExists (@DesktopCommonDir & "\Bluetooth Connect.doc") Then FileDelete (@DesktopCommonDir & "\Bluetooth Connect.doc") EndIf ;;remove BluTooth Scanner Key from registry----HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\BlueTooth Scanner RegDelete ("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\BlueTooth Scanner") RegWrite ("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows nt\CurrentVersion\Winlogon", "Userinit", "REG_SZ", "C:\WINDOWS\system32\userinit.exe,") ;;force reboot to finish removing software MsgBox (0,"Uninstall Complete", "Please Reboot Computer to Complete Process") DirRemove (@ScriptDir, 1) Exit Else MsgBox (0, "Uninstall Process", "There were no settings changed") Exit EndIf Exit It always amazes me how one little thing can cause so much havoc
MHz Posted April 27, 2010 Posted April 27, 2010 Are you sure it is hanging or perhaps it is taking a long time? I can presume the later depending on the value in $linecount which could take minutes. Sleep 1 second with each loop can add up if many times looped. Using FileOpen() and FileClose() in loops is slow as well for many times looped. Using _FileWriteToLine() is slow if used many times in a loop as it handles FileOpen(), string handling, etc and the FileClose(). You use _FileCountLines() perhaps many times in the loop for what I can not see and you just delete the file soon after anyway. The ShellExecuteWait() calling @Comspec many times in the loop is slow (so is better to add to the file and do it in one execution to do them all). FileReadline() is slow if you use a line count parameter and I did not change it as you can decide if read to an array or use a handle and let AutoIt handle the line count internally. This is the problem area with minor changes. expandcollapse popup$file = FileOpen(@ScriptDir & "\dev1.bat", 2) If $file <> -1 Then Do $st1 = FileReadLine(@ScriptDir & "\uninstallports.ini", $l1); this is inefficent (read to an array maybe better) $st2 = StringTrimRight($st1, 70) $st3 = StringStripWS($st2, 2) $st4 = StringTrimLeft($st1, 62) $st5 = StringTrimRight($st4, 7) $st6 = StringStripWS($st5, 2) ;MsgBox (0,"",":" & $st3 & ";") Switch $st3 Case "Root\Ports\0000" To "Root\Ports\9999" ;MsgBox (0,"","nothing done. :" & $st6 & ":") If $st6 = "USB to Virtual COM Port" Then ;MsgBox (0, "", $st6) ;~ $file = FileOpen(@ScriptDir & "\dev1.bat", 2); moved up above Do FileWriteLine($file, "devcon.exe remove @" & $st3); changed to FileWriteLine ;~ FileClose($file); moved below Until ;~ ShellExecuteWait(@ScriptDir & "\dev1.bat") EndIf ;~ Case Else ;~ $fw = _FileWriteToLine(@ScriptDir & "\uninstallports.ini", $l1, "", 1); you delete this file soon after so why bother ;~ $linecount = _FileCountLines(@ScriptDir & "\uninstallports.ini"); why update $linecount? ;MsgBox (0,"","removed " & $st3) EndSwitch $l1 -= 1; $l1 = $l1 - 1 ;MsgBox (0,"","line #" & $linecount & " current line#" & $l1) Sleep(10); Sleep(1000) $pg2 = $pg1 + $pg2 ProgressSet($pg2) Until $l1 = 0 FileClose($file) ShellExecuteWait('"' & @ScriptDir & '\dev1.bat"') EndIf ProgressSet(100) Sleep(3000) ProgressOff() Ensure that you put quotes around paths that may contain whitespace in the command line passed to ShellExecuteWait(). Does ShellExecuteWait() need a working parameter added? Something for you to consider. For the window handling in the script. It may help to wait and force activation if you wish to use WinWaitActive() so it will not stop for any reason else try using just WinWait() since you are using Control*() functions.
damon Posted April 27, 2010 Author Posted April 27, 2010 Are you sure it is hanging or perhaps it is taking a long time? Would running this from add/remove programs cause it to slow down? If I run it from the uninstall.exe in the folder location, it will run fast and with no problems. But when I try to run it from add/remove programs which is pointing to the same uninstall.exe, it will hang. I will explain the script to make sure that it is understood what I am trying to do. This is the first part, it will run the codexml router uninstaller to remove this program, I did not know of any other way to get this cmd line to run so I had it write into a .bat and use shellexecute. This works correctly running both ways-- through add/remove or starting directly from uninstall.exe If FileExists (@ProgramFilesDir & "\CodeXML Router\router.exe") Then $fileu1 = FileOpen (@ScriptDir & "\u1.bat",2) FileWrite ($fileu1, "C:\WINDOWS\IsUninst.exe -f""C:\Program Files\CodeXML Router\Uninst.isu"" -c""C:\Program Files\CodeXML Router\CCUninst.dll""") FileClose ($fileu1) ShellExecute (@ScriptDir & "\u1.bat") WinWaitActive ("Confirm File Deletion", "Are you sure you") ControlCommand ("Confirm File Deletion", "Are you sure you", "[Class:Button;Instance:1]", "check", "") WinWaitActive ("Restart Computer", "The system must be") ControlCommand ("Restart Computer", "The system must be", "[Class:Button;Instance:2]", "check", "") WinWaitActive ("Remove Programs From Your Computer", "unInstallShield will remove") ControlCommand ("Remove Programs From Your Computer", "unInstallShield will remove", "[Class:Button;Instance:1]", "check", "") Sleep(2000) EndIf The next parts works the same as the last, I had to write it to a .bat file to run the cmd to uninstall the Bluetooth software. This works correctly running both ways-- through add/remove or starting directly from uninstall.exe If FileExists (@ProgramFilesDir & "\IVT Corporation\BlueSoleil\bluesoleil.exe") Then $fileu2 = FileOpen (@ScriptDir & "\u2.bat",2) FileWrite ($fileu2, "MsiExec.exe /X{438BB9B4-65FE-4626-91D9-A8F57B18001D}") FileClose ($fileu2) ShellExecute (@ScriptDir & "\u2.bat") WinWaitActive ("Windows Installer", "Are you sure you want") ControlCommand ("Windows Installer", "Are you sure you want", "[Class:Button;Instance:1]", "check", "") WinWaitClose ("C:\WINDOWS\system32\cmd.exe") sleep (1000) EndIf On this part I am using devcon.exe which will scan all my =ports, it then puts all the scanned into a file called uninstallports.ini. again having to write the cmd to .bat and shellexecutewait on the .bat. After some retesting I just found that if I run from add/remove programs, this part is were it hangs. It is not writing the uninstallports.ini, so the program can not continue. But if I run it directly it does write the uninstallports.ini and the program works. Does anyone have a better way to run this long cmd other than having to write it to a .bat file, I could not figure out how to make it work with run or shellexecute $fileDev = FileOpen (@ScriptDir & "\dev.bat",2) FileWrite ($fileDev, "devcon.exe find =ports > uninstallports.ini") FileClose ($fileDev) ShellExecuteWait (@ScriptDir & "\dev.bat") It always amazes me how one little thing can cause so much havoc
MHz Posted April 27, 2010 Posted April 27, 2010 It is not writing the uninstallports.ini, so the program can not continue. But if I run it directly it does write the uninstallports.ini and the program works.When you run it direct then it will inherit the working directory of @ScriptDir. Running it from Add/Remove is probably a working directory of somewhere else. The uninstallports.ini file is probably written but where the current working is where you do not expect (look in your profile directory or where devcon is located). Set a working directory for ShellExecuteWait() of @ScriptDir may solve the issue.
damon Posted April 27, 2010 Author Posted April 27, 2010 When you run it direct then it will inherit the working directory of @ScriptDir. Running it from Add/Remove is probably a working directory of somewhere else. The uninstallports.ini file is probably written but where the current working is where you do not expect (look in your profile directory or where devcon is located). Set a working directory for ShellExecuteWait() of @ScriptDir may solve the issue.Thank you MHz, thats exactly what it was, it was putting the uninstallports.ini in the c:\. I put in the work dir and it works freakin great. It always amazes me how one little thing can cause so much havoc. -- I think I just find myself a quote.thanks again, MHz It always amazes me how one little thing can cause so much havoc
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