Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Depending on the type of problem you have with the uninstall and how you are deploying it it is entirely possible to write a script and deploy it to edit the cached MSI on the machine to fix the problem. You can iterate through the MSI's in the C:\Windows\Installer\ folder to look for the one for your product ( Opening them all and reading the summary information for example ) </p> <p>Once you have found the one you need you can modify the tables directly to fix whatever problem you have introduced (i.e. disabling custom action on uninstall etc), next time the uninstall is called the problem will not occur. </p> <p>Resources:<br> <a href="http://msdn.microsoft.com/en-us/library/aa372021(VS.85).aspx" rel="nofollow noreferrer">Windows Installer SQL Reference</a><br> <a href="http://msdn.microsoft.com/en-us/library/aa367810(VS.85).aspx" rel="nofollow noreferrer">Windows Installer Automation Interface Reference</a></p> <p>Including a sample script, I should point out that this is mainly for say an internally deployed application not really something you could send to customers as a fix but its possible to create a binary that does the same thing and have it included in say a setup.exe where the binary kicks off first to clean up and remove the previous uninstall and then put down the new one, or alternatively just send out the binary to fix the uninstall issues. </p> <pre><code>Option Explicit Dim objFS, objShell Dim objFolder, objFiles, objFile Dim objInstaller Dim installerPath, titleToFind Dim queries Const msiOpenDatabaseReadOnly = 0 Const msiOpenDatabaseTransact = 1 Set objInstaller = CreateObject("WindowsInstaller.Installer") Set objShell = CreateObject("WScript.Shell") installerPath = objShell.ExpandEnvironmentStrings("%SystemRoot%") &amp; "\Installer\" 'Set the title you want to use for comparison titleToFind = "Sample" ' Define the queries you wish to run against the database if found queries = Array( "UPDATE `InstallExecuteSequence` SET `Condition` = 'NOT Installed' WHERE `Action` = 'SampleAction'", _ "DELETE FROM `InstallExecuteSequence` WHERE `Action` = 'SampleAction'") Set objFS = CreateObject("Scripting.FileSystemObject") On Error Resume Next If ( objFS.FolderExists(installerPath)) Then Set objFolder = objFS.GetFolder(installerPath) Set objFiles = objFolder.Files For Each objFile in objFiles If ( StrComp ( Right(objFile.Name, 4), ".msi") = 0 ) Then If ( CheckMSI (installerPath &amp; objFile.Name, titleToFind) ) Then UpdateMSI ( installerPath &amp; objFile.name) Exit For End If End If Next End If Set objFS = Nothing Set objShell = Nothing Set objFile = Nothing Set objFiles = Nothing Set objFolder = Nothing Set objInstaller = Nothing ' Check if the title in the MSI matches the one you are looking for Function CheckMSI ( msiPath, title) Dim objDatabase, objSummary Dim msiTitle Set objDatabase = objInstaller.OpenDatabase ( msiPath, msiOpenDatabaseReadOnly ) : CheckError Set objSummary = objDatabase.SummaryInformation(0) msiTitle = objSummary.Property(2) If ( StrComp ( msiTitle, title) = 0 ) Then CheckMSI = true Else CheckMSI = false End If Set objSummary = Nothing Set objDatabase = Nothing End Function ' Loop though the queries specified above and execute them against the MSI Function UpdateMSI (msiPath) Dim objDatabase Dim objView Dim query Set objDatabase = objInstaller.OpenDatabase(msiPath, msiOpenDatabaseTransact) : CheckError For Each query in queries Set objView = objDatabase.OpenView (query) : CheckError objView.Execute : CheckError Next objDatabase.Commit Set objView = Nothing Set objDatabase = Nothing End Function Sub CheckError Dim message, errRec If Err = 0 Then Exit Sub message = Err.Source &amp; " " &amp; Hex(Err) &amp; ": " &amp; Err.Description If Not installer Is Nothing Then Set errRec = installer.LastErrorRecord If Not errRec Is Nothing Then message = message &amp; vbLf &amp; errRec.FormatText End If Fail message End Sub Sub Fail ( message ) WScript.Echo message WScript.Quit 2 End Sub </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload