第二轮:
MigrateFeatureStates:我看到你更新了你的问题。看起来您正在处理功能。我假设您正在使用从版本 1 到版本 2 的重大升级?首先,标准 MSI 操作 MigrateFeatureStates 将尝试“保留”主要升级的功能安装状态 - 如果主要升级在 Upgrade table(属性列)中配置为这样做,只需提一下。
特征属性:换句话说,如果您不设置任何特征属性(ADDLOCAL、ADDSOURCE、@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 源中获取 - 该链接只是以供参考)。该脚本默认获取可能出现在您的盒子上的常见运行时包的功能状态。
我想这会产生一些现实世界的选择:
- 依靠 MigrateFeatureStates 在版本 2 中添加任何新功能。新功能必须设置为默认安装。
- 通过自定义操作或功能条件设置功能属性。
- 使用 MSI API 检索当前安装的功能状态,并使用自定义命令行设置功能属性通过 msiexec.exe 安装新版本。
- 让用户在 GUI 中以交互方式添加他们需要的功能。
- 我忘记了什么。
很容易扩展此脚本以报告所有已安装 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 @、Dictionaries、SDK、Help、Tutorials 等...),那么这可以通过the MSI API 实现。我不熟悉通过msiexec.exe 命令行检索功能安装状态的方法。
组件:如果您指的是 MSI 组件(安装程序的原子位,分配给用户可选择的功能,但用户从未直接看到),那么我不完全理解您要达到的目标。 ADDLOCAL 是Feature Installation Options Properties 之一,它仅影响功能安装状态,它仅间接影响组件(分配给您所指功能的组件)。
重大升级:我想知道您是否没有实施适当的重大升级,这是您遇到的真正问题。请用更多信息更新您的问题。正确实施的主要升级将安装任何新组件、删除过时的组件并安装您添加的任何新功能。在我再写之前,请先澄清你的问题。
我有一个 VBScript,它将检索您指定的产品(或所有已安装的 MSI 文件)的当前功能状态。如果这确实是你所追求的。