卸载MSI-Package始终会提供重新启动消息

时间:2018-03-07 08:09:57

标签: windows-installer wmi ps

我只是为一些新软件编写脚本。因此,我必须删除一些较旧的软件。我正在使用PS脚本执行此操作。这几乎没问题。提升的权限正在运行,软件已被删除,但第一次卸载时始终会显示有关重新启动的消息。只有按下'确定'

才能确认此消息

现在我怎么强迫消息不会出现?

这就是我在PS-Script中所拥有的:

start-process msiexec.exe -Wait -ArgumentList '/x "file.msi" /passive /norestart'

我还尝试了/ quiet标志,但是我什么都没看到(d'呃),软件仍在那里。

我必须重新启动是合乎逻辑的,但我只是不想看到这条消息。我不确定它是来自MSIEXEC还是来自MSI文件本身的消息。谷歌找不到东西。

enter image description here

2 个答案:

答案 0 :(得分:0)

更新:事后考虑:检查此对话框是否实际显示在InstallUISequence?如果它仅插入到InstallUISequence而不存在于InstallExecuteSequence中,那么当您为设置触发静默安装/卸载时它将永远不会运行,因为在此过程中会跳过整个InstallUISequence安装模式。

QN添加到msiexec.exe命令行以静默运行。见下面的样品。 如果你运气好的话,这可以解决你的整个问题,而不需要下面提到的任何小的升级或黑客攻击。所以检查一下。请将REBOOT=ReallySuppress添加到所有静默msiexec.exe命令行 - 以防止标准MSI功能触发突然重启。

REBOOT = REALLYSUPPRESS

MSI文件中有一个名为REBOOT的属性,可以在REBOOT=ReallySuppress命令行上设置为msiexec.exe,以禁止标准MSI预定重新启动 。这对于静默安装尤其重要,否则可能会在没有警告的情况下触发自发重启(对于设计错误的非常糟糕的MSI文件 - 在制作公司使用的软件包时,我总是禁用ScheduleRebootForceReboot - 重新启动知识没有警告的工人和PC可以消除大量的工作):

msiexec.exe /x {11111111-1111-1111-1111-1111111111GH} REBOOT=ReallySuppress

我还会使用旧式的msiexec.exe开关:/x/i等...而不是"便利功能":/passive/norestart等......只是我的两分钱。

供参考

非标准重启

但是,您发布的对话似乎是非标准的。它实际上看起来像是从设置本身的自定义操作显示的自定义对话框 - 这些将不符合MSI标准,您必须根据具体情况处理它们。

我想这是一个安全的假设,你想要卸载的软件已经在野外"并安装在您尝试将其从中删除的多个工作站上?鉴于这是一个正确的假设,我们在谈论清理多少台计算机?许多?数百?成千上万的?如果MSI不活动,您可以调整它以在部署之前通过转换删除对话框。刚才提到这一点。从技术上讲,您可以通过将自定义操作的条件设置为0来实现此目的(对于false,则自定义操作将永远不会运行)。

离题:有一个可怕的" hack"我从未尝试过,我只会将一台计算机清理用作支持人员:How to apply a Msi transform at uninstall?我不会使用它(除非我正在清理一台PC - 例如开发盒)。

也可以直接编辑缓存的MSI(至少先备份):I screwed up, how can I uninstall my program?。除非您只需要几个盒子来手动​​清理,否则也不建议这样做。另外,通过修改其条件将自定义操作设置为不运行,不要删除自定义操作。

清理

所以我想我们还有几个选择:

  1. 在msiexec.exe命令行上找到我们可以硬编码为0或取消定义(将其设置为空字符串)的自定义操作条件中使用的PUBLIC属性,防止自定义操作运行。请注意,可能没有在命令行上覆盖的条件 - 它取决于设置设计。

    • 这可能有效,但如果通过AppSearch,自定义动作或其他一些机制设置MSI本身内部属性,那么它可能不可靠(MSI具有很多"移动部件"以一种可以使成年男子哭泣的方式相互作用)。这可能会间歇性地发生 - 换句话说,它可能不会在所有系统上发生。突然它只是爆炸了。相应地适用偏执狂。只是我的两分钱。
    • 供应商也可以使用该属性来专门禁止重启对话框 - 在这种情况下您可以使用它,但如果供应商已经这样做,我会非常惊讶。显示这样的自定义重新启动对话框显示缺乏如何使用MSI的知识。但请参阅下面ISSCHEDULEREBOOT的最后一个要点...
    • 条件必须评估为false。因此,如果将DOREBOOT指定为条件,则必须将其设置为等于命令行上的空字符串。这"取消定义"它 - 该属性在MSI会话中不存在。换句话说,设置DOREBOOT = 0不会产生错误的条件! (如果自定义操作仅以DOREBOOT为条件 - 那么条件中没有指定值,并且检查属性是否具有值。任何指定的值都会将条件评估为真 ):

      msiexec.exe /x {11111111-1111-1111-1111-1111111111GH} DOREBOOT=""
      
    • 如果将DOREBOOT=1指定为自定义操作的条件,则必须将属性值设置为等于其他值(以使条件评估为false):

      msiexec.exe /x {11111111-1111-1111-1111-1111111111GH} DOREBOOT=0
      
    • 如果上述情况不够复杂 - DOREBOOT属性必须列为" 安全"通过将其添加到此类安全自定义属性的列表中的属性。保存此列表的属性称为SecureCustomProperties。它是允许为非管理员用户传递到延迟安装模式的属性的分隔列表。未能将DOREBOOT属性添加到此列表将导致此日志文件警告:" 忽略不允许的属性DOREBOOT " - 您设置的任何值都将被忽略,并且不起作用。如果计划安装,重启仍然会发生。
    • UPDATE :在另一个有趣的转折中,看起来从提升的命令提示符启动的msiexec.exe会话实际上接受在命令行上指定的属性值,即使它们未设置为安全(假设您以管理员身份运行),但是当您从非提升的命令提示符启动然后通过UAC对话框提升时 - 然后刷新属性并且不会在会话中应用。 错误或功能?我不知道哪个 - 当然是出乎意料的和高惊讶因素" 。 Windows EnableUserControl等Windows Installer系统策略也可能与unpredictable results一起发挥作用。这里有一股真正的MSI臭虫。
    • 因此请更新SecureCustomProperties以包含DOREBOOT(或同等属性)。这在Property表中完成。
    • 总之:出于所有实际目的,这个选项通常只是理论上的一个选项"。俗话说:理论上理论与实践没有区别,但在实践中有。然而...
    • Installshield设置似乎有一个名为ISSCHEDULEREBOOT的属性,用于调整ScheduleReboot自定义操作。 可能可以使用此属性来禁止重新启动 - 在Installshield制作的设置中(仅限),因为它也会自动标记为安全。
    • 如果您通过部署系统(SCCM)进行部署,部署用户可能拥有所有这些必需的权限和权限,并且上述问题可能不会浮出水面,但在较为随意部署的较小公司中这可能会有所不同。
    • 太多的离题,让我们选择应该有效的选项。
  2. 为问题MSI创建次要升级,将其应用为次要升级或次要升级修补程序包(较小的文件大小,更复杂)。然后像上面一样使用上面的命令行调用程序包的卸载(同时设置REBOOT=ReallySuppress)。

    • 这将是"修补程序"调用卸载序列之前系统上的缓存MSI数据库。这意味着我们可以禁用有问题的自定义操作(通常我们可以在缓存MSI中覆盖我们想要的任何内容)。
    • 我多次使用过这种方法,对于任何部署范围(超过几台机器)而言,这是我唯一推荐的方法。
  3. 实施

    对于大规模部署,我会选择选项2 - 尽管这非常麻烦。为了开始,get hold of a tool capable of viewing an MSI file并打开有问题的MSI。在“自定义操作”表中查找可能与此类对话框相关的任何自定义操作。也许它说" ShowRebootDialog"或类似的。

    找到候选自定义操作后,请在InstallExecuteSequence表中找到它(我还要检查InstallUISequence - 以防万一您使用最少的GUI运行而不是禁止GUI )。 自定义操作是否具有关联条件?如果是这样,您可以通过命令行将此类条件设置为始终为false,如上面选项1中所述 - 在这种情况下,自定义操作将永远不会跑。但正如所解释的那样:只有在问题属性未设置在设置本身内时才可靠。

    次要升级需要新的包GUID和递增的版本号(通常是第三个版本号)。在MSI中设置并保存 - 使用与以前相同的文件名。如果您使用的是Orca,可以通过为{Package}编写View => Summary Information... => New GUID来执行此操作,然后在Property表中调整ProductVersion属性。

    1. 在您的清理包/脚本中,您现在必须首先安装次要升级some help material) - 此命令以交互方式运行以进行测试(为静默模式添加/ QN) :

        msiexec.exe /i YourSetup.msi REINSTALLMODE=vomus REINSTALL=ALL
      
    2. 成功安装次要升级后,您可以以正常方式调用卸载序列。 PUH!如果次要升级正常运行,您应该最终成功禁止重启对话框 - 此命令以交互方式运行以进行测试(为静默模式添加/ QN)。

        msiexec.exe /x {11111111-1111-1111-1111-1111111111GH} REBOOT=ReallySuppress
      
    3. 可能有一种我没想过的简单方法。上面链接的TRANSFORMS hack应该可行 - 但是对我来说这太难看了。这种黑客攻击会在你最不期望的时候破解(例如在Windows更新之后 - 新的限制和功能会堵塞漏洞)。你的风险。当您在实际受保护的位置直接写入注册表时,"实现细节" (引擎的内部),然后关于可能发生的事情的所有赌注都是关闭的(例如,不同的行为可能导致不同的操作系统版本,并且更新可以锁定事物以命名但有两件事 - 您还需要一个包来部署转换本身,破解注册表,然后启动卸载 - 通常比使用内置的MSI功能更复杂和更脆弱。通过API,不要直接)。

      由于在无提示模式下运行时隐藏了UAC提示(高程失败而没有警告 - 除了日志文件 - 如果已创建),您必须在安静地运行这些命令行时使用管理员权限。将/QN添加到每个命令行。要添加日志记录,请添加/L*V "C:\msilog.log"快速示例(记住管理员权限):

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

      或者,为所有MSI安装启用日志记录。有关如何执行此操作,请参阅installsite.org on logging(部分" 全球所有机器上的设置")。我更喜欢为dev-box打开这个默认日志记录,但它确实会影响安装性能,并且会在temp文件夹中添加大量日志文件(你可以偶尔使用一次)。通常你会突然看到一个MSI错误,并且你希望你有一个日志 - 现在你可以随时准备好%tmp%.

答案 1 :(得分:0)

这里可能有两个问题:

  1. 该消息似乎不是重新启动的标准Windows Installer请求。这意味着它来自一个自定义动作,所以它只是一些代码不关心控制重启的任何MSI选项。如果您没有创作MSI并且无法更改它,那么您无法做任何事情。

  2. 如果您对已安装的产品进行静默卸载,那么您将不会被告知它是否失败,因为无声表示没有UI。特别是,如果卸载需要提升,那么如果在任何地方需要管理员权限,它将失败。另一方面,由于某些其他原因,它可能会失败。如果您通过某些UI或进度条显示正常尝试卸载会发生什么?此外,如果您向uniunstall添加日志记录,您可能会看到错误。添加类似/ l * vx [日志文件的路径]