Windows installer 如何修复赢得';t卸载

Windows installer 如何修复赢得';t卸载,windows-installer,Windows Installer,在阅读了Rob Mensching的文章之后,我认为我试图用msizap来做这件事是个坏主意,我在测试中发现了一些问题 在《他会做什么不同》一文中,他说: 利用数据构建解决方案。我 希望可以建立一个新的MSI 解决问题。然后你送 修复程序和说明将分发给所有人 那些有问题的人。会的 可能有点像 重新设置/重新安装(msiexec/fv,a 支持的交换机)在顶部 先安装,然后卸载。 这样机器就保持在已知的状态 状态和设置增量 改善 这样的微星将如何建立?我使用的是WiX,问题是卸载过程试图在删除ex

在阅读了Rob Mensching的文章之后,我认为我试图用msizap来做这件事是个坏主意,我在测试中发现了一些问题

在《他会做什么不同》一文中,他说:

利用数据构建解决方案。我 希望可以建立一个新的MSI 解决问题。然后你送 修复程序和说明将分发给所有人 那些有问题的人。会的 可能有点像 重新设置/重新安装(msiexec/fv,a 支持的交换机)在顶部 先安装,然后卸载。 这样机器就保持在已知的状态 状态和设置增量 改善


这样的微星将如何建立?我使用的是WiX,问题是卸载过程试图在删除exe后运行exe,因为它是在InstallFinalize之后安排的。(忘了指定它应该只在安装时运行,而不是卸载时运行)

如果MSI不卸载,您可能需要使用MSI zap。它不会删除任何文件,但您可以使用Orca查看MSI中所有文件的列表并手动删除它们。

根据卸载问题的类型和部署方式,完全可以编写脚本并部署它来编辑机器上的缓存MSI以修复问题。您可以遍历C:\Windows\Installer\文件夹中的MSI以查找适用于您的产品的MSI(例如,打开所有MSI并阅读摘要信息)

一旦找到所需的表,就可以直接修改表以修复引入的任何问题(例如,禁用卸载时的自定义操作等),下次调用卸载时,将不会出现问题

资源:

包括一个示例脚本,我应该指出的是,这主要是为了一个内部部署的应用程序,而不是你可以发送给客户作为修复程序的东西,但它可以创建一个二进制文件来做同样的事情,并将其包含在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

有关于如何做到这一点的链接或资源吗?