Jump to content

Silent uninstalling - reg reading help


beato
 Share

Recommended Posts

This maybe more of a syntax or logic question, but I dont know how to perform the following.

I have a uninstall/install program using autoit that I created that goes thru and uninstalls a bunch of apps, reboots and then kicks off the install for the new apps. One of the functions is to uninstall all my apps silently. I typically in the past have gone to the image sharepoint were the app was installed and kicked off the standard uninstall MSI switch:

RunWait('MsiExec.exe /X"\\server name\folder\i386_English.msi" /qb') etc

No issues with that. However, I am now in a position where say three of the applications in question were installed from and image. Of these three all of them are at different service packs, so they are all going to different images (diff sps) out on a admin sharpoint. So the standard "path to MSI" switch won't work because the path is different based on what image it was installed from

The problem is that to run the uninstall string I need to know what image path to go to. Basically I need to find out what version or install path for a given app is at and then based on that output run the uninstall string.

I was thinking the best way to determine the install location or SP of a given app is to cycle through the REG at > HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ hive here\ on a users system. However, I would have to know (all) the exact hives prior e.g. Version\Uninstall\{CFFAD179-EAA8-4862-AB95-321C00CE6A8F}]

I dont know the logic programatically. Any thoughts or ideas

Link to comment
Share on other sites

msiexec /x takes a GUID also. You could search by name through the registry in HKLM\Software\Microsoft\Windows\Currentversion\Uninstall ... enumerating through until you find the "DisplayName" and launch the corresponding "UninstallString" adding the /qb or just note the GUID (which is likely the name of the registry key) and formulate the msiexec string yourself.

Lar.

f_mrcleansmalm_77ce002.jpgAutoIt has helped make me wealthy

Link to comment
Share on other sites

Download MyUninstaller from Nirsoft, it will tell you the uninstall commands.

http://www.nirsoft.net/utils/myuninst.html

Thanks! However, can this util be used silently or in auto mode. e.g. run your app> select the apps you want uninstalled> read those selected to a file> then on any system in question, you could launch you app read in the file that contains a "selection set" and hit a button and walk away etc? I know the uninstall paths or can find them its the automation of collecting them all (don't know how to script it)

FWIW Here is my situation - I have hundred users, all have basically the same ten apps installed (some are at different sp's/paths). I remote desktop into each system and run my "master setup app" hit go and on to the next system. I try to do everything in two steps automatically. One: uninstall, dir removals, reg deletes, clean up, auto reboot. Upon login I set the runonce key (in the prior uninstall step) to "launch" a idle graphic that says go next step and when selected it launches the master setup again but this time installs all the new ten apps etc.. The key here is minimal babysitting both steps.

Again, I have the program basically done, its just for that a few apps have different paths to the msi that I want to automate in my master prrogram:)

Link to comment
Share on other sites

I would use PSEXEC and push it out to each... shoot... why remote... but anyway.

If you know some common text for the app regardless of version in the "Add Remove Programs", then you can use any one of the numerous "Search Uninstall in Registry" type functions written numerous times by members. I am sure one of them returns the "UninstallString" ... you can detect if the uninstallstring has "msiexec /x" in it and "/qb" or "/qn" ... if it does not have "/qb" or "/qn" then add it to the UnistallString and RunWait() it.

If you are waiting for someone to write one for you... have a seat and get some coffee.

Learn how to enumerate through Uninstall info in the registry using AutoIt. It has been addressed on the forum dozens of times.

Lar.

f_mrcleansmalm_77ce002.jpgAutoIt has helped make me wealthy

Link to comment
Share on other sites

I would use PSEXEC and push it out to each... shoot... why remote... but anyway.

If you know some common text for the app regardless of version in the "Add Remove Programs", then you can use any one of the numerous "Search Uninstall in Registry" type functions written numerous times by members. I am sure one of them returns the "UninstallString" ... you can detect if the uninstallstring has "msiexec /x" in it and "/qb" or "/qn" ... if it does not have "/qb" or "/qn" then add it to the UnistallString and RunWait() it.

If you are waiting for someone to write one for you... have a seat and get some coffee.

Learn how to enumerate through Uninstall info in the registry using AutoIt. It has been addressed on the forum dozens of times.

Lar.

Thanks Lar.

Link to comment
Share on other sites

I would use PSEXEC and push it out to each... shoot... why remote... but anyway.

Lar.

Also, as to PSEXEC (which I know a little bit about), when I perform this major release rollout, its after hours (weekends) when users are not present and my program has a gui so there is some interaction required by me. As well as there are always glitches on some systems were either services that get unregistered and then re-registered hang (passwords) and need my input or the uninstall dialogs are flaky and need some OK's or Finish buttons to select.

I'm all ears if you have a better idea/method :P

Edited by beato
Link to comment
Share on other sites

OK, so I have the following snipit that is pretty much what I want it to do => only grab MSI type of installs (no installshield due to different switches) from the "supported app list" and then automatically run the unisntall.

However, I'm having a problem trying to execute the silent switch on all that it finds. It currently finds the apps but I am prompted with the standard uninstall dialogs for each. Any suggestions?

Again, ultimately I am trying for it to cycle through the "supported apps" string and uninstall all silently. For handling a possible error where say one of the MSI's gets hung (so it doesn't continue on to the next app) did I put in the a correct method for the entire loop to stop and exit with a message (process wait)?

Thanks..

Dim $SupportedApps = "App1,App2,App3,App4"  
Dim $MyApps = StringSplit($SupportedApps, ",")
Dim $InstalledAppsCount = 1
Dim $Found = 0


While 1
   
    $SubKey = RegEnumKey("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", $InstalledAppsCount)
    If @error Then ExitLoop
   
    $DisplayName = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" & $SubKey, "DisplayName")
    $Uninstallstring = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" & $SubKey, "UninstallString")
   
    For $i = 1 To $MyApps[0]
       
            If StringInStr($DisplayName, $MyApps[$i]) Then
           
            $Found += 1
                RunWait($Uninstallstring)
                ProcessWait("MsiExec.exe",1000000)
                $Uninstallstring = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" & $SubKey, "UninstallString")
                RunWait(@ComSpec & ' /c start /wait MsiExec.exe /X' & $Uninstallstring  & ' /qb', 'C:', @SW_HIDE)     ;<= having trouble here, not sure if this is the correct place or method
                                
;~              GUICtrlSetData($StatusLabel, "Uninstalling app...") ;would like to put a status here to see what app is being worked on

                if $Uninstallstring <> "" then
                    msgbox("4096", "failed", "problems")
                    Exitloop ;looks to see if msi is still running due to an error and would exit FOR completely             <= will this correctly exit out completely
                Endif
            EndIf  
    Next
    
    $InstalledAppsCount += 1
   
WEnd

If Not $Found Then
    MsgBox(64, "Not Found", "No apps found", 3)
Else

EndIf
Edited by beato
Link to comment
Share on other sites

What if you use /qn ?

Nope. still not working. I'm thinking it wouldn't matter if qn or qb was used? qn will display no dialog and qb will just display the uninstall progress dialog (prefer that feedback) but still be silent. Actually when I run the script, the Msiexec.exe help dialog is displayed, I click OK and the "problem" dialog is displayed, so I select OK and it exits.???
Link to comment
Share on other sites

maybe...

Dim $MyApps[3] = ["goo","boo","schmoo"]
$InstalledAppsCount = 1
$Found = 0

While 1

    $SubKey = RegEnumKey("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", $InstalledAppsCount)
    If @error Then ExitLoop

    $DisplayName = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" & $SubKey, "DisplayName")
    $Uninstallstring = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" & $SubKey, "UninstallString")

    For $i = 0 To UBound($MyApps)-1
        If StringInStr($DisplayName, $MyApps[$i]) And StringInStr($Uninstallstring, "msiexec") Then

            $Found += 1
            If Not StringInStr($Uninstallstring, "/qb") And Not StringInStr($Uninstallstring, "/qn") Then $Uninstallstring &= " /qb"
            RunWait($Uninstallstring)
        EndIf
    Next

    $InstalledAppsCount += 1

WEnd

If Not $Found Then
    MsgBox(64, "Not Found", "No apps found", 3)
EndIf

Edited by LarryDalooza

f_mrcleansmalm_77ce002.jpgAutoIt has helped make me wealthy

Link to comment
Share on other sites

maybe...

Dim $MyApps[3] = ["goo","boo","schmoo"]
$InstalledAppsCount = 1
$Found = 0

While 1

    $SubKey = RegEnumKey("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", $InstalledAppsCount)
    If @error Then ExitLoop

    $DisplayName = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" & $SubKey, "DisplayName")
    $Uninstallstring = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" & $SubKey, "UninstallString")

    For $i = 0 To UBound($MyApps)-1
        If StringInStr($DisplayName, $MyApps[$i]) And StringInStr($Uninstallstring, "msiexec") Then

            $Found += 1
            If Not StringInStr($Uninstallstring, "/qb") And Not StringInStr($Uninstallstring, "/qn") Then $Uninstallstring &= " /qb"
            RunWait($Uninstallstring)
        EndIf
    Next

    $InstalledAppsCount += 1

WEnd

If Not $Found Then
    MsgBox(64, "Not Found", "No apps found", 3)
EndIf
:mellow: Close, thank you. However, in the "Dim $MyApps[3]" I have six "NAMES" specified and I get ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.: when script is run?
Link to comment
Share on other sites

your killing me smalls...

try changing the script from...

Dim $MyApps[3] = ["goo","boo","schmoo"]

to

Dim $MyApps[YOUR NUMBER GOES HERE] = ["YOUR APP1","YOUR APP2","YOUR APP3","YOUR APP(NN)",...]

and someone else will take it from here... there are 23,000 members and you have enough to solve your problem... trial and error from now on, brother.

Lar.

f_mrcleansmalm_77ce002.jpgAutoIt has helped make me wealthy

Link to comment
Share on other sites

your killing me smalls...

try changing the script from...

Dim $MyApps[3] = ["goo","boo","schmoo"]

to

Dim $MyApps[YOUR NUMBER GOES HERE] = ["YOUR APP1","YOUR APP2","YOUR APP3","YOUR APP(NN)",...]

and someone else will take it from here... there are 23,000 members and you have enough to solve your problem... trial and error from now on, brother.

Lar.

Embarrassed. :mellow: Thanks. Its all good. I didn't do toooo bad though.

FWIW - The script ran through all the uninstalls (MSI progress was displayed for each app), BUT nothing was uninstalled? Very odd for sure. The entire process went really quick so I figured something was up, but the concept was just what I am looking for. I'll keep digging into why nothing was uninstalled.

Thanks again!

Link to comment
Share on other sites

it is possible you need a working directory... try running the UninstallString with the /qb from the run dialog... if it works from the run dialog...then this should be working...

RunWait($Uninstallstring,@SystemDir)

Lar.

Reporting back! :mellow: The system dir wasn't it. However, the problem is that the uninstall value in the reg is Msiexe /1{....} and it needs to ne Msiexe /X{...}. Tested it and it works. Don't know how I missed that.

So now I'm trying to figure out how to find the equivalent of vbs Replace. As in:

RunWait(Replace($Uninstallstring,"/I{","/X{"),"")

Link to comment
Share on other sites

So now I'm trying to figure out how to find the equivalent of vbs Replace. As in:

RunWait(Replace($Uninstallstring,"/I{","/X{"),"")

StringReplace()

Dog ate your help file?

:mellow:

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

And we have a winner!

RunWait(StringRegExpReplace($Uninstallstring,"/I{","/X{"),"")

Appears to be working great. I'll do a few more test and share my finding. Thank you all!

Working code

Dim $MyApps[6] = ["App1, App2"]
$InstalledAppsCount = 1
$Found = 0

While 1

    $SubKey = RegEnumKey("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", $InstalledAppsCount)
    If @error Then ExitLoop
    
    $DisplayName = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" & $SubKey, "DisplayName")
    $Uninstallstring = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" & $SubKey, "UninstallString")

    
    For $i = 0 To UBound($MyApps)-1
        If StringInStr($DisplayName, $MyApps[$i]) And StringInStr($Uninstallstring, "msiexec") Then

            $Found += 1
            If Not StringInStr($Uninstallstring, "/qb") And Not StringInStr($Uninstallstring, "/qn") Then $Uninstallstring &= " /qb"
            RunWait(StringReplace($Uninstallstring,"/I{","/X{"),"")
        EndIf
    Next

    $InstalledAppsCount += 1

WEnd

If Not $Found Then
    MsgBox(64, "Not Found", "No apps found", 3)
EndIf
Edited by beato
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...