【问题标题】:ADDLOCAL=FEATURE1 in MSI installer removes other FEATURESMSI 安装程序中的 ADDLOCAL=FEATURE1 删除其他 FEATURES
【发布时间】:2020-07-08 18:44:03
【问题描述】:

我正在尝试在 setup.exe(1.0) 之上使用 wix 安装程序 setup.exe(2.0) 安装 FEATURE_NEW 之一 setup.exe /v /qn ADDLOCAL=FEATURE_NEW

它会安装 FEATURE_NEW,但问题是,它会删除其他功能 FEATURE1、FEATURE2 等。

我希望升级现有功能并安装新的 FEATURE_NEW,不应安装额外的 FEATURES。

所以我的问题是我可以使用以前安装的功能列表“N”加上新添加的功能(即 N + NEW_FEATURES)来安装/升级产品。 我正在搜索类似的东西,

setup.exe /v /qn ADDLOCAL=INSTALLED_FEATURES,FEATURE_NEW

【问题讨论】:

  • ADDLOCAL 属性控制功能安装而不是组件。
  • 好的,既然你更新了你的问题,我添加了我提到的脚本。您应该阅读整个答案 - 我认为您不想通过msiexec.exe 命令行执行此操作,而是通过另一种机制(功能条件、自定义操作等)。

标签: wix windows-installer


【解决方案1】:

第二轮

MigrateFeatureStates:我看到你更新了你的问题。看起来您正在处理功能。我假设您正在使用从版本 1 到版本 2 的重大升级?首先,标准 MSI 操作 MigrateFeatureStates 将尝试“保留”主要升级的功能安装状态 - 如果主要升级在 Upgrade table(属性列)中配置为这样做,只需提一下。

特征属性:换句话说,如果您设置任何特征属性(ADDLOCALADDSOURCE、@987654325 @、ADVERTISE 等...),那么您的新版本应该继承您的第一个版本的功能结构并自动安装任何新功能(前提是它们被设置为默认安装)。

MSI API:基于此,我不确定您是否有必要添加特定功能,但如果您的功能不是 设置为默认安装。如前所述,我不知道通过命令行检索当前功能状态的方法(可能有一个),但您可以使用MSI API,然后通过 MSI API 或命令行调用新安装(或其他方式)。

特征操作:我有一个过时的 VBScript,我可以快速适应生成 msiexec.exe 命令行来进行特征状态操作,但在开始之前应该提到它您可以使用多种机制您的 MSI 包中来控制功能选择:How to install feature based on the property set in custom action? 本质上您可以使用自定义操作来随意操作功能选择。您可以详细检查系统以确定应该安装哪些功能,而不应该安装哪些功能。您还可以使用特征条件来影响特征选择,而无需一行代码(无需自定义操作)。请参阅上面的链接答案(推荐)。此答案中还有一个关于“MSI 功能”的部分试图解释它:Wix Installer : Setting component condition property when doing a MSIEXEC admin install at command line

GUI 功能操作:我还想补充一点,如果您的 GUI 包含您可以看到的自定义对话框屏幕,您显然可以更改 MSI GUI 中的功能状态即将在系统上安装的功能。

总结:总而言之,您可以在 MSI 中通过功能条件自定义操作来操作功能- 您还可以让用户在 GUI 中以交互方式和手动方式更改功能选择。如果这还不够,您可以使用 MSI API 检索已安装 MSI 的功能状态,如下面的 VBScript 所示。该脚本生成的是一个命令行 sn-p,它将复制已安装的功能状态,以及您在脚本中指定位置所做的任何添加。您需要输入您想要获取功能状态的 MSI 的产品代码:How can I find the product GUID of an installed MSI setup?(只需从 MSI 的属性表或 WiX 源中获取 - 该链接只是以供参考)。该脚本默认获取可能出现在您的盒子上的常见运行时包的功能状态。

我想这会产生一些现实世界的选择:

  1. 依靠 MigrateFeatureStates 在版本 2 中添加任何新功能。新功能必须设置为默认安装。
  2. 通过自定义操作或功能条件设置功能属性。
  3. 使用 MSI API 检索当前安装的功能状态,并使用自定义命令行设置功能属性通过 msiexec.exe 安装新版本。
  4. 让用户在 GUI 中以交互方式添加他们需要的功能。
  5. 我忘记了什么。

很容易扩展此脚本以报告所有已安装 MSI 软件包的所有功能状态(这实际上是脚本在我改编它之前所做的)。


Here is the below script on github.com


On Error Resume Next

Public cmdline

' Sample Product Codes:
  ' Microsoft Visual C++ 2008 Redistributable - x86 9.0.30729.17: {9A25302D-30C0-39D9-BD6F-21E6EC160475}

productcode = InputBox("ProductCode for your MSI:", "ProductCode:","{9A25302D-30C0-39D9-BD6F-21E6EC160475}")
If productcode = vbCancel Or Trim(productcode) = "" Then
   WScript.Quit(0)
End If

' Arrays of current feature states
ReDim ADDLOCAL(-1), ADDSOURCE(-1), ADVERTISE(-1), REMOVE(-1)

Set installer = CreateObject("WindowsInstaller.Installer")
Set productfeatures = installer.Features(productcode)
If (Err.number <> 0) Then
   MsgBox "Failed to open MSI package. Invalid product code?", vbCritical, "Fatal error. Aborting:"
   WScript.Quit(2)
End If

' Spin over all product features detecting installation states
For Each feature In productfeatures

    featurestate = installer.FeatureState(productcode, feature)
   
    ' Using crazy VBScript arrays
    Select Case featurestate
       Case 1 ReDim Preserve ADVERTISE(UBound(ADVERTISE) + 1) : ADVERTISE(UBound(ADVERTISE)) = feature
       Case 2 ReDim Preserve REMOVE(UBound(REMOVE) + 1) : REMOVE(UBound(REMOVE)) = feature
       Case 3 ReDim Preserve ADDLOCAL(UBound(ADDLOCAL) + 1) : ADDLOCAL(UBound(ADDLOCAL)) = feature
       Case 4 ReDim Preserve ADDSOURCE(UBound(ADDSOURCE) + 1) : ADDSOURCE(UBound(ADDSOURCE)) = feature
       Case Else ' Errorstate MsgBox "Error for feature: " + feature
    End Select
    
Next

' Now add whatever feature you need to ADDLOCAL, here is just a sample:
ReDim Preserve ADDLOCAL(UBound(ADDLOCAL) + 1) : ADDLOCAL(UBound(ADDLOCAL)) = "MyNewFeature"

' Flatten arrays
If UBound(ADDLOCAL) > -1 Then cmdline = chr(34) + "ADDLOCAL=" + Join(ADDLOCAL, ",") + chr(34)
If UBound(REMOVE) > -1 Then cmdline = cmdline + + " " + chr(34) + "REMOVE=" + Join(REMOVE, ",") + chr(34)
If UBound(ADVERTISE) > -1 Then cmdline = cmdline + + " " + chr(34) + "ADVERTISE=" + Join(ADVERTISE, ",") + chr(34)
If UBound(ADDSOURCE) > -1 Then cmdline = cmdline + + " " + chr(34) + "ADDSOURCE=" + Join(ADDSOURCE, ",") + chr(34)

' Your current feature installstate translated to msiexec.exe command line parameters
Wscript.Echo cmdline ' MsgBox has 1024 character limit

第一轮

Features:如果要检索当前安装产品的功能安装状态(功能是用户可选择的安装部分:@987654341 @、DictionariesSDKHelpTutorials 等...),那么这可以通过the MSI API 实现。我不熟悉通过msiexec.exe 命令行检索功能安装状态的方法。

组件:如果您指的是 MSI 组件(安装程序的原子位,分配给用户可选择的功能,但用户从未直接看到),那么我不完全理解您要达到的目标。 ADDLOCALFeature Installation Options Properties 之一,它仅影响功能安装状态,它仅间接影响组件(分配给您所指功能的组件)。

重大升级:我想知道您是否没有实施适当的重大升级,这是您遇到的真正问题。请用更多信息更新您的问题。正确实施的主要升级将安装任何新组件、删除过时的组件并安装您添加的任何新功能。在我再写之前,请先澄清你的问题。

我有一个 VBScript,它将检索您指定的产品(或所有已安装的 MSI 文件)的当前功能状态。如果这确实是你所追求的。

【讨论】:

  • 感谢 Stein,详细解答
【解决方案2】:

如果您正在执行 ADDLOCAL,那么您将明确列出您要安装的功能 - 已安装的功能就是您指定的。它不是增量的,也不意味着“也安装这些功能”。例如,它关闭功能条件。如果您想在使用引导程序的主要升级期间添加功能,您可以使用 MsiEumFeatures() 来获取已安装的功能列表,您可以在其中添加新功能。另一种方法是使用自定义操作来解析 ADDLOCAL 字符串,在 MigrateFeatureStates 之后排序,并将新的字符串添加到列表中。

【讨论】:

  • 哎哟。我从没想过 ADDLOCAL 和其他特性属性会关闭特性条件,但我想这是必要的。我从未测试过它。对于由于操作系统问题而无法安装的功能(例如仅平板电脑的功能,或者在旧世界的 ANSI 与 Unicode 文件中的不同功能)似乎不太好。一页纸的大规模部署PDF的更多原因应该是所有设置都应该解释我猜不应该为部署做什么? (另一个是最大化 INSTALLLEVEL 以强制安装所有功能)。
  • 感谢菲尔的回答,我想通过远程我们的升级机制远程执行这个命令。它只能运行 setup.exe /v /qn ADDLOCAL=INSTALLED_FEATURES,FEATURE_NEW 之类的命令,而不是枚举功能和转储功能等。
  • 如果 MSI 在静默模式下运行,MigrateFeatureStatesInstallExecuteSequence 中运行。但是,如果显示设置 GUI,MigrateFeatureStates 仅在 GUI 序列中运行(换句话说,该操作在每次安装时只运行一次 - 它根本不会在其他安装模式下运行 - 例如维护模式或卸载)。在测试期间以及对自定义操作进行排序时需要注意的事项 - 如果您选择这种方法。我没有测试过这种方法。请记住,MigrateFeatureStates 应该自动添加任何新功能 - 无需代码。
  • @stein:指定 ADDLOCAL 无论如何都会关闭 MigrateFeatureStates。
  • 没有选项,INSTALLED_FEATURES 的关键字吗?对于 setup.exe /v /qn ADDLOCAL=INSTALLED_FEATURES,FEATURE_NEW
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多