What causes an MSI update to not update a component in an installer?
Asked Answered
C

4

6

(EDIT: Question changed.)

I have a product with an installer which was built by InstallShield 2010, and appears by all accounts to be installing just fine as a "new" install.

Periodically, I make changes to the contents of the installation, as I update this or that component with bug fixes and so forth. At those times I try to change the version numbers in the metadata of the files that got updated, but there are components for which that isn't possible. Of course they always end up with more recent modify dates. I change the version number for the product in the MSI data as well. However, I have not been changing the Package Code each time.

When some users run the installer on a system where my product is already present, they're prompted with update mode UI ("would you like to update?" etc.) and the installer appears to complete. However, the updated files don't always overwrite the older files until a "repair" installation is run afterwards, especially if the version number didn't change, and there is evidence now that flagging the component's contents with a "force overwrite" doesn't change this behavior.

What's going on here? Is there any way I can get a better result? Does the Package Code need to change whenever I rev the product or update a component? (Edit: The Package Code is changing each time I build the release, so this is not the cause of the problem.)

Edit: It's an update UI, but maintenance after update is what actually completes the desired installation.

Chaetognath answered 14/1, 2011 at 21:41 Comment(0)
B
3

You should certainly be changing the PackageCode every single build. In fact, by default, InstallShield has a build setting that does just this.

In fact, the MSDN help topic Package Codes says:

Nonidentical .msi files should not have the same package code. It is important to change the package code because it is the primary identifier used by the installer to search for and validate the correct package for a given installation. If a package is changed without changing the package code, the installer may not use the newer package if both are still accessible to the installer.

This is why you are getting a Maintenance UI experience instead of an Upgrade experience.

Now once you start doing this you are going to have to next consider do you want to support Minor Upgrades, Major Upgrades or Patches to service your application. It's very important that you understand this and test your strategy before putting your installer into production.

Bridgeboard answered 15/1, 2011 at 0:22 Comment(7)
If there's an InstallShield setting for this, I have yet to actually find it after 11 years of using InstallShield (I used InstallScript up to the most recent major version.) Can you suggest some resources for learning this that are less abominably incoherent than the MSDN documentation?Chaetognath
EDIT: I found the setting, and it is set to "Yes" for all my releases in the project. So the cause of my problem is not an unchanging package code, I guess. I'll pose the other question as a question in its own right.Chaetognath
Sounds like you are updating the PackageCode and generating a SEtup.exe and the result is a minor upgrade. You have to follow the component rules to the letter in this situation.Bridgeboard
Read msdn.microsoft.com/en-us/library/aa368599(v=vs.85).aspx and msdn.microsoft.com/en-us/library/aa368267(v=vs.85).aspx and all the various links off of those pages.Bridgeboard
Yes, well, but that's the "abominably incoherent MSDN documentation" I was referring to. ;-)Chaetognath
This part isn't too bad. It actually has some nice tables and flow charts to explain what happens. You could also log the install and read what it tells you it's doing and why.Bridgeboard
This will justify @Christopher Painter's answer: I'm now to the point where I need to rev the installer, and "AMUS" is giving me serious heartburn. Now I have to go through and fix all the components. I don't think Windows Installer and Installshield are very user-friendly, even to a seasoned programmer.Chaetognath
H
2

In @ChristopherPainter's answer above I too learned that InstallShield has a setting to auto-generate the package code, but he didn't say where it was. So for anyone else looking for it:

This setting is found under Media / Releases / (release name), product configuration, general tab. There you will find "Generate Package Code" and you can verify that it is set to Yes.

Hereat answered 2/7, 2014 at 15:21 Comment(0)
L
1

The installer is doing what it's supposed to, based on the unchanging file version information.

Ideally you update the file version each time you alter a file (for files that contain version information at all), but if for whatever reason you're not going to do that, there are still a couple ways to force components to be updated.

The easy way is to set the REINSTALLMODE property. You could set it to "amus", which would cause all files to be reinstalled. See MSDN - http://msdn.microsoft.com/en-us/library/aa371182%28v=vs.85%29.aspx

That works, but may introduce its own problems. For instance, if you are including some redistributables in your package, forcing those redistributable components to be reinstalled can cause them to be backleveled.

The somewhat harder way, which allows you to have control at the individual component level, is to use a custom action. Call MsiSetComponentState to explicitly set each of your components to whatever state you want. http://msdn.microsoft.com/en-us/library/aa370383%28v=VS.85%29.aspx

My recollection is that your custom action must come after CostFinalize, so the installer doesn't wipe out your updates.

Labio answered 15/1, 2011 at 22:58 Comment(2)
It's ironic that another software commonly installed alongside ours from a completely different company is backleveling a component we include, but I think this solution will work for us. Thanks!Chaetognath
This will justify @Christopher Painter's answer: I'm now to the point where I need to rev the installer, and "AMUS" is giving me serious heartburn. Now I have to go through and fix all the components. I don't think Windows Installer and Installshield are very user-friendly, even to a seasoned programmer.Chaetognath
I
0

When Windows Installer decides whether to install your component, it will first look whether the "keypath" resource is already present. If it is, none of the resources in the component are installed. (I assume Installshield puts each file in its own component, and the keypath is the file.)

When the keypath resource is a versioned file, Windows Installer will consider it to exist only if it finds a file with an equal or higher version. So if a file with the same version number is already present, it will not be installed again. Changing a file without changing the version number will therefore cause problems.

edit: as to why a repair fixes the problem: I believe it will reinstall all components from the cached MSI file in c:\windows\installer regardless of the presence/version of the keypath resource. This seems logical as it would be the only way to make sure that corrupted files are restored. (I can't immediately find a clear reference on MSDN to back this up, sorry.)

The TortoiseSVN developer has blogged about a similar problem in TortoiseSVN when upgrading from a pre-1.6.10 version to a later one. In his case the problem was not the version of the file, but a change in the keypath of some components with the same result. A repair also fixed the application in that case.

Incursive answered 15/1, 2011 at 1:35 Comment(1)
That sounds right; I use their assistant functions to start the project, and then modified things as needed to add functionality, such as a pair of custom actions. But why would a "repair" install triggered through the Programs and Features control panel then set things to right, when the upgrade installation failed to do so? Shouldn't the behavior be the same in both cases?Chaetognath

© 2022 - 2024 — McMap. All rights reserved.