1

We have multiple products. All can be installed separate but also installed at the same time. All are send as single MSI file. The issue is now the upgrade. If someone get a new MSI for one product it must fit at least to the major version of all other installed products.

The test with different upgrade code fails because if all are installed and each has the rule to allow the updates only within the same major version you can Deinstall one product and than install any version because there is no crosscheck

Reading the docu :

https://learn.microsoft.com/en-us/windows/win32/msi/upgradecode

The UpgradeCode property is a GUID representing a related set of products. The UpgradeCode is used in the Upgrade Table to search for related versions of the product that are already installed.

This sounds that we can use the same upgrade guid for all products and the installer can manage than the detection of the product versions for both.

Is this the correct way?

Or should we create a registry key „product major version“ and check this as central Storage over all MSI files.

Sample:

More details .. each product is a separate MSI file

  • Product A
  • Product B
  • Product C

Product A and B can be installed separate but if they are on the same computer their major version must fit

Product C is exclusive which means it can’t coexist with A or B

Basic Idea with same update guid was

  • Product A .. Update Code X
  • Product B .. Update Code X
  • Product C .. Update Code Y

On install of A or B make two test

  • if Update Code Y is here abort
  • If Update Code X is there Check major version abort if this does not fit or install or upgrade of A or B

On install C

  • if Update Code X is there abort
  • If Update Code Y is there Upgrade

From the other article a definitive solutions seems to give each product a own key but than the tests are more complicate and i have to know all keys in any product .. Adding entries to MSI UpgradeTable to remove related products

  • Product A .. Update Code X
  • Product B .. Update Code Z
  • Product C .. Update Code Y

On install A

  • if Update Code X is there and major version fit upgrade
  • If Update Code Z is there and major version fit upgrade
  • if Update Code Y is there abort

On install B

  • if Update Code Z is there and major version fit upgrade
  • If Update Code x is there and major version fit upgrade
  • if Update Code Y is there abort

On install C

  • if Update Code X or Z is there abort
  • If Update Code Y is there upgrade

Regards

Markus
  • 373
  • 1
  • 11
  • You can do bootstrapper app with all your MSIs included. Guess it should handle your case. You'll get one exe installer at the end. – ba-a-aton Apr 01 '21 at 13:32
  • each MSI is about 1 GB and there are about 20 of them .. so we would like to keep them separate .. anyway a bootstrapper won´t solve the update issue it will just bundle the MSI to one. Or do i miss something .. how a bootsrap loader solve the update issue for each MSI ? – Markus Apr 01 '21 at 13:43
  • 1
    [An old answer on MSI and multiple upgrade code upgrades](https://stackoverflow.com/questions/51801570/adding-entries-to-msi-upgradetable-to-remove-related-products/51803320#51803320). It sounds like your products are so related that you should release them as one MSI? If you have problems with the size you could put some content online - not as bad as it sounds - help material and tutorials and such? I shouldn't say anymore before I know more about the product. And there are some ways to [speed up builds](https://stackoverflow.com/a/30033958/129130). – Stein Åsmul Apr 01 '21 at 21:29
  • [Putting files online](https://stackoverflow.com/a/56380980/129130) - [another version](https://stackoverflow.com/questions/53904385/how-to-generate-msi-exe-installer-file-in-visual-studio-2017-for-a-project-of-ov/53905088#53905088). This may be a little crazy to suggest given your question - but I keep wondering what to install locally in the age of the Internet? It is much easier to update online material than to make a whole new setup to test and distribute for every little change? – Stein Åsmul Apr 01 '21 at 21:36
  • @SteinÅsmul thx this really helps in understanding .. after reading this I am back to the question : what happens if I use one upgrade code for all. The FindRelatedProduct should than find all products installed with this code. The reason for this is that add more MSI I can‘t know before the keys and the MSI are already on the customer sites with the stored list – Markus Apr 02 '21 at 03:41
  • Hmm, maybe you have see this one already: [WiX to install multiple products](https://stackoverflow.com/a/1546916/129130). If not, please read it. By the sounds of it you have a single product suite and a number of sub-products that seem more like different "Features" than different MSI files. You could use Burn to deliver all MSI files as a "bundle" of related versions and handle update that way. This means you have to build the whole thing for any change to any product. This is the same if you treat them as features inside the same MSI. Please do read that link - I am not sure what to answer. – Stein Åsmul Apr 02 '21 at 13:54
  • Again: if you have parts of these products that can be serviced online - help material, videos, tutorials, etc... are prime candidates to eliminate from local installation. You install only binaries if you can is what I try to do, and then move anything else to an online source that can be updated once for all users. This is to eliminate frequent updates to the installer for trivial changes to support material - as already mentioned and also to keep the setup smaller and leaner and meaner to build and QA. If you do - make sure to update your software to handle "online resource is missing". – Stein Åsmul Apr 02 '21 at 13:57
  • Often a lot of such "help material" can be extracted and installed via a separate installer. This might be what you already do? The intent is as stated: to not have to rebuild installers for binaries for trivial help material changes. Proper QA of installers for binaries is a nightmare in my opinion. Days of effort for the whole team to do it properly (and developers will throw in their "hot potatoes" of fixes in the binaries and cause a real mess if you skip full QA). – Stein Åsmul Apr 02 '21 at 14:09
  • 1
    Concrete on upgrade codes: if all products share one upgrade code they are all related by definition. You can detect a specific "version range" by authoring the upgrade table in detail. That is what it is for. It can detect existing products and then decide what to do. It might just detect a previous version and refuse to install, or it could uninstall the previous version. More advanced detection logic you would need to put in a custom action. I have never used this in real life. Do you have different language versions? – Stein Åsmul Apr 02 '21 at 14:49
  • I add a sample to the question above with 3 products .. in real we are speaking about 20 and more to come 8) .. the MSI are addons for other applications (CAD, CAX, PDM) .. no language issue here. – Markus Apr 02 '21 at 18:12
  • We try to remove our MSI size also as stated here .. but our customer often works on client with no or very restricted net access. Our consultants do most time onside installations – Markus Apr 02 '21 at 18:17
  • Do these applications have their own mechanism for deployment of addons? – Stein Åsmul Apr 06 '21 at 12:19

1 Answers1

0

it seems to work with the same upgrade id .. in the install log we can see all related proudcts sharing the GUID separate by ";"

Action start 15:07:46: FindRelatedProducts.
FindRelatedProducts: Found application: {E9C16B5B-DEFC-4257-B378-6BDA6724EAA3}
MSI (c) (68:D0) [15:07:46:467]: PROPERTY CHANGE: Adding PREVIOUSVERSIONSINSTALLED property. Its value is '{E9C16B5B-DEFC-4257-B378-6BDA6724EAA3}'.
FindRelatedProducts: Found application: {3C0B5AA4-2C04-4C51-9CDA-199367DD5D5B}
MSI (c) (68:D0) [15:07:46:467]: PROPERTY CHANGE: Modifying PREVIOUSVERSIONSINSTALLED property. Its current value is '{E9C16B5B-DEFC-4257-B378-6BDA6724EAA3}'. Its new value: '{E9C16B5B-DEFC-4257-B378-6BDA6724EAA3};{3C0B5AA4-2C04-4C51-9CDA-199367DD5D5B}'.
Action ended 15:07:46: FindRelatedProducts. Return value 1.

anyway i have to add this here to avoid uninstall before the install runs because of the shared GUID

<InstallExecuteSequence>          
    <RemoveExistingProducts Before='InstallInitialize'>0</RemoveExistingProducts>
</InstallExecuteSequence>
Markus
  • 373
  • 1
  • 11