InstallShield uninstall GUID changes w/ every install
Push comes to shove, I may need to look at adding some code to the install that looks in C:\Program Files\Installshield Installation\ for a directory that's less than 5 minutes old, let's say, and renames it to something predictable. If this were Linux/UNIX, that would be a piece of cake. But under Windows... if there's no better solution, can anyone point me in the right direction there?
Answers (6)
# Log file funtion function time{(Get-Date -Format dd-MM-yyyy-hh:mm:ss)} $logfile = "c:\temp\JRE-Uninstall.log" Function LogWrite {Param ([string]$logstring)Add-content $Logfile -value ($(time) + " - $logstring ")}#Product to Remove$Product = '*Java*'#Publisher$Publisher = '*Oracle*'#32bit Uninstall Strings$32bitPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'#64bit Uninstall Strings$64bitPath = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'try{$JavaVersions = Get-ChildItem -Path $32bitPath, $64bitPath | Get-ItemProperty -ErrorAction Stop | Where-Object { $_.DisplayName -like "$Product" -and $_.Publisher -like "$Publisher"} | Select-Object -Property DisplayName, UninstallString }catch{$_}if($JavaVersions -eq $null){exit LogWrite "Java not found"}$v = $JavaVersions.DisplayName |Out-StringLogWrite "detected $V"#Perform silent uninstall of targeted versionsforeach ($Version in $JavaVersions) {Write-Host $JavaVersions.DisplayName}do{ForEach ($Version in $JavaVersions){ $v = $Version.DisplayName |Out-String $Uninstall = $Version.UninstallString.replace("MsiExec.exe /I","MsiExec.exe /X") Write-Host $Uninstall LogWrite "Removing $v $Uninstall" Start-Process cmd.exe -ArgumentList "/k $Uninstall /qn /norestart" logwrite "Removed $v GUID $Uninstall" Start-Sleep 60 try{$Javaremoved = Get-ChildItem -Path $32bitPath, $64bitPath | Get-ItemProperty -ErrorAction Stop | Where-Object { $_.DisplayName -like "$Product" -and $_.Publisher -like "$Publisher"} | Select-Object -Property DisplayName, UninstallString }catch{$_}}}until($Javaremoved -eq $null)LogWrite "Removal complete"exit
Hello,
I had a very similar problem today, and it took me a while to find an elegant solution. My application had the following UninstallString, with 'SOME GUID' being a different guid every time:
"C:\Program Files (x86)\InstallShield Installation Information\{SOME-GUID}\setup.exe" -runfromtemp -l0x0009 -removeonly
I managed to uninstall the whole thing in 3 CMD lines
FOR /F "tokens=*" %%A IN ('reg query HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall /f "UNIQUE_DISPLAY_NAME" /s ^| FindStr /R "[{].*[}]"') DO SET GUID=%%A
set GUID=%GUID:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\=%
"%ProgramFiles(x86)%\InstallShield Installation Information\%GUID%\setup.exe" -runfromtemp -l0x0009 -removeonly -s -f1"c:\complete\path\to\uninstall.iss"
So what this does, is search the part of the registry where the uninstallstrings are for the 'Display Name' (This name needs to be modified). The line that contains the GUID is then filtered out by searching for a regular expression with FindStr /R "[{].*[}]". The result is stored in variable GUID.
After the first line, the variable GUID should contain:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{AND-THE-ENTIRE-GUID}
The whole path is then deleted by a search and replace, with a syntax I only discoverd today, for example, to replace 'teh' with 'the': VARIALBE = %VARIALBE:teh=the%. What remains is the GUID.
I then generated an uninstall.iss using the -r switch, and included it as a parameter with: -s -f1"c:\complete\path\to\uninstall.iss" (don't forget to include the full path if you do this, otherwise you may have unexpected results).
Hopefully, this will help someone, someday.
Cheers!
Comments:
-
Some fool downvoted Cubefreak's excellent answer. Thankyou very much.
Careful with your UNIQUE_DISPLAY_NAME - I had two application names which differed by a * character and the script didn't respect batch file escaping. So I had to use another registry field to get a unique match.
But it's automated, and done. Excellent work. - carl.bennett 7 years ago
i see 2 ways to get around this: you could add some code at the installation that will put the GUID in a text file which could be read at uninstall. or you could run a script that will check in the reg uninstall key for the GUID. either way is pretty easy to do.
Well, I am just running the install, not packaging it. If there's a way to capture the GUID during install, I'd love to hear it.
As for the other way... the registry GUID changes, too. So I found a piece of VBScript that's supposed to hunt through all of the Uninstall keys for a specific text string and return the name of the key it's in, but I couldn't make that go, as I'm just not familiar with VBScript. If this was Linux, no sweat, I'd be done. But then, if this was Linux, I wouldn't have to deal with registries and changing GUIDs ;)
so that the conversation will remain readable.