如何使用 WiX 和 MSI 进行静默安装和卸载?

Posted

技术标签:

【中文标题】如何使用 WiX 和 MSI 进行静默安装和卸载?【英文标题】:How do I do a silent install and uninstall with WiX and MSI? 【发布时间】:2011-02-23 08:21:12 【问题描述】:

如何在 WiX 中创建一个不向用户显示任何 UI 对话框并使用默认设置进行安装、升级和卸载的静默安装程序?

【问题讨论】:

【参考方案1】:

使用 WiX 创建的安装程序 .exe 可以从命令行运行,而无需用户使用以下命令行参数之一进行输入:

/quiet - 不显示任何 UI /passive - 显示 UI,但不需要用户输入。本质上只是显示一个安装进度条

此答案基于 WiX 3.9。

【讨论】:

如何传递安装路径?【参考方案2】:

Windows Installer (MSI) 使用以下命令行参数保持静默:

静默安装或静默主要升级:

msiexec.exe /i foo.msi /qn

静默小升级:

msiexec.exe /i foo.msi REINSTALL=ALL REINSTALLMODE=vomus /qn

静默卸载:

msiexec.exe /x foo.msi /qn

可执行路径:

C:\Windows\system32\msiexec.exe

【讨论】:

很好的答案。一个小问题是,如果您必须通过 UAC 对话框授权安装,则使用 /qn 不会显示任何内容。但是,如果您使用 /qb,您可以选择对其进行授权。 那是设计的功能。静默安装根据定义是非交互式的,UAC 提示是一种交互。未能在 30 秒内单击“是”将导致安装失败。在调用安装之前,您的调用进程应该已经提升。 我也面临同样的问题,当我尝试通过双击 MSI 以全 UI 模式运行 MSI 时,它会提示我一个 UAC(程序名称,发布者:未知,文件来源),我需要选择是继续安装,但我需要在非交互模式下使用 cmd msiexec 命令安装 MSI(基本上它应该在 UAC 中自动选择是)但无论如何都不会发生(/q /a /qn )。我正在使用一个工具在 100 台服务器上部署 MSI,它在内部创建了一个导致失败的命令 (msiexec /i /qn)。有人有解决方案吗?【参考方案3】:

无论是否由 WiX 创建,所有 MSI 安装程序都可以通过命令行参数进行控制。因此,您可以使用 UI 制作安装程序并仍然静默安装,无需从安装程序中删除 UI,只需在命令行中将其抑制即可。请记住,请确保在您的第一个安装程序中添加升级元素,以便后续安装程序匹配

【讨论】:

WiX 升级元素设置 UpgradeCode 属性并在升级表中创建一行。从技术上讲,第一个 MSI 不必具有升级元素。它只需要具有 UpgradeCode 属性。如果您忘记执行此操作,则在后续 MSI 中存在涉及“假”升级表条目的技巧,其中包含将操作属性设置为第一个 MSI 的 ProductCode 的自定义操作。尽量避免这种情况。 :-)【参考方案4】:

只要不包含任何 UI/UIRef 元素,就不会包含任何 UI :)

【讨论】:

价值非常有限。让用户双击 MSI 并在没有任何确认或结果状态的情况下安装它是 IMO 非常不理想的用户体验。如果您在一堆 MSI 中的一部分被另一个处理 UI 的程序(Think Visual Studio、SQL Server..)一起更改,那很好,但如果它是一个独立的 MSI,我认为它只完成了一半。 我同意它的价值绝对有限,但它确实回答了 OP。更好(或“正确”)的解决方案是使用 msiexec 参数,如下所述。 将 msiexec.exe 与命令行参数一起使用,指定无 ui 的安静模式是可行的方法。 @Christopher Painter。在数百台机器上安装企业环境中的任何应用程序都需要使用组策略等过程。拥有一个 UI 不是最理想的,而且会浪费时间迫使员工去公司的每台机器上按下按键,只是在需要新应用的地方。 使用已经提到的“msiexec.exe /i foo.msi /qn”。因此,用户界面是为个人用户和故障排除管理员维护的,并且可以隐藏以进行部署。

以上是关于如何使用 WiX 和 MSI 进行静默安装和卸载?的主要内容,如果未能解决你的问题,请参考以下文章

用Wix手工编辑XML制作C++ MSI安装程序,怎样保证安装新版本时候强制卸载旧版本,急急急!!!

如何从包含多个 MSI 的 wix 自定义引导程序包中安装/卸载单个 msi,例如安装项目的添加/删除功能?

如何在 wix 安装程序中卸载另一个程序?

WiX 3.8:使用相同注册表值的两个MSI。如果同时卸载两个MSI,如何删除注册表值?

Wix 自定义卸载操作 - 如何在 msi 删除文件之前运行

如何使用 WiX 从源代码重建完全相同的 msi 文件?