Powershell:通过UpgradeCode

时间:2018-03-02 18:00:14

标签: powershell windows-installer install uninstall

当我通过Powershell脚本升级/降级我的应用程序时,我想首先强制卸载当前安装的版本,然后再运行新的安装程序。

如何使用Powershell,使用应用程序的UpgradeCode?

按应用程序名称执行此操作会不那么健壮。

1 个答案:

答案 0 :(得分:1)

由于您提到了升级代码,因此它必须意味着您正在谈论MSI文件(Windows Installer)。正如其他人所说的那样,卸载通常由正确创作的MSI软件包自动执行 - 它被称为major upgrade - 这实际上是对现有版本产品的卸载,然后安装最新版本。

正在安装的MSI的Upgrade Table将指定在安装新版本之前将卸载该框上的现有软件包。理论上,您可以卸载任意数量的现有安装。如果你作为帽子疯了,你甚至可以卸载一个有竞争力的产品。坦率地说,令人惊讶的是,我从未尝试过在一次重大升级中卸载多个产品 - 很少需要它。在大多数情况下,您卸载单个现有产品,然后安装最新版本。

  1. 您可以使用transform修改升级表,以更改主要升级的行为方式 - 换句话说,使其启动或停止卸载特定的预先存在的安装。

  2. 您还可以通过调用此MSI API函数(COM - 用作示例的VBScript)枚举共享相同升级代码的所有相关产品:

  3. Set installer = CreateObject("WindowsInstaller.Installer")
    
    ' Enumerate all products related to "Microsoft Visual C++ 2008 Redistributable - x86 9.0.30729.4148"
    
    ' {AA783A14-A7A3-3D33-95F0-9A351D530011} is the upgrade code
    Set upgrades = installer.RelatedProducts("{AA783A14-A7A3-3D33-95F0-9A351D530011}")
    
    For Each u In upgrades
       MsgBox u, vbOKOnly, "Product Code: "
    Next
    

    然后,您可以通过将产品代码传递到msiexec.exe命令行来卸载产品(请参阅下文,了解如何通过MSI API COM自动化执行此操作):

    msiexec.exe /x {11111111-1111-1111-1111-11111111111X} /L*V "C:\msilog.log" REBOOT=ReallySuppress
    

    快速参数说明(因为我建议使用此选项):

     /X = run uninstall sequence
     /QN = run completely silently
     /L*V "C:\msilog.log"= verbose logging at path specified
     {11111111-1111-1111-1111-11111111111X} = product guid of app to uninstall
     REBOOT=ReallySuppress = prevent reboot without warning (badly authored MSI packages)
    

    如果您不想通过msiexec.exe卸载,那么您可以在此处找到无数种方法来调用MSI卸载: 的 Uninstalling an MSI file from the command line without using msiexec

    您可以通过几种不同的方式找到已安装的MSI的产品代码:How can I find the product GUID of an installed MSI setup?

    更新:我想我忘记了显而易见的,您可以直接通过MSI API自动卸载。在下面的脚本中,我们将所有产品共享相同的升级代码,然后按顺序卸载它们。

    请注意,当以静默方式运行时,您应该使用管理员权限运行,因为UAC可能会被禁止,然后卸载通常会失败(权限被拒绝)。因此,以下脚本以交互方式运行卸载 - 允许UAC提示和提升。

    如果不显而易见:运行此脚本将卸载Orca!我将此产品用作示例,因为它可以快速安装(hints on finding the installer quick if you need to towards bottom here - 搜索"奥卡&#34):

    BIG DISCLAIMER

    COM方法installer.ConfigureProduct不接受允许我们传入REBOOT=ReallySuppress的任何参数。这意味着一个(非常)严重创作的包触发了ScheduleReboot操作(或使用一些更加模糊的魔法导致重启) - 如果您使用管理员权限并以静默模式运行以下脚本,可能会在没有警告的情况下重启系统

    有一个较新的调用ConfigureProductEx可用作Win32函数,但它通过COM自动化界面显示 。如果您platform invoke可以使用该调用 - 此处的第14节中有一个C ++示例:Uninstalling an MSI file from the command line without using msiexec。或者您可以使用WiX工具包中的DTF功能(请参阅与C ++示例相同的链接中的第6节)。

    2018年7月更新

    Set installer = CreateObject("WindowsInstaller.Installer")
    installer.InstallProduct "product.msi", "REMOVE=ALL REBOOT=ReallySuppress"
    Set installer = Nothing
    

    也许上面的代码段是最好的卸载方法?这应该禁止任何重新启动。我现在没有时间或设置来测试它(在Linux机器上),但我想在忘记之前添加它。

    原始卸载脚本

    Const msiUILevelNone = 2
    Const msiInstallStateAbsent = 2
    
    Set installer = CreateObject("WindowsInstaller.Installer")
    'installer.UILevel = msiUILevelNone ' Disabled to prevent silent uninstall. Now the UAC prompt will show
    
    ' Uninstall Orca, replace upgrade code with yours
    Set products = installer.RelatedProducts("{CFF4D510-79B2-1CCD-0061-5741A0565A76}")
    
    For Each product In products
       ' MsgBox "Product Code: " & product ' Show the product code found, if you want
    
       ' The following call when run silently with admin rights may reboot the system without warning!
       ' This is due to badly authored MSI packages - most packages will not trigger this problem.
       installer.ConfigureProduct product, 0,  msiInstallStateAbsent ' Uninstall product
    
       ' See text above for info on the newer ConfigureProductEx method.
    Next
    
    Set installer = Nothing
    
    MsgBox "Finished" ' Just so we know the script ran if nothing found to uninstall
    

    一些链接: