卸载 MSI-Package 总是给出重启消息 [英] Uninstalling MSI-Package always gives reboot message

查看:31
本文介绍了卸载 MSI-Package 总是给出重启消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是在为一些新软件编写一些脚本.因此我必须删除一些旧软件.我正在用 PS 脚本执行此操作.这几乎可以正常工作.提升的权限正在工作,软件被删除,但第一次卸载时总是有一条关于重新启动的消息.此消息只能通过按确定"来确认.

I'm just scripting something for some new software. Therefore i have to remove some older software. I'm doing this whit a PS script. This works almost fine. The elevated rights are working, the software got removed, but there is always a message from the first uninstalling concerning a reboot. This message must only be acknowledged by pressing 'OK'.

现在如何强制消息不出现?

Now how can I force the message not coming up?

这是我在 PS-Script 中的内容:

This is what I have in the PS-Script:

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

我也尝试了/quiet 标志,但我什么也没看到(d'uh)而且软件仍然存在.

I tried also the /quiet flag, but than i see nothing (d'uh) and the software is still there.

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

That i have to do a restart is logical, but i just don't want to see the message. I'm not sure if it is a message from MSIEXEC or from the MSI-file itself. Google could not find a thing.

推荐答案

UPDATE:事后想:检查这个对话框是否真的从 InstallUISequence 显示?如果它仅插入到 InstallUISequence 中而不出现在 InstallExecuteSequence 中,那么当您为设置触发静默安装/卸载时它永远不会运行,因为整个 InstallUISequence 在这种安装模式下被跳过.

UPDATE: After the fact thought: check if this dialog is actually showing from the InstallUISequence? If it is only inserted into the InstallUISequence and not present in the InstallExecuteSequence, then it will never run when you trigger silent install / uninstall for your setup since the whole InstallUISequence is skipped in this installation mode.

QN 添加到 msiexec.exe 命令行以静默运行.请参阅下面的示例.如果幸运的话,这可以解决您的整个问题,而无需进行下面提到的任何小升级或黑客攻击.所以检查一下.还要将 REBOOT=ReallySuppress 添加到所有静默 msiexec.exe 命令行 - 以防止标准 MSI 功能触发突然重启.

Add QN to the msiexec.exe command line to run silently. See samples below. If you get lucky, this could solve your whole problem without any of the minor upgrades or hacks mentioned below at all. So check it. Do add REBOOT=ReallySuppress to all silent msiexec.exe command lines as well - to prevent standard MSI features from triggering a sudden reboot.

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

There is a property called REBOOT in MSI files that can be set to REBOOT=ReallySuppress on the msiexec.exe command line in order to suppress standard MSI scheduled reboots. This is especially important for silent installs which could otherwise trigger a spontaneous reboot without warning (for very badly authored MSI files with design errors - I always disable ScheduleReboot and ForceReboot when making packages for corporate use - rebooting knowledge workers' PCs without warning can wipe out a lot of work):

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

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

I would also use the old-style msiexec.exe switches: /x, /i, etc... rather than the "convenience functions": /passive, /norestart, etc... Just my two cents.

供参考:

但是,您发布的对话框似乎不标准.它实际上看起来像是从设置本身的自定义操作中显示的自定义对话框 - 这些不符合 MSI 标准,您必须逐案处理.

However, the dialog you posted seems non-standard. It actually looks like a custom dialog shown from a custom action in the setup itself - these will conform to no MSI standard and you must deal with them on a case-by-case basis.

我想这是一个安全的假设,即您要卸载的软件已经在野外"并且安装在您试图从中删除它的许多工作站上?鉴于这是一个正确的假设,我们在谈论多少台计算机进行清理?许多?数百?几千?如果 MSI 未生效,您可以调整它以在部署前通过转换删除对话框.只是为了将来提及这一点.从技术上讲,您可以通过将自定义操作的条件设置为 0(如果为 false - 那么自定义操作将永远不会运行)来实现.

I guess it is a safe assumption that the software you seek to uninstall is already "in the wild" and installed on a number of workstations that you are trying to remove it from? Given that this is a correct assumption, how many computers are we talking about for cleanup? Dozens? Hundreds? Thousands? If the MSI was not live, you could have tuned it to remove the dialog with a transform before deployment. Just mentioning this for the future. Technically you can do this by setting the condition for the custom action to 0 (for false - then the custom action will never run).

题外话:有一个可怕的黑客"我从未尝试过,我只会作为支持人员使用它来清理一台计算机:如何在卸载时应用 Msi 转换? 我不会使用它(除非我是清理单个 PC - 例如开发箱).

Digression: There is a terrible "hack" that I have never tried that I would only use for a single computer cleanup as a support person: How to apply a Msi transform at uninstall? I wouldn't use it (unless I was cleaning up a single PC - such as a dev box).

也可以直接编辑缓存的MSI(至少先做好备份):我搞砸了,我该如何卸载我的程序?.这也不推荐,除非您只有几个盒子需要手动清理.另外,通过修改条件将自定义动作设置为不运行,不要删除自定义动作.

It is also possible to directly edit the cached MSI (at least make a backup first): I screwed up, how can I uninstall my program?. This is not recommended either, unless you just have a couple of boxes to manually clean up. Also, set the custom action to not run by modifying its condition, do not delete the custom action.

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

So I guess we are left with a couple of options:

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

  1. Find a PUBLIC property used in the custom action condition that we can hard code to 0 or undefine (set it equal to an empty string) on the msiexec.exe command line preventing the custom action from running. Note that there might not be a condition to override on the command line - it depends on the setup design.

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

  • This might work, but isn't super reliable if that property is set inside the MSI itself as well via AppSearch, custom actions or some other mechanism (MSI features a lot of "moving parts" that interact in ways that can make a grown man cry). This could happen intermittently as well - in other words it might not happen on all systems. Suddenly it just blows up. Apply suitable paranoia accordingly. Just my two cents.
  • The property can also have been made by the vendor to specifically allow the reboot dialog to be suppressed - in this case you can use it, but I would be very surprised if a vendor has done this. Showing such a custom reboot dialog shows lacking knowledge of how MSI should be used. But see the last bullet point on ISSCHEDULEREBOOT below...
  • The condition must evaluate to false. So if DOREBOOT is specified as a condition it has to be set equal to an empty string on the command line. This "undefines" it - the property doesn't exist in the MSI session. In other words setting DOREBOOT=0 will not yield a false condition! (if the custom action is conditioned with only DOREBOOT - then there is no value specified in the condition and the check is for whether the property has a value at all. Any assigned value will evaluate the condition to true):

msiexec.exe /x {11111111-1111-1111-1111-1111111111GH} DOREBOOT=""

  • 如果 DOREBOOT=1 被指定为自定义操作的条件,那么您必须将属性值设置为等于其他值(以使条件评估为假):

  • If DOREBOOT=1 is specified as condition for the custom action, then you must set the property value equal to something else (to make the condition evaluate to false):

    msiexec.exe /x {11111111-1111-1111-1111-1111111111GH} DOREBOOT=0
    

  • 更复杂的是 - 好像以上还不够 - 必须将 DOREBOOT 属性列为安全"属性,方法是将其添加到此类安全自定义属性列表中.包含此列表的属性称为 SecureCustomProperties.它是一个分隔的属性列表,允许为非管理员用户传递到延迟安装模式.未能将 DOREBOOT 属性添加到此列表将导致此日志文件警告:忽略不允许的属性 DOREBOOT" - 您为其设置的任何值都将被忽略并且没有影响.如果计划重启,重启仍然会发生.
  • 更新:在另一个有趣的转折中,从提升的命令提示符启动的 msiexec.exe 会话实际上确实接受命令行上指定的属性值,即使它们未设置为安全(假设您以管理员身份运行),但是当您从非提升的命令提示符启动,然后通过 UAC 对话框提升时 - 属性将被刷新并且不会在会话中应用.错误或功能?我不知道是哪一个 - 当然是出乎意料的和高度惊讶的因素".Windows Installer 系统策略,例如 EnableUserControl 也可能在此处产生不可预测的结果.这里有一种真正的 MSI 错误的味道.
  • 因此更新 SecureCustomProperties 以包含 DOREBOOT(或等效属性).这是在属性表中完成的.
  • 总而言之:出于所有实际目的,此选项通常只是理论上"的选项.俗话说:理论上没有理论和实践的区别,但在实践中却有.然而...
  • Installshield 设置似乎有一个名为 ISSCHEDULEREBOOT 的属性,它可以调节 ScheduleReboot 自定义操作.可能可以使用此属性来抑制重新启动 - 在 Installshield 制作的设置中(仅限),因为它也会自动标记为安全.
  • 如果您通过部署系统 (SCCM) 进行部署,则部署用户可能拥有所有这些必需的特权和权限,上述问题可能不会出现,但在部署较为随意的小公司中,情况可能有所不同.
  • 离题太多了,让我们来看看应该可行的选项.
  • And in a twist of further complexity - as if the above isn't enough - the DOREBOOT property must be listed as a "Secure" property by adding it to the list of such secure custom properties. The property which holds this list is referred to as SecureCustomProperties. It is a delimited list of properties allowed to pass to deferred installation mode for non-admin users. Failing to add the DOREBOOT property to this list will cause this log file warning: "Ignoring disallowed property DOREBOOT" - and any value you set to it will be ignored and have no effect. And the reboot will still happen if it is scheduled to.
  • UPDATE: In another interesting twist it looks like an msiexec.exe session launched from an elevated command prompt actually does accept property values specified on the command line even if they are not set as secured (given that you are running as admin), but when you launch from a non-elevated command prompt and then elevate via the UAC dialog - then the properties are flushed and will not apply in the session. Bug or feature? I don't know which - certainly unexpected and "high astonishment factor". Windows Installer system policies such as EnableUserControl may also come into play here with unpredictable results. There is a smell of real MSI bugs here.
  • So Update SecureCustomProperties to include DOREBOOT (or equivalent property). This is done in the Property table.
  • In conclusion: for all practical purposes this option is generally only an option "in theory". As the saying goes: in theory there is no difference between theory and practice, but in practice there is. However...
  • Installshield setups seem to have a property called ISSCHEDULEREBOOT that conditions the ScheduleReboot custom action. It might be possible to use this property to suppress a reboot - in Installshield-made setups (only), because it will also be marked as secure automatically.
  • If you deploy via a deployment system (SCCM) the deploying user probably has all these required privileges and permissions and the problems above may not surface, but this may be different in smaller companies with more haphazard deployment.
  • Way too many digressions, let's get to the option that should work.
  • 为有问题的 MSI 创建次要升级,将其应用为次要升级或次要升级补丁包(文件更小,制作更复杂).然后像以前一样使用上面看到的命令行调用包的卸载(同时设置 REBOOT=ReallySuppress).

    Create a minor upgrade for the problem MSI, apply it either as a minor upgrade or as a minor upgrade patch package (smaller file size, more complex to make). Then call the uninstall for the package as before with the command line seen above (with REBOOT=ReallySuppress set as well).

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

    <小时>

    实施

    对于大规模部署,我会选择选项 2 - 尽管它非常麻烦.要开始,获取能够查看 MSI 文件的工具 并打开有问题的 MSI.在自定义操作表中查找可能与此类对话框相关的任何自定义操作.也许它说ShowRebootDialog"或类似的东西.


    Implementation

    For large scale deployment I would choose option 2 - although it is very much a hassle. To get going, get hold of a tool capable of viewing an MSI file and open the MSI in question. Look in the Custom Action table for any custom action that could be related to such a dialog. Maybe it says "ShowRebootDialog" or similar.

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

    Once you find a candidate custom action, locate it in the InstallExecuteSequence table (I'd check in the InstallUISequence as well - just in case you run with minimal GUI and not suppressed GUI). Does the custom action have an associated condition? If so you might be able to set such a condition by command line to always be false, as explained above in option 1 - in which case the custom action will never run. But as explained: only reliable if the property in question isn't set inside the setup itself.

    次要升级需要一个新的包 GUID 和一个递增的版本号(通常是第三个版本号).在您的 MSI 中设置并保存它 - 使用与以前相同的文件名.如果您正在使用 Orca,您可以通过 View =>摘要信息... =>PackageCode 的新 GUID,然后调整 Property 表中的 ProductVersion 属性.

    A minor upgrade needs a new package GUID and a incremented version number (generally the third version number). Set this in your MSI and save it - use the same file name as before. If you are using Orca you can do this by going View => Summary Information... => New GUID for PackageCode, and then you tweak the ProductVersion property in the Property table.

    1. 在您的清理包/脚本中,您现在必须首先安装次要升级(一些帮助材料) - 此命令以交互方式运行以进行测试(添加/QN 用于静默模式):

    1. In your cleanup package / script you must now first install the minor upgrade (some help material) - this command runs interactively for your testing (add /QN for silent mode):

      msiexec.exe /i YourSetup.msi REINSTALLMODE=vomus REINSTALL=ALL
    

  • 成功安装次要升级后,您可以以正常方式调用卸载序列.呸!如果次要升级运行正常,您应该最终成功抑制了重启对话框 - 此命令以交互方式运行以进行测试(添加/QN 用于静默模式).

  • Once the minor upgrade is successfully installed you can call the uninstall sequence the normal way. Puh! Provided the minor upgrade ran properly you should finally have successfully suppressed the reboot dialog - this command runs interactively for your testing (add /QN for silent mode).

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

  • 可能有一种我没有想到的更简单的方法.链接到上面的 TRANSFORMS hack 应该可以工作 - 但它太丑了,我无法尝试.此类黑客攻击往往会在您最意想不到的时候崩溃(例如,在 Windows 更新之后 - 新的限制和功能可以弥补漏洞).你的风险.当您在实际受保护的位置和实现细节"(引擎内部)直接写入注册表时,所有的赌注都不会发生(例如,不同的操作系统版本可能会导致不同的行为,更新可以将事情锁定,但有两件事 - 您还需要一个包来部署转换本身,破解注册表,然后开始卸载 - 通常比使用内置的 MSI 功能更复杂和易受攻击.通过 API,不要不要直接去).

    There might be a simpler way that I haven't thought of. The TRANSFORMS hack linked to above should work - but it is too ugly for me to try. Such hacks tend to break when you least expect it (after Windows Updates for example - new restrictions and features close the loophole). Your risk. When you write directly to the registry in locations that are actually protected and "implementation details" (the internals of the engine), then all bets are off as to what might happen (different behavior may result on different OS versions for example, and updates can lock things to name but two things - you also need a package to deploy the transform itself, hack the registry and then to kick off the uninstall - generally more complex and vulnerable than using built-in MSI features. Go via APIs, don't go direct).

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

    Since the UAC prompt is hidden when running in silent mode (elevation fails without warning - except in the log file - if created), you must use admin rights when running these command lines quietly. Add /QN to each command line. To add logging, add /L*V "C:\msilog.log". Quick sample (remember the admin rights):

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

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

    Alternatively, enable logging for all MSI installations. See installsite.org on logging (section "Globally for all setups on a machine") for how to do this. I prefer this default logging switched on for dev-boxes, but it does affect installation performance and adds a lot of log files to the temp folder (that you can just zap once in a while). Typically you suddenly see an MSI error and you wish you had a log - now you can, always ready in %tmp%.

    这篇关于卸载 MSI-Package 总是给出重启消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆