views:

88

answers:

1

I have an InstallScript project written from scratch in InstallShield 2010. It contains, amongst other things, three native InstallShield objects and four InstallShield Merge Module Holder Objects which wrap MSM files.

When I originally tested the project, it installed fine on a clean environment, but when I tried upgrading to a newer version, each of the four Merge Module Holder Objects produced an "Error 1706. No valid source can be found for product XXXX" message.

I did some digging on the net and found that this is a Windows Installer error, and it occurs because the MSI file has to exist on the machine even after the original install media is gone. The recommended way to ensure that is to tick the "cache the msi package locally" checkbox in the Merge Module Holder Object property dialog.

I ticked that box for all four merge modules and re-tested, but that did not solve the problem. I then looked at where these merge modules were actually being put on the hard disk. The property dialog said <DISK1TARGET>, which resolves to C:\Program Files\InstallShield Installation Information\{Product GUID} at runtime. Looking at the test machine, it seemed as though all four merge modules were writing to the same place, thereby overwriting each other's MSI files.

To get round that, I edited each merge module to cache itself to a unique path, <DISK1TARGET>\{Name}. I compiled and tested again, and I can see that each merge module does now indeed save itself to a unique subfolder. However, all four Error 1706 messages are still appearing when I upgrade.

Does anyone have any ideas? I'm sure I'm missing something obvious, but it doesn't appear to be documented anywhere. :-)

UPDATE:

According to lots of posts on InstallShield forums, it appears that InstallShield generates a brand new product GUID for each embedded MSI every time it builds the InstallScript project. During the update process, the InstallShield engine overwrites each MSI file cached on the target machine with the newer version, but when it comes to execute them, Windows Installer says "hey, this is a new product, where's the old product's MSI so that I can uninstall it?", hence the error.

Is it possible to tell InstallShield to not re-generate the product GUID for each embedded MSI on every build? Surely this behaviour makes a mockery of the whole idea of embedding merge modules into InstallScript projects? :-(

A: 

I got this working by:

  1. Obtaining standalone MSI setups corresponding to the MSMs that we already had. Fortunately this was possible for all of them.
  2. Including the MSIs as installable components in the InstallScript project, installed to a suitable temporary location on the target.
  3. In the relevant <feature>_Installed event, shell out to msiexec.exe and run the MSI file with the /i and /qb switches.
  4. In the relevant <feature>_UnInstalling event, shell out to msiexec.exe and run the MSI file with the /x switch.

This feels a bit "wrong", but it works very well, so I'm happy to leave it at that unless anyone has any better ideas.

Christian Hayter