如果已安装,则跳过 MSI

Posted

技术标签:

【中文标题】如果已安装,则跳过 MSI【英文标题】:Skip MSI if already installed 【发布时间】:2017-07-24 09:39:30 【问题描述】:

我有一个 WIX 安装程序,用于安装我的程序和 .NET Core 1.0.5。 .NET Core 以静默模式安装:

<ExePackage InstallCommand="/q" Id = "DotNetCore.Setup" SourceFile="..\DotNetCore\DotNetCore.exe" />

在干净的系统上,安装程序运行良好。如果我尝试重新安装它,我会重新启动。可能检测到 .NET 安装程序已安装并自行触发修复功能。如果 .NET Core 已经安装,有什么方法可以跳过它的安装?

我尝试查找命令行参数,但似乎没有任何用处

【问题讨论】:

【参考方案1】:

ExePackage 元素具有 DetectCondition 属性。这意味着您可以指定一个条件,如果条件评估为假,则将安装包。您可以将其与 util:RegistrySearch 元素结合使用,该元素可用于搜索注册表以检测 .NET Core 是否已安装。

为了执行注册表搜索,您首先需要找到安装 .NET 时存在的注册表项。

找到“HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\”, (或 64 位计算机上的“HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\”)键在您的注册表中,然后找到与 .NET Core 对应的子键 - 该键应该具有“DisplayName”的值" 应该是 ".NET Core" 或类似的东西。

一旦找到正确的密钥,其名称应为十六进制字符串 - 这是与 .NET Core 程序对应的 GUID 之一。然后,您可以使用以下代码允许安装程序搜索此密钥的存在:

<util:RegistrySearch Id="VCRedistTest32" Root="HKLM" Key="SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\YOUR_GUID_HERE" Result="exists" Variable="DOTNETPresent" Win64="no"/>

(使用 Win64="yes" 代替 64 位注册表)

然后您可以对 ExePackage 使用以下内容:

<ExePackage InstallCommand="/q" Id = "DotNetCore.Setup" SourceFile="..\DotNetCore\DotNetCore.exe" DetectCondition="DOTNETPresent"/>

不要忘记将 util 扩展的引用添加到*** wix 元素:

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
 xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">

【讨论】:

【参考方案2】:

如果安装了 .net Core,您需要使用 DetectCondition 属性和注册表搜索来分配属性。

ExePackage Element - DetectCondition

“确定包是否存在于目标系统上的条件。此条件可以使用内置变量和搜索返回的变量。此条件是必要的,因为 Windows 不提供检测包是否存在的方法ExePackage。Burn 使用此条件来确定在捆绑操作期间如何处理此包;例如,如果此条件为假或省略并且正在安装捆绑包,则 Burn 将安装此包。

【讨论】:

非常感谢!您能否提供条件来确定是否安装了 .net 核心?如果我可以强制“安装”安装,我什至可以避免检测条件 安装后需要检查注册表。一个完整的例子你可以在这里查看firegiant.com/wix/tutorial/net-and-net/bootstrapping

以上是关于如果已安装,则跳过 MSI的主要内容,如果未能解决你的问题,请参考以下文章

如果对象为空,则跳过 for 循环

如果 wget 中已经存在文件,则跳过下载?

如果函数内部的条件失败,则跳过 bash while 循环

如果无法使用 DataContractSerializer 反序列化密钥,则跳过字典条目

Graphql:如果参数类型为字符串则跳过参数

Python:如果条件为真,则跳过 For 循环中的迭代