views:

227

answers:

1

This has to be a common need yet I find hardly ANY references to it on the web...

I've got a product that has three sets of components, one installed on the server, one on the web head, and one on the developer's machine. All three sets could be installed on one machine and should peacefully coexist.

As I had it yesterday, each component was installing to a different place and working ok, but that was just temporary as some files, gac'd assemblies, and registry settings ought to be shared. Now I've made a merge module out of the shared components and this new merge-module scenario is working fine during install under ideal conditions and I've got major upgrades of a single msi all figured out.

The problem is during installation of an msi when the version of the merge module within the installing msi is lower than that of the already installed version (of a different msi) - the newer version is overwritten with the older version! Furthermore, upon un-installation routine of any of the three msis, the shared stuff is removed even though it is still in use by the other installed components.

For the most part I understand why I'm getting this behavior, but I don't understand how I'm supposed to be configuring my installers so that these components can be shared WITHOUT having a separate installer for the shared components. Also, I don't want one big installer either - this won't scale well.

What I want is that the three installers contain whatever latest version of the components in the merge module were available at build-time. At install time, if a newer version of the shared components is installed, don't overwrite them. At uninstall(and upgrade) time, the reference counts that should have been tracked would determine whether the shared items should be removed.

In case I'm just missing something, here are the important parts of the merge file: My merge module's version number (the y in "w.x.y") is incremented with each build, the package ID remains fixed, and each component has Shared="yes" (although I've tried it without this as well).

I've started storing the various version numbers in the registry, and I figured maybe I could conditionally install the merge module feature only if the version number in the registry were absent or lower. But the conditional arguments can't evaluate w.x.y.z properly, as says the documentation. The documentation then suggests AppSearch, but AppSearch RegistrySearch can only check for existence, not version number comparison either. Apparently the FileSearch can, but the assembly file version numbers will not be incremented with each build.

And I've read that MergeModules have many problems - maybe these are them - but wixlibs don't seem to offer any solutions to these problems either.

So what is the right way to do merge module versioning??? I found a book that has a TOC entry called "merge module versioning" on Amazon but the book is out of print. :-P

+1  A: 

It looks to me that this behaviour that we want - always have the best version of a shared component installed - is supported only from MSI 4.5 on. So maybe this is not a problem of WiX itself, but I know almost nothing about WiX.

We will want the attribute msidbComponentAttributesShared (0x0800) to be set in the Component table for the shared component. Maybe you can check your MSM with Orca for this.

I think this blog post mentions something about it (but it's probably not of great help for you here): http://blogs.msdn.com/windows_installer_team/archive/2008/03/29/windows-installer-4-5-servicing-enhancements-shared-components-and-patch-uninstall.aspx

Martin
Good thought, but I don't know how to apply this in WiX. +1
uosɐſ