Upgrade Problem
-
daveman1010220
- Posts: 7
- Joined: Wed Mar 25, 2009 10:41 am
Upgrade Problem
Hello. I'm trying to find a solution to a troubling problem. We recently upgraded to InstallAware 8 for our project from a different MSI-based installer.
Once our product is installed, it is crucial to the operation of the machine that it works properly unless it is completely removed.
A scenario has been discovered, whereby we can find the machine in an unusable state if upgrade fails. This failure happens if for some reason, we cannot complete the installation of the new version and a rollback is triggered. However the rollback only uninstalls the new version. It does not replace the old version. This is obviously unacceptable.
My question is, shouldn't there be a way to ensure that the old version is restored by the installer, given that the new version did not successfully install?
If such a mechanism exists, could someone provide an 'outline' of how this would work using InstallAware 8?
Once our product is installed, it is crucial to the operation of the machine that it works properly unless it is completely removed.
A scenario has been discovered, whereby we can find the machine in an unusable state if upgrade fails. This failure happens if for some reason, we cannot complete the installation of the new version and a rollback is triggered. However the rollback only uninstalls the new version. It does not replace the old version. This is obviously unacceptable.
My question is, shouldn't there be a way to ensure that the old version is restored by the installer, given that the new version did not successfully install?
If such a mechanism exists, could someone provide an 'outline' of how this would work using InstallAware 8?
-
MichaelNesmith
- Posts: 3452
- Joined: Thu Dec 22, 2005 7:17 pm
- Contact:
A very easy way to do this would be using Windows Installer 4.5 and the transaction mechanism. Read our blog for information on how to use the MSI Transaction plug-in, or refer to the help file. If anything fails, you can roll-back the system to the entire state before your uninstall and failed reinstall attempt with a single command.
Michael Nesmith
Install[b]Aware[/b]
[i]Home of The Next Generation MSI Installer[/i]
Get your free copy today - http://www.installaware.com/
Install[b]Aware[/b]
[i]Home of The Next Generation MSI Installer[/i]
Get your free copy today - http://www.installaware.com/
-
daveman1010220
- Posts: 7
- Joined: Wed Mar 25, 2009 10:41 am
Awesome!
This works very nice, thanks for the tip. Do you know of anywhere, possibly on the forums, where there is a silent check / upgrade script for msi45? That's sort of the last step in making this all work cleanly.
I do not have an option to check / install my new msi installer 4.5 in the installaware script. The newest version it seems to show in installaware studio 8 is 3.1. I installed the MSI4.5 installation package, downloaded from the InstallAware site.
Thanks in advance!
I do not have an option to check / install my new msi installer 4.5 in the installaware script. The newest version it seems to show in installaware studio 8 is 3.1. I installed the MSI4.5 installation package, downloaded from the InstallAware site.
Thanks in advance!
-
MichaelNesmith
- Posts: 3452
- Joined: Thu Dec 22, 2005 7:17 pm
- Contact:
-
daveman1010220
- Posts: 7
- Joined: Wed Mar 25, 2009 10:41 am
Re-Ran the Installer
Ok, I re-ran the installer to confirm that I did indeed have all the necessary components installed and that they are the versions that came with the InstallAware 8 installer. The attached is what I see for Windows Installer options, even though the InstallAware 8 installer clearly said it supports 4.5. Shouldn't there be another option in this pane? 
File Attached:
dialog.JPG
File Attached:
dialog.JPG
-
MichaelNesmith
- Posts: 3452
- Joined: Thu Dec 22, 2005 7:17 pm
- Contact:
-
daveman1010220
- Posts: 7
- Joined: Wed Mar 25, 2009 10:41 am
Thanks For The Help!
This all works very well. Fixed the rollback problem nice and clean. 
-
daveman1010220
- Posts: 7
- Joined: Wed Mar 25, 2009 10:41 am
Upgrading MSI Transaction-Enabled Installer Causing Problems
Hello. Everything was going so well with the new MSI transaction code until I tried upgrading a new build with the msi transaction logic in it to a newer build with the msi transaction logic in place. For reasons I have been unable to discern, the installer will freeze during the very earliest removal stage of the old installer.
The theory I was working on was that an MSI transaction was being created inside of an existing msi transaction and that was somehow causing a problem. I arrived at this theory due to the fact that upgrading from an older installer that does not have msi transaction works fine.
Since we pass a variable across the command line of the upgrading / uninstalling installer that lets us know it is an upgrade, I tried placing all the msi transaction logic inside conditional IF branches, so that the transaction does not happen if the upgrade variable is set by command line.
This did not work and all attempts to validate whether this variable is actually getting set have failed. I have tried message boxes. I have tried the built-in debugger. I have even tried to glean something from procmon with no luck there either.
Is upgrading from one installaware installer built with msi transaction to another built with msi transaction supposed to work? Are there any known issues here?
Thanks in advance.
The theory I was working on was that an MSI transaction was being created inside of an existing msi transaction and that was somehow causing a problem. I arrived at this theory due to the fact that upgrading from an older installer that does not have msi transaction works fine.
Since we pass a variable across the command line of the upgrading / uninstalling installer that lets us know it is an upgrade, I tried placing all the msi transaction logic inside conditional IF branches, so that the transaction does not happen if the upgrade variable is set by command line.
This did not work and all attempts to validate whether this variable is actually getting set have failed. I have tried message boxes. I have tried the built-in debugger. I have even tried to glean something from procmon with no luck there either.
Is upgrading from one installaware installer built with msi transaction to another built with msi transaction supposed to work? Are there any known issues here?
Thanks in advance.
-
MichaelNesmith
- Posts: 3452
- Joined: Thu Dec 22, 2005 7:17 pm
- Contact:
You cannot nest transactions - Windows Installer does not allow this - and the plug-in will return an error code:
http://msdn.microsoft.com/en-us/library ... S.85).aspx
Why are you unable to print the variable? What happens when you try to print its value via MessageBox, for instance?
http://msdn.microsoft.com/en-us/library ... S.85).aspx
Why are you unable to print the variable? What happens when you try to print its value via MessageBox, for instance?
Michael Nesmith
Install[b]Aware[/b]
[i]Home of The Next Generation MSI Installer[/i]
Get your free copy today - http://www.installaware.com/
Install[b]Aware[/b]
[i]Home of The Next Generation MSI Installer[/i]
Get your free copy today - http://www.installaware.com/
-
daveman1010220
- Posts: 7
- Joined: Wed Mar 25, 2009 10:41 am
As it turns out, I had an argument that was making the messagebox silent still in the secondary uninstaller. So now I get my messagebox and it tells me a lot. I now know that my argument is indeed getting passed in and that I am indeed skipping over the MSI transaction stuff during upgrade uninstalls. I have narrowed the problem down to what appears to be an infinite loop inside of 'Apply Uninstall (get result into variable SUCCESS)'. It is not simply slow, it will never return once it gets to this point.
I am using a command like this to call the uninstaller:
Run Program $OLDINSTALLER$ REMOVE=TRUE MODIFY=FALSE REPAIR=FALSE UNINSTALLFORUPGRADE=TRUE (WAIT)
So using this command, the same as was done with the installer pre-msi-transaction, it now hangs. I have only removed the /s after 'run program' so that I can see what is happening with my messageboxes.
Any ideas?
I am using a command like this to call the uninstaller:
Run Program $OLDINSTALLER$ REMOVE=TRUE MODIFY=FALSE REPAIR=FALSE UNINSTALLFORUPGRADE=TRUE (WAIT)
So using this command, the same as was done with the installer pre-msi-transaction, it now hangs. I have only removed the /s after 'run program' so that I can see what is happening with my messageboxes.
Any ideas?
-
daveman1010220
- Posts: 7
- Joined: Wed Mar 25, 2009 10:41 am
Upgrade Problems Continue
It appears that whatever is causing us grief here occurs when we do a:
'Run Program $OLDINSTALLER$ REMOVE=TRUE MODIFY=FALSE REPAIR=FALSE UNINSTALLFORUPGRADE=TRUE (WAIT)'
The install script will do everything it seems it should do, except for actually completing the 'Apply Uninstall' in the secondary installer.
I thought I had made a discovery when I was able to achieve a successful
upgrade after changing the PRODUCT CODE in InstallAware.
As it turns out, the real effect of changing the product code in InstallAware
is that it runs the following line our script:
'Install/Remove MSI Package $OLDPRODUCTCODE$[REMOVE=ALL UPGRADINGPRODUCTCODE=TRUE] (get result into variable REMOVEOLD)
instead of the 'Run Program...' line detailed above. What this really means is that for whatever reason, the simpler version of the uninstall, the one that does not attempt to run our custom actions, succeeds. I do not believe it is directly caused by our custom actions, just that the code path required to run our custom actions is failing.
Is there any reason you can think of the installer might simply never return from the 'run program' call to uninstall at the point of 'apply uninstall'? The other variation of this I see when changing the product code, yet still calling the 'run program...' logic is that the installer returns and simply says that the product cannot be directly uninstalled and that I'll have to uninstall it manually before proceeding.
Please keep in mind this only happens with MSI transactions in the InstallAware script.
'Run Program $OLDINSTALLER$ REMOVE=TRUE MODIFY=FALSE REPAIR=FALSE UNINSTALLFORUPGRADE=TRUE (WAIT)'
The install script will do everything it seems it should do, except for actually completing the 'Apply Uninstall' in the secondary installer.
I thought I had made a discovery when I was able to achieve a successful
upgrade after changing the PRODUCT CODE in InstallAware.
As it turns out, the real effect of changing the product code in InstallAware
is that it runs the following line our script:
'Install/Remove MSI Package $OLDPRODUCTCODE$[REMOVE=ALL UPGRADINGPRODUCTCODE=TRUE] (get result into variable REMOVEOLD)
instead of the 'Run Program...' line detailed above. What this really means is that for whatever reason, the simpler version of the uninstall, the one that does not attempt to run our custom actions, succeeds. I do not believe it is directly caused by our custom actions, just that the code path required to run our custom actions is failing.
Is there any reason you can think of the installer might simply never return from the 'run program' call to uninstall at the point of 'apply uninstall'? The other variation of this I see when changing the product code, yet still calling the 'run program...' logic is that the installer returns and simply says that the product cannot be directly uninstalled and that I'll have to uninstall it manually before proceeding.
Please keep in mind this only happens with MSI transactions in the InstallAware script.
Michael,
I have taken over this issue from Dave. I have reproduced the problem in a simple installer that includes nothing specific to our application. I created the installer project by going through the project wizard and creating the simplest of installers. Then I added a prerequisite for MSI 4.5 so I can use transactions, and altered the MSICode a bit to:
1. make use of the transactions, and
2. remove the old version by calling Run Program on the old installer listed in the registry instead of calling "Install/Remove MSI Package $PRODUCTCODE$," because using the "Install/Remove MSI" call causes the MSICode of the old installer to not be executed.
During an upgrade, the removal of the old version hangs on "Apply Uninstall" if we're using transactions.
The flow of the MSICode can be boiled down to:
As you can see, the MSI Transaction is begun and committed in the first installer. When uninstalling as part of an upgrade, the UNINSTALLFORUPGRADE variable is set to TRUE which stops the code from beginning or committing a transaction since one is already in progress. Unfortunately, though, the call to "Apply Uninstall" hangs.
I have zipped up my simple project and attached it to this message. To reproduce the issue, simply build the project, install it, update the Revision Code, build it again, and run the newly built version. It will freeze after calling apply uninstall inside of the 2nd installer.
Note that I've added a bunch of diagnostic message boxes to the MSICode. Note, also, that we ultimately will be removing the old version silently. The "/s" switch has been removed here to help with debugging.
Thanks,
Jack
File Attached:
TransactionUpgradeFreeze.zip
I have taken over this issue from Dave. I have reproduced the problem in a simple installer that includes nothing specific to our application. I created the installer project by going through the project wizard and creating the simplest of installers. Then I added a prerequisite for MSI 4.5 so I can use transactions, and altered the MSICode a bit to:
1. make use of the transactions, and
2. remove the old version by calling Run Program on the old installer listed in the registry instead of calling "Install/Remove MSI Package $PRODUCTCODE$," because using the "Install/Remove MSI" call causes the MSICode of the old installer to not be executed.
During an upgrade, the removal of the old version hangs on "Apply Uninstall" if we're using transactions.
The flow of the MSICode can be boiled down to:
Code: Select all
if Variable CMDLINE not Contains (Ignore Case) UNINSTALLFORUPGRADE=
Set Variable UNINSTALLFORUPGRADE to FALSE
end
if Variable UNINSTALLFORUPGRADE not Equals TRUE
MSI Transaction : Begin New Transaction
end
if Variable NEEDSUPGRADE Equals TRUE
Read Registry Key HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\$PRODUCTCODE$\\UninstallString into OLDINSTALLER
Run Program $OLDINSTALLER$ REMOVE=TRUE MODIFY=FALSE REPAIR=FALSE UNINSTALLFORUPGRADE=TRUE (WAIT)
end
if Variable REMOVE Equals TRUE
Apply Uninstall (get result into variable SUCCESS) <-- THIS HANGS!
if Variable UNINSTALLFORUPGRADE not Equals TRUE
MSI Transaction : Commit Changes
end
else
Apply Install (get result into variable SUCCESS)
if Variable UNINSTALLFORUPGRADE not Equals TRUE
MSI Transaction : Commit Changes
end
end
I have zipped up my simple project and attached it to this message. To reproduce the issue, simply build the project, install it, update the Revision Code, build it again, and run the newly built version. It will freeze after calling apply uninstall inside of the 2nd installer.
Note that I've added a bunch of diagnostic message boxes to the MSICode. Note, also, that we ultimately will be removing the old version silently. The "/s" switch has been removed here to help with debugging.
Thanks,
Jack
File Attached:
TransactionUpgradeFreeze.zip
using InstallAware 9 R2 (Build Moya.sp3.070910)
-
MichaelNesmith
- Posts: 3452
- Joined: Thu Dec 22, 2005 7:17 pm
- Contact:
If you look at your setup, its not hanging but waiting for the Windows Installer mutex to be released. It is already being held by the transaction you began in your other setup.
Michael Nesmith
Install[b]Aware[/b]
[i]Home of The Next Generation MSI Installer[/i]
Get your free copy today - http://www.installaware.com/
Install[b]Aware[/b]
[i]Home of The Next Generation MSI Installer[/i]
Get your free copy today - http://www.installaware.com/
Are you saying that you cannot perform an uninstallation of an InstallAware-based .exe installer as part of an upgrade after starting an MSI transaction?
If I uninstall the old version using "Install/Remove MSI" instead of calling "Run Program $OLDINSTALLER$," it does not hang. However, doing it that way doesn't work for us because it means none of our MSICode for uninstall gets executed.
If I uninstall the old version using "Install/Remove MSI" instead of calling "Run Program $OLDINSTALLER$," it does not hang. However, doing it that way doesn't work for us because it means none of our MSICode for uninstall gets executed.
using InstallAware 9 R2 (Build Moya.sp3.070910)
For posterity and the benefit of any IA users who may run into this, trying to use an MSI 4.5 transaction to wrap an upgrade while still maintaining the functionality of uninstalling the upgrading-from version using the UninstallString from the registry to call the .exe version of the upgrading-from installer...
The problem was that if we uninstalled the upgrading-from version from within an MSI transaction started in the installer for the upgrading-to version, the upgrading-from version's uninstaller would hang on the "Apply Uninstall" function. We could avoid the freeze by using the "(Un)Install MSI Setup" function within the upgrading-to installer to remove the upgrading-from version. However, if we did that, all of the MSICode - including the code that calls the upgrading-from version's custom actions - would not be executed. We seemed to be at an impasse since we needed both the transaction functionality and for the MSICode of the upgrading-from uninstaller to be executed. Copying the MSICode from the upgrading-from version into the upgrading-to version was not an option because it needed to remain general. That code could change over time, and we need to be able to upgrade from any previous version. We can't keep all of the various revisions of the uninstallation MSICode in the current installer's upgrade code.
I solved this by altering the Uninstall section of the MSICode to not call "Apply Uninstall" if we're uninstalling as part of an upgrade. Then, I altered the Upgrade section to first run the upgrading-from version's uninstaller, telling it via a command line variable to uninstall as part of an upgrade, then when it completes and returns execution to the upgrading-to installer, the upgrading-to installer calls "(Un)Install MSI Package" to actually remove the old version. This maintains generality - it ensures that the correct MSICode and custom actions are run for whatever version we are upgrading from while also avoiding the freeze caused by attempting to start a second MSI operation whilst holding an MSI Transaction token.
The problem was that if we uninstalled the upgrading-from version from within an MSI transaction started in the installer for the upgrading-to version, the upgrading-from version's uninstaller would hang on the "Apply Uninstall" function. We could avoid the freeze by using the "(Un)Install MSI Setup" function within the upgrading-to installer to remove the upgrading-from version. However, if we did that, all of the MSICode - including the code that calls the upgrading-from version's custom actions - would not be executed. We seemed to be at an impasse since we needed both the transaction functionality and for the MSICode of the upgrading-from uninstaller to be executed. Copying the MSICode from the upgrading-from version into the upgrading-to version was not an option because it needed to remain general. That code could change over time, and we need to be able to upgrade from any previous version. We can't keep all of the various revisions of the uninstallation MSICode in the current installer's upgrade code.
I solved this by altering the Uninstall section of the MSICode to not call "Apply Uninstall" if we're uninstalling as part of an upgrade. Then, I altered the Upgrade section to first run the upgrading-from version's uninstaller, telling it via a command line variable to uninstall as part of an upgrade, then when it completes and returns execution to the upgrading-to installer, the upgrading-to installer calls "(Un)Install MSI Package" to actually remove the old version. This maintains generality - it ensures that the correct MSICode and custom actions are run for whatever version we are upgrading from while also avoiding the freeze caused by attempting to start a second MSI operation whilst holding an MSI Transaction token.
using InstallAware 9 R2 (Build Moya.sp3.070910)

