作为this question的后续内容,在阅读了blog post提到的Rob Mensching this answer之后,似乎我尝试使用msizap进行操作的方式是一个坏主意我在测试中看到了一些问题。
在他以不同的方式做的事情中,他说:
利用数据构建解决方案。一世 期望建立一个新的MSI 解决问题。然后你发送 所有的修复和指示 那些有问题的人。它会 可能是类似的东西 recache / reinstall(msiexec / fv,a 支持开关)顶部 有问题的安装然后卸载。 这样机器就知道了 状态和设置递增 提高。
如何构建这样的MSI?我正在使用WiX,问题是卸载过程试图在删除之后运行exe,因为它是在InstallFinalize之后安排的。 (忘了指定它应该只在安装而不是卸载时运行)
答案 0 :(得分:2)
根据您在卸载时遇到的问题类型以及如何部署它,完全可以编写脚本并对其进行部署以编辑计算机上的缓存MSI以解决问题。您可以遍历C:\ Windows \ Installer \文件夹中的MSI来查找产品的MSI(打开所有内容并阅读摘要信息)
一旦找到了你需要的那个,你可以直接修改表来修复你引入的任何问题(即在卸载时禁用自定义操作等),下次调用卸载时不会发生问题。
资源:
Windows Installer SQL Reference
Windows Installer Automation Interface Reference
包括一个示例脚本,我应该指出,这主要是因为内部部署的应用程序并不是真正可以作为修复程序发送给客户的东西,但它可以创建一个二进制文件来执行相同的操作并将其包含在内说一个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
答案 1 :(得分:0)
如果MSI不会卸载你可能只需要使用MSI zap。它不会删除任何文件,但您可以使用Orca查看MSI中所有文件的列表并手动删除它们。