There are three crucial keys in a Windows Installer package - the Package Code, the Product Code and the Upgrade Code. The Package Code uniquely identifies a particular release, and should change every time. The Product Code may or may not change, and determines whether or not you can install two versions of a product alongside each other or whether you must upgrade. You can install them side-by-side if the Product Codes differ, otherwise the new version will replace the old one. The Upgrade Code should remain the same for new versions of the same product and simply identifies that an upgrade is possible.
Doesn't sound too bad, does it? Unfortunately, these codes are a bit difficult to keep track of in practice, and unhelpful error messages didn't help me to spot what I'd got wrong. The error messages appeared to suggest that 3.1 was less than 3.0.1. Not only is this patently untrue, but it's referring to Version Numbers, which are not directly related to the codes I've been talking about.
Despite the misleading error messages, I knew that the codes were one of the things that could cause this sort of problem and a prime source of confusion, so I checked them against a previous package, and against the spreadsheet where we keep a record of them, and they seemed to be correct. A considerable amount of time spent scratching my head while I explored other fruitless avenues followed.
Eventually, with qidane looking over my shoulder and prompting, I went back to the codes and realised what I'd done. The Product Code in the previous package had been altered at the prompting of InstallShield technical support while trying to solve the problem that led to authoring the new package; and when I'd looked it up in the spreadsheet, I'd read the wrong column. It's easy enough to go cross-eyed, as the codes I'm referring to each look something like this:
With a different Product Code, the assumption was that the new version couldn't be installed directly over the old one and therefore couldn't be optimised into a Minor Upgrade which would generate nice small patches, but would have to be a Major Upgrade - effectively a complete reinstall, and a very evil thing if you're aiming to create a downloadable patch that won't have users running screaming to the hills.
Changing the Product Code back to the original version solved the problem.
Windows Installer is a wonderful technology which I have a history of defending against other developers in the community who only see its authoring complexity (or the not-bad but relatively brain-dead subset of its functionality exposed by Visual Studio) and don't appreciate how much of a boon it is to users and particularly systems administrators. However, this has to be an area where improvement in the authoring tools would be possible.
I was able to find documentation on the error messages relatively easily which suggested where I might look in my project for possible mistakes, even if the text of the messages themselves wasn't helpful. I knew from my own experience that it was quite likely to be something to do with the codes, and made a point of double-checking them as a result, but I still managed to mess it up.
There are a couple of things that might help developers to avoid this kind of error, and some others. It would be nice to have a diagram generated of what the authoring tool thinks the relationships between different packages are, including the types of upgrades (small/minor/major). It would be particularly useful to have the compiler spit out its actual reasons for saying that an upgrade should be of a particular type, so that it's easy to double-check them and find any errors. This information could also be exposed through the diagram I've already mentioned.
I suppose I ought to send a modified version of this to InstallShield as a suggestion...