安装时卸载另一个 MSI
我有一个基本的 MSI 项目。我需要在安装时删除另一个 MSI 产品,该产品现已集成到我们的主应用程序中。我尝试使用升级场景并将其视为重大升级。但是,这不起作用,因为我相信升级代码不匹配。
接下来,我还执行了一个自定义操作,在 CostFinalize 之后运行 msiexec.exe(我认为 Installshield 帮助中已说明这一点)。直到我安装在没有我要删除的安装程序的系统上之前,该操作一直运行良好。如果未安装其他过时的产品,我的安装程序将会失败。我尝试对系统搜索设置的自定义操作设置条件,但系统搜索的功能似乎受到限制。我不能只检查注册表项并设置布尔属性。
有什么想法吗?
I have a Basic MSI project. I need to remove another MSI product on installation that is now integrated into our main application. I tried to use the upgrade scenarios and treat it as a major upgrade. However, this didn't work because of the upgrade codes not matching I believe.
Next, I also made a custom action that ran msiexec.exe after the CostFinalize (I think this was stated in the Installshield help.) This worked perfectly until I installed on a system that didn't have the installer I was looking to remove. My installer would fail if the other obsolete product was not installed. I tried to put a condition on the custom action set by the system search, but it seems the system search is limited in functionality. I can't just check a reg key and set a boolean property.
Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
需要考虑的一些事项
1) UpgradeTable ( FindRelatedProducts / RemoveExisting Products ) 可用于删除与另一个产品的 UpgradeCode 关联的 ProductCode。
2) 如果内存可用,MSI 将不会在每台机器安装期间删除每用户产品(或反之亦然)。上下文必须相同。
3) UI 序列在静默安装期间不会运行。
4) 您无法从执行序列运行 msiexec,因为系统范围的互斥体每台机器只有一个执行序列。
5) 如果您在 UI 中进行安排(我已经告诉过您,您不应该这样做,因为它不会在静默安装期间运行),还有另一个互斥体表示每个进程只有 1 个 UI。
如果您要从每用户到每用户或从每台机器到每台机器,我认为您应该能够使用升级元素/表行执行您想要的操作,而无需编写自定义操作。否则,您将需要一个 setup.exe 样式的引导程序来在进入 msiexec 世界之前处理卸载。
A few things to consider
1) The UpgradeTable ( FindRelatedProducts / RemoveExisting Products ) can be used to remove ProductCodes associated with another product's UpgradeCode.
2) If memory serves, MSI won't remove a Per-User product during a Per-Machine install ( or the other way around ). The context has to be the same.
3) The UI Sequence doesn't run during silent installs.
4) You can't run msiexec from the execute sequence because there is a system wide mutex of only one execute sequence per machine.
5) If you schedule in UI ( I already told you that you shouldn't since it doesn't run during silent installs ) there is another mutex that says only 1 UI per process.
If you are going from per-user to per-user or per-machine to per-machine, I would think it's reasonaable you should be able to do what you want using Upgrade elements / table rows without writing custom actions. Otherwise you'll need a setup.exe style bootstrapper to handle the uninstall prior to entering the msiexec world.
我在 InstallShield 2013 中使用自定义 InstallScript 实现了这一点。该脚本是通过 UI 序列中的自定义操作执行的,但我将其放置在“SetupProgress”对话框之后,即“执行操作”之前,而不是 CostFinalize 之后(如文档所述)。我在操作中添加了“未安装”条件。如果您按照建议的顺序放置此命令,安装程序初始化后它将立即开始卸载。如果您将其移至我所做的位置,则直到用户单击“立即安装”按钮后,它才会启动。
将其放在 UI 序列中的原因是为了解决一次只安装一个 msi 安装程序(或卸载程序)的问题。由于该限制,这在执行序列中根本不起作用。
这种方法的主要弱点是,正如 Christopher 所说,这在静默安装中不起作用(这也可以在 IS 文档中找到)。但这是实现这一目标的官方手段。 (查看:http://helpnet.installshield.com/installshield16helplib/IHelpCustomActionMSIExec.htm )如果您可以接受这一点(因为静默安装通常是特殊情况),那么这就可以了。
正如 Chris 还所说,当主 ui 运行时,您无法启动卸载程序 ui,但这对我的脚本来说不是问题,因为它添加了一个命令行开关来在没有 ui 的情况下运行卸载程序(即静默)。
我的脚本还避免了必须知道要卸载的应用程序的 guid。以下是绑定到自定义操作的脚本(UninstallPriorVersions 是入口点函数):
I achieved this in InstallShield 2013 using custom InstallScript. The script is executed via a custom action in the UI sequence, but I placed it after the "SetupProgress" dialog, i.e. before "Execute Action" instead of after the CostFinalize (as the documentation does say). I added the condition "NOT Installed" to the action. If you place this in the suggested order, it will kick off the uninstallation as soon as the installer has initialized. If you move it to where I did, it doesn't kick off until the user has clicked the final install now button.
The reason to put this in the UI sequence is to get around the one msi installer (or uninstaller) at a time problem. This simply doesn't work in the execution sequence because of that restriction.
The primary weakness in this method is that as Christopher stated, this won't work in a silent install (that is also found in the IS documentation). That is the official means for achieving this though. (check out: http://helpnet.installshield.com/installshield16helplib/IHelpCustomActionMSIExec.htm) If you can live with that (since silent install is generally as special case scenario), then this works just fine.
As Chris also said, you can't launch the uninstaller ui while the primary ui is running, but that's not a problem with my script because it adds a command line switch to run the uninstaller without the ui (i.e. silently).
My script also avoids having to know the guid of the application you want to uninstall. Here's the script to bind to the custom action (UninstallPriorVersions is the entry point function):