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

Christopher Painter chrpai at iswix.com
Mon Apr 26 12:30:53 PDT 2021


Not all possible component rule violations are actually documented.  In a nutshell, the way I see it,  you have a DLL that is only partially backwards compatible in that a newer version of the DLL requires the existence of another dll that the original version didn't care about.

So if the code in the dll can attempt to load the new dll and fail gracefully in a backwards compatible way you'd be fine.

not all the component "rules"  are in the MSI... sometimes they are in the actual application code.

Hope that makes sense.

________________________________
From: Andrew Kielbasinski (akielbas) <akielbas at cisco.com>
Sent: Monday, April 26, 2021 2:01 PM
To: Christopher Painter <chrpai at iswix.com>; wix-users at lists.wixtoolset.org <wix-users at lists.wixtoolset.org>
Subject: Re: Sharing common program parts with merge modules


Hi Christopher,

Thanks for your quick response.



You’re right, it’s not merge module specific, more of looking for a way that Windows Installer can be used for scenarios like this.



The components that are EXEs and DLLs are currently in C++, and I guess we can code them to be loosely coupled but I think that is a lot of overhead to write all future code like that. Ideally all the dependencies are opaque to the products which only interface with a single executable.



I do see that my current approach of putting every resource in a separate component is the violation? I’ve previously reviewed the MSDN documentation on “Organizing Applications into Components” (https://docs.microsoft.com/en-us/windows/win32/msi/organizing-applications-into-components) and I guess that what I have is components that depend on each other and that perhaps I need to put all the dependencies (resources) in a single component. However that comes with the restriction that these resources must be in the same directory, which I think is a fairly significant restriction and in my case would require significantly reorganizing the shared component.





From: Christopher Painter <chrpai at iswix.com>
Date: Monday, April 26, 2021 at 9:16 AM
To: wix-users at lists.wixtoolset.org <wix-users at lists.wixtoolset.org>
Cc: Andrew Kielbasinski (akielbas) <akielbas at cisco.com>
Subject: Re: Sharing common program parts with merge modules

Go ahead and use the word component because it applies here as overloaded it is.  What you have is basically a component rule violation.    Your example mentions a merge module but really it's a shared components question and could be applicable via wixlibs as well.



What is component 4 coded in?  Could it be programmed in such a way to be more loosely coupled with component 5?    If not, could the code in component 4 and component 5 be all merged into component 4?   Either at the source code level  or  include component 5's file as a companion resource file in component 4.     DLL's don't always have to be the key file of their own component.  That is mainly if the DLL contains  COM metadata which wouldn't be the end of the world either as most people use the registry table for COM meta data rather than the COM tables.





________________________________

From: wix-users <wix-users-bounces at lists.wixtoolset.org> on behalf of Andrew Kielbasinski (akielbas) via wix-users <wix-users at lists.wixtoolset.org>
Sent: Monday, April 26, 2021 7:18 AM
To: wix-users at lists.wixtoolset.org <wix-users at lists.wixtoolset.org>
Cc: Andrew Kielbasinski (akielbas) <akielbas at cisco.com>
Subject: [wix-users] Sharing common program parts with merge modules



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!

____________________________________________________________________
WiX Toolset Users Mailing List provided by FireGiant http://www.firegiant.com/



More information about the wix-users mailing list