sponeil

Using a Visual Studio 2005 SP1 "Setup Project", I can get the upgrade feature to work as documented, but I have problems with "how" it works. Both of these scenarios are from real installs I'm working on:

Scenario 1:
The install creates a database and several configuration files. The uninstall must remove them all. An upgrade install needs to run conversions on the customer's database and configuration files, which have changed since the original install. If the customer skips a release when upgrading, multiple conversion scripts need to be run (so I also need to know which version he's upgrading from).

Scenario 2:
The install, which will be silently pushed to thousands of laptops via AD or SMS, registers and starts a Windows service, installs a Layered Service Provider, and downloads an initial configuration file from the install server. The uninstall must clean everything up properly. All upgrade installs will be downloaded across the Internet and run silently by the service (the end user doesn't have privileges to run the upgrade install). If the upgrade install tries to mess with the service EXE or LSP DLL, it will mess up the TCP/IP stack on the client. Instead, a custom script must be run to tell the OS to replace the Service EXE and LSP DLL after the next reboot.

Problem when RemovePreviousVersions=true:
There is no way to distinguish between an upgrade install and a manual uninstall followed by a manual install. This breaks both of the scenarios above very badly.

Problem when RemovePreviousVersions=false:
This sort of works, but it puts duplicates in "Add/Remove Programs", and I'm not sure how to safely remove them from my upgrade script. I also need to be able to run a custom script before the upgrade install runs (to make sure certain services and applications are closed before the new files are installed). In silent mode, it automatically moves locked files to C:\Config.msi and flags them for deletion on reboot, which breaks the TCP/IP stack for scenario 2.


Does anyone have an elegant (or even an unelegant) solution to this How about a simple way to remove the duplicates in "Add/Remove Programs" I really need to use an MSI for scenario 2 because I've read that AD will only push MSI files, and I need to support that.

Thanks,
Sean



Re: ClickOnce and Setup & Deployment Projects How can I distinguish between install and upgrade?

sponeil

I think I've come up with a kludge that may work. The custom action on commit can search the registry for extra copies in HKLM/Software/Microsoft/Windows/CurrentVersion/Uninstall and run "msiexec.exe /x{ProductCode} /quiet" for each one. I don't think it messes anything up when I run the uninstall for the old version AFTER the new version is installed. It is a very big problem if the uninstall runs BEFORE the new version is installed.

Anyone have a cleaner way to do it
Sean





Re: ClickOnce and Setup & Deployment Projects How can I distinguish between install and upgrade?

sponeil

That kludge I suggested works when you run the old uninstall manually, but it fails when I try to run it automatically at the end of the install. My best guess here is that it msiexec won't run an uninstall while another install is still running. So I'm back to having the same problem.





Re: ClickOnce and Setup & Deployment Projects How can I distinguish between install and upgrade?

PhilWilson

When the setup detects a prior version installed (RemovePreviousVersions=True) it sets the case-sensitive PREVIOUSVERSIONSINSTALLED property, so you could have a custom action condition of PREVIOUSVERSIONSINSTALLED if you want to run it only if it's an upgrade.





Re: ClickOnce and Setup & Deployment Projects How can I distinguish between install and upgrade?

sponeil

Does it set this property during the uninstall, the reinstall, or both (Keep in mind that I need to stop it from running the uninstall script first, and keep the uninstall from touching any of the files.)




Re: ClickOnce and Setup & Deployment Projects How can I distinguish between install and upgrade?

PhilWilson

That property is set in the new install when it detects a previous version, as its name implies.

If you want to detect in the older version that it's being uninstalled because of an upgrade, there's the standard Windows Installer property UPGRADINGPRODUCTCODE, so if you want an uninstall custom action in the older version to run only if it's an install and not an upgrade, condition it on not UPGRADINGPRODUCTCODE.






Re: ClickOnce and Setup & Deployment Projects How can I distinguish between install and upgrade?

sponeil

Thanks, that seems to be pretty close to what I was looking for. I now have these custom actions:

Commit:
Run "MySetup.exe /Install" if not PREVIOUSVERSIONSINSTALLED
Run "MySetup.exe /Upgrade" if PREVIOUSVERSIONSINSTALLED

Uninstall:
Run "MySetup.exe /Upgrade" if not UPGRADINGPRODUCTCODE


Am I correct in believing that there's no way to get it to stop moving locked binary files to C:\Config.msi and replacing them during an upgrade install

Thanks again,
Sean





Re: ClickOnce and Setup & Deployment Projects How can I distinguish between install and upgrade?

PhilWilson

In-use files get detected and if there's no top-level Window app that can release them, yes, they get scheduled for replacement later. Vista might give you a files in use dialog because the in-use detection is better. With other tools you could write a custom action to detect your in-use files and show a files in use dialog, but Visual Studio setups don't have that hook.




Re: ClickOnce and Setup & Deployment Projects How can I distinguish between install and upgrade?

sponeil

Ok, thanks. That answers all my questions for now.