WIX: How to Select Features depending on properties - wix

I want to select features based on certain properties' values.
Similar to this question:
WIX: How to Select Features From Command Line
It seems that setting the ADDLOCAL property value is one way to do it, but is this the right way? Microsoft seems to warn against doing it in this article:
http://msdn.microsoft.com/en-us/library/aa367536(VS.85).aspx

Features can be conditionally installed as well. See the Condition element under the Feature element. Component Conditions may work as well. Depends on your package structure.

Why not use components instead of features? Components can be conditionally installed depending on various properties.
We do this having "pretend features" that a user can select via a checkbox, then a complicated set of conditionals to install various components depending on their Office version AND the state of the checkbox.

Related

WiX: RemoveExistingProducts + ADDLOCAL

I'm using Wix 2. I am using RemoveExistingProducts, but want to keep my previously installed features. In addition, I'd like to add new features via ADDLOCAL parameters given via command line.
However, according to this article ADDLOCAL does set the Preselected flag.
Therefore MigrateFeatureStates does not fire:
Skipping MigrateFeatureStates action: feature settings already made
Is there a possibility to use them both?
No, not both. The documentation is pretty clear that ADDLOCAL (and all the other feature state controls via the command-line Properterties) take over the selection manager. It, unfortunately, makes using the command-line to control feature states very tricky.

MSI Properties Empty on Passive, Basic UI, and No UI Install

I am working on an installer with a handful of custom actions that look for values in the following MSI properties:
ADDLOCAL
ADDDEFAULT
REINSTALL
REMOVE
When running the installer with the full UI, these properties contain lists of comma-separated feature names as appropriate given the options that are selected by the user. However, when I run the installer in passive mode or with only a basic UI (or no UI) from the command line, I find that the properties are empty/blank. It is only when I explicitly set them from the command line that they have any value. This is an acceptable work-around, but it would be much better if these could take on some kind of default, such as "all", without requiring values to be passed on the command line. Is there some way I can specify this in WiX (which I am using to build the MSI) or do I have to do something in the custom action code (or something else entirely)?
I have looked at the property reference here, but I did not see any mention of how one could specify default features for these properties.
What I also found interesting is if I do specify a feature this way on the command line during install, it seems to be stored for the uninstall in the REMOVE property (in other words, I do not have to pass any parameters when uninstalling in any mode). Is this a feature that I can rely on? Will it automatically update if someone modifies the installation later?
I'm running WiX 3.5.2519 and using Visual Studio 2010 with Visual C++ for the custom action code. Thanks for any help you can give me!
Edit:
Actually, I was wrong. It appears that the REMOVE property is always set to "all" when uninstalling and running in one of these modes, even if I pass a different value on the command line or only install a subset of features. This seems broken. Am I doing something wrong here?
C:\> msiexec REMOVE=FeatureName /passive /l* uninstall.log /x Product.msi
It will completely ignore what I specify for "FeatureName" and use "all" in its place.
Your custom actions probably shouldn't examine those properties. Instead they should examine the feature and/or component states of the product, depending on what they're trying to do. In conditional statement syntax, this looks like $component-action or &feature-action (where you use the name of the component or feature whose action you are trying to condition against). In C++ (for inside the custom action) this looks like MsiGetFeatureState or MsiGetComponentState, and these are of course made available through similar means in most other languages (such as session.FeatureRequestState / session.ComponentRequestState in a language you shouldn't use).
It is a recommended practice that all properties to be used by the installation be entered into the Property table with an initial value. The installer sets the properties to these values at the launch of the installation. Properties for which a blank is an acceptable value and properties built into the installer do not need to be initialized.
You can then change the default value programmatically or on the command line as described here: Using Properties.

WiX project allowing side-by-side installation

I am in the process of creating an MSI for our product. I would like the product to be able to install side-by-side. So that I can install 1.0.0 first and later can add 1.0.1 so that the two versions are both installed.
I am using WiX to create the msi and would like to know how this can and should be done in Wix? For example
Do I need to create new Guids for all components?
How would i add the version info to wix or should i rename my product completely?
How can I create the projects so that releasing a new version requires minimal changes in the wix project?
Greetings,
Martijn
You should be able to get away with just changing the top-level productcode and UpgradeCode GUIDs to make your two products completely unrelated, and use the Productversion to identify the version. You can share component guids between products (that's how merge modules work) so that the guts of your installer (component definitions) needn't be tweaked and can still be shared.
You major challenge will be ensuring that the two decoupled products don't interfere with one another, for example by having the same default installation folder, start menu entries and the same Add/Remove programs entry. You might achieve this by including the product version number in the ProductName Property, which can look a bit techy in your install UI, but it isn't unheard of.
Regarding your first question: No, you don't need to.
But why?
I had difficulties to understand the windows installer rules in my side-by-side scenario.
You really need to understand the concepts of component rules (including when you need to brake them) and key paths. WiX doesn't abstract these aspects away.
This answer does already highlight possible interferences.
Let's consider a few examples.
The GUID of the component with the application executable does not need to be changed. This breaks the component rules, but it works, as both versions of the product define the same component in a non-interfering way.
A resource shared by both versions is not directly supported. A prominent example is the use of file extensions using ProgIDs, as shown here.
If you change the GUID (also happening when using the "*" GUID), the extension will be removed when uninstalling either version.
If you don't change the GUID, the extension will be retained, but point to the version which was installed most recently. You may go with this option as the lesser of two devils, supporting at least a scenario where users uninstall the versions in the same order in which they installed them.
There is a pitfall here: The extension needs to be the key path of the component. This makes the usage of the ProgID element problematic in a side-by-side scenario as you'll get the ICE69 warning in case you don't put the ProgID element in the same component as the referenced file. Further more, it's an implementation detail of WiX which registry entry it generates will be the key path.

Is it possible to override the behavior of a merge module

Supposing I have a merge module that installs a file "MyFile.txt" to a certain location, and that I wish to use that merge module, however I want to supply a different copy of "MyFile.txt" from the one supplied with the merge module.
Is it possible to do this? (And for bonus points how can I do this using Wix)
Update: Roughly speaking MyFile.txt is part of a package up component of installable items that we provide to others, they then comine these components with their own to produce an installer.
In the ideal world they would only need to add new files to the output, however this is a replacement for an existing system where they currently have the ability to modify or even replace items (suce as MyFile.txt) in the end installer, and so without the ability to do the same with the merge module the migration path will be difficult.
The packaged up component doesn't need to be a merge module if there is a better solution, however merge modules seemed like the sensible choice and in all other respects provide a very nice re-usable package of installer logic.
It's possible but every technique that I know is a bit of a hack and doesn't scale very well. Can you tell me more about what type of file MyFile.txt is and what the intent of the different flavors of the file? Usually my goal is to never have the same filename twice ( darn component rules ) and then design variation points to support the needs. Sometimes upstream changes to the application are required to do this correctly.

Add user group to another user group with wix v3

I need to add group within a group
e.g. COMPUTER\Users group to the "Backup Operators" group.
Wix provides a way to add a user to a group using the GroupRef Element but does not seem to provide an obvious way to add a group
Can this be done? If so how?
You'd need to write a CustomAction. It probably wouldn't take too much to extend the existing User and Group CustomAction in the WiX toolset to support this. In fact, there is a feature request open for this behavior in the WiX toolset today. Maybe you could contribute the fix?
Some resources:
http://msdn.microsoft.com/en-us/library/aa370283(VS.85).aspx (Local Group Functions)
http://support.microsoft.com/kb/119671 (link seems to be broken, leaving in for now)
I got some C++ code that wraps user and group creation, and as I recall adding groups to groups should be possible with relative ease. Unfortunately I no longer have access to that code-base, perhaps the Boost library has support, or a simple VBScript should suffice.
I don't like to make software recommendations, but I have found that the VbsEdit application features a large library of standard VBScript samples - perhaps you can find a ready made script in its' sample library.