[wix-users] Sharing common program parts with merge modules

Andrew Kielbasinski (akielbas) akielbas at cisco.com
Mon Apr 26 05:18:31 PDT 2021


Apologies this may not be strictly a WiX question, more Windows Installer, but I'm trying to use WiX to implement it and I figured there are a lot of installer experts here.

I have two Products (A and B) that need to include a Shared Element (trying not to use the word component as it overlaps with Windows Installer naming). This element is an executable with a bunch of dependencies (DLLs and Resource images) and it is guaranteed to be backward compatible to support any older version of Product A and B.

Some requirements:
1) There needs to be a single instance of the shared element at runtime.
2) The products are independent and can be installed, upgraded and uninstalled in any order (no downgrades of a particular product allowed).
3) Product A and B installers must be MSI, can't be executable bootstrapper.
4) If a product being installed contains a newer version of shared element than what is installed, it should upgrade the shared element
5) If a product being installed contains same or older version of shared element than what is installed, it should skip install of the shared element
6) The shared element install needs to be ref counted and removed only when both products are removed.

I have created a merge module with WiX and have created Windows Installer components for each part of the shared element. The GUIDs are fixed (not autogenerated every build). It looks something like this:

Shared Element Merge Module v1
                Component 1 (shared element exe)
                Component 2 (shared element dll1)
                Component 3 (shared element dll2)
                Component 4 (shared element image)

Generally this seems to be working OK with the component ref counting, but I am looking at a scenario where I introduce a new DLL to the merge module

Shared Element Merge Module v2
                Component 1 (shared element exe)
                Component 2 (shared element dll1)
                Component 3 (shared element dll2)
                Component 4 (shared element image)
                Component 5 (shared element dll3)

The scenario is as follows:
1) Install Product A (contains Shared Element Merge Module v1)
2) Install Product B (contains Shared Element Merge Module v2)
3) Uninstall Product B

In step #1 Components 1-4 all have 1 reference.
In step #2 Components 1-4 are upgraded and have 2 references. Component 5 is installed and has 1 reference.
In step #3 Components 1-4 reference is reduced to 1. Component 5 is removed.

The issue is that the missing DLL (component 5) is required for the upgrade shared element executable to function. Is there any way to prevent this?

Possible solutions I have considered:
1) I've considered putting all the resources into as few components as possible (so all the images in a single component, the executable and all dependent DLLs in another component) but it seems like I could still face the issue above in the future if I need to introduce new resources in new directories.
2) I've considered having multiple copies of the shared element on disk at runtime (so each version of merge module uses autogenerated GUIDS for components, and files are installed to a version specific directory). Need some magic where each product uses the latest version available and ignores older copies. If product that brought a newer version is uninstalled then the other product reverts back to using older version which is still there.
3) Use a full MSI for the shared element and use Installer chaining. Seems like I'd have to handle the ref counting myself and do some condition magic with the chained installers to prevent uninstall of the shared component until the last product is uninstalled.

Any thoughts or suggestions would be appreciated. Thank you!


More information about the wix-users mailing list