В зависимости от типа проблемы, с которой вы столкнулись при удалении, и способа ее развертывания, можно полностью написать сценарий и развернуть его для редактирования кэшированного MSI на компьютере, чтобы устранить проблему. Вы можете перебирать MSI в папке C: \ Windows \ Installer \, чтобы найти тот, который подходит для вашего продукта (например, открыть их все и прочитать сводную информацию)
После того, как вы нашли ту, которая вам нужна, вы можете изменить таблицы напрямую, чтобы исправить любую проблему, которую вы ввели (например, отключение настраиваемого действия при удалении и т. Д.), В следующий раз, когда удаление будет вызвано, проблема не возникнет.
Ресурсы:
Справочник SQL установщика Windows
Справочник по интерфейсу автоматизации установщика Windows
Включая пример сценария, я должен отметить, что это, в основном, говорит, например, о том, что приложение, развернутое внутри, на самом деле не то, что вы могли бы отправить клиентам в качестве исправления, но возможно создать двоичный файл, который делает то же самое и включает его скажем, setup.exe, где бинарный файл запускается сначала для очистки и удаления предыдущей деинсталляции, а затем откладывает новую, или, в качестве альтернативы, просто отправляет бинарный файл для устранения проблем удаления.
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%") & "\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 & objFile.Name, titleToFind) ) Then
UpdateMSI ( installerPath & 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 & " " & Hex(Err) & ": " & Err.Description
If Not installer Is Nothing Then
Set errRec = installer.LastErrorRecord
If Not errRec Is Nothing Then message = message & vbLf & errRec.FormatText
End If
Fail message
End Sub
Sub Fail ( message )
WScript.Echo message
WScript.Quit 2
End Sub