I am trying install one of FEATURE_NEW using wix installer setup.exe(2.0) on top of setup.exe(1.0)
setup.exe /v /qn ADDLOCAL=FEATURE_NEW
It installs FEATURE_NEW, but issue is, it removes other features FEATURE1,FEATURE2 etc.
I want existing feature should upgrade and new FEATURE_NEW installed, no additional FEATURES should be installed.
So my question is Can I Install/upgrade product with previously installed feature list 'N' plus newly added feature i.e. N + NEW_FEATURES.
I am searching something like,
setup.exe /v /qn ADDLOCAL=INSTALLED_FEATURES,FEATURE_NEW
Round 2:
MigrateFeatureStates: I see you have updated your question. It does look like you are dealing with features. I assume you are using a major upgrade from version 1 to version 2? First of all the standard MSI action MigrateFeatureStates
will try to "preserve" the feature installation state for major upgrades - if the major upgrade is configured to do so in the Upgrade table (attributes column), just to mention it.
Feature Properties: In other words, if you do not set any feature properties (ADDLOCAL
, ADDSOURCE
, REMOVE
, ADVERTISE
, etc...), then your new version should inherit the feature structure of your first version and crucially install any new features automagically (provided they are set to install by default).
MSI API: Based on this, I am not sure your specific addition of a feature is necessary, but it might be if your feature is not set to install by default. As stated I am not aware of a way to retrieve the current feature state via the command line (there could be one), but you can use the MSI API and then invoke the new install either via MSI API or the command line (or some other way).
Feature Manipulation: I had a dated VBScript I could quickly adapt to generate msiexec.exe
command lines for feature state manipulation, but before going into that it should be mentioned that you can use a number of mechanisms within your MSI package to control feature selection: How to install feature based on the property set in custom action? In essence you can use a custom action to manipulate feature selection at will. You can inspect the system in detail to determine what features should be installed and not. You can also use feature conditions to affect feature selection without a single line of code (no custom action). See the linked answer just above (recommended). There is also a section on "MSI Features" in this answer which tries to explain it: Wix Installer : Setting component condition property when doing a MSIEXEC admin install at command line
GUI Feature Manipulation: I also want to add that you can obviously change the feature state in the MSI GUI if your GUI includes the Custom dialog screen where you can see the features about to be installed on the system.
Summary: So in summary you can manipulate features by feature conditions and custom actions from within your MSI - and you can also have the user change the feature selection interactively and manually in the GUI. If that is not enough you can retrieve the feature state for an installed MSI using the MSI API as shown in the VBScript below. What the script produces is a command line snippet which will replicate the installed feature state, with any additions you make in the designated place in the script. You need to input the product code for the MSI you want to get the feature state for: How can I find the product GUID of an installed MSI setup? (just get it from the property table of your MSI or from your WiX source - that link is just for reference). The script defaults to get the feature state for a common runtime package likely to be present on your box.
I guess this yields a few real-world options:
- Rely on MigrateFeatureStates to add any new features in version 2. New features must be set to install by default.
- Set feature properties via a custom action or feature conditions.
- Retrieve the currently installed feature states using MSI API and install the new version via msiexec.exe with custom command lines setting feature properties.
- Make the user add the features they need interactively in the GUI.
- Whatever I have forgotten.
It is easy to extend this script to report all feature states for all installed MSI packages (which is in fact what the script used to do before I adapted it).
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
Round 1:
Features: If you want to retrieve the currently installed product's feature installation state (features are the user-selectable installation parts: Program
, Dictionaries
, SDK
, Help
, Tutorials
, etc...), then that is possible via the MSI API. I am not familiar with a way to retrieve the feature installation state via the msiexec.exe
command line.
Components: If you are referring to MSI components (the atomic bits of the installer that are assigned to the user selectable features, but are never seen by the user directly), then I do not fully understand what you are trying to achieve. ADDLOCAL
is one of the Feature Installation Options Properties, and it affects feature installation state only, it only indirectly affects components (those that are assigned to the feature you refer to).
Major Upgrade: I am wondering if you have not implemented a proper major upgrade, and that this is the real problem you are experiencing. Please update your question with more information. A properly implemented major upgrade will install any new components, remove obsolete ones and also install any new features you have added. Before I write any more, please clarify your question.
I have a VBScript which will retrieve the current feature state of a product you specify (or for all the installed MSI files for that matter). If that is indeed what you are after.
If you are doing an ADDLOCAL then you are explicitly listing the features you want to install - the installed features are what you specify. It is not incremental, and does not mean "also install these features". For example, it turns off feature conditions. If you want to add features during a major upgrade with a bootstrapper you can use MsiEumFeatures() to get the installed feature list, to which you add your new ones. Another way would be to use a custom action to parse the ADDLOCAL string, sequenced after MigrateFeatureStates, and add the new one to the list.