I have an internal MSI placed on a network drive, and I'd like to write a login script so that anyone on our network can get the MSI installed onto their machines, or to get it auto-reinstalled whenever the MSI is updated (which happens often).
If I use msiexec.exe /i REINSTALL=ALL
it will do nothing if the MSI has not yet been installed on that machine. If I leave out the REINSTALL=ALL
, then it will do fresh installations, but will not do update/reinstall.
What parameters should I choose to make it do a fresh installation if the package was not yet installed, and to do a full reinstall if the package was already installed?
Running msiexec /i
first followed by a reinstall might work, but I'd like to avoid that if possible.
EDIT: The reason /famus
is needed is that these are developer machines, and someone might manually update the registry or register a different set of dlls. The intention of the script is that even if there has not been any changes to the MSI, the developer can also run the script to easily revert back to "official" environment.
What about trying:
msiexec /i <path to msi> ADDLOCAL=<top level feature name>
You can get the top level feature(s) by opening the package in Orca.exe and looking at the Feature table.
I solved it in the end with a batch file that runs msiexec /famus first, and if the exit code is 1605 it will run msiexec /i.
A common practice to support minor upgrades at one point was to author REINSTALL=ALL
in the package, but then add a type 51 (set property) custom action REINSTALL={}
to clear the property when your product is NOT Installed
. I'm not sure this is exactly what you're looking for, but it might be a start. If you didn't create this package, you could add both the property and the clear action with a transform: msiexec.exe /i [...] TRANSFORMS="[...]\reinstall.mst"
I would use major upgrades instead of minor upgrades. For a major upgrade the command line will always be the same - no need to use different command lines depending on whether it is an upgrade or a fresh install.
Major upgrades are in fact completely separate setups linked by logic specified in the Upgrade table telling Windows Installer how the "upgrade" should be performed. The upgrade isn't an upgrade at all, but an uninstall of the existing product and an install of the new product.
The upgrade table has a learning curve, it's a bit Greek sometimes, but it allows a great deal of flexibility in specifying upgrade behavior. Some samples:
- You can uninstall the old product and install the new one
- You can disallow installation of an older product on top of a newer one
- You can allow downgrading a newer install with the older one being run (for example to ensure the version you got in your login script is the one on target systems)
There are some additional challenges involved with major upgrades that can confuse things. Specifically major upgrades allow the install of the new version to precede the uninstall of the old one! This scenario requires error free setups with component referencing done correctly. The most common approach, however, is to uninstall the older version completely and then install the new version afterwards. This approach is more forgiving and will generally work correctly even if component referencing in the setup has been messed up.
Personally I never use minor upgrades for anything but minor tweaks to publicly released software. I find these upgrades to be extremely error prone, tedious to deploy, time consuming to debug and QA and generally unnecessary complexity. I also use them in cases where a major upgrade fails because of errors in the uninstall logic of a previous package. In other words when I need to hotfix the faulty install before it can uninstall properly.