I use InnoSetup 5.5.1 (a) for my Delphi 6 software installations. A user just informed me that the old uninstall entries pile up in the Control Panel Remove Programs list if not uninstalled manually. I'm thinking of changing my install to remove old entries automatically but I don't want to remove old entries that are valid. Some users like to keep an old version or two around in case they don't like a later version or for fear a later version will break something.
For clarity's sake, I am referring specifically to the typical situation where a user usually accepts the default installation directory, overwriting the existing version. However, with the exception that some users may install one or more versions to a different directory just to preserve them, while choosing to overwrite most of the time. I found this SO post on removing old versions:
InnoSetup: How to automatically uninstall previous installed version?
But did not see any mention on knowing how to detect which of the old versions are superfluous or not.
Therefore, during an install, how can I automatically remove old uninstall entries automatically from the installed program list without removing any that the user actually wants to keep?
As long as you keep your AppId the same between different versions of your application, there will only ever be one Add/Remove entry for it, no matter how many times the user runs the installer. This is the normal and recommended design for a typical application where the user only has one copy of it and wants to keep it up to date.
If, however, the user chooses alternate installation locations in one or more of the later installs, then it's possible for the older location to get "orphaned" -- running the uninstall will remove the newer copy but leave the older one behind, with no Add/Remove entry. (It will still be possible to uninstall it by running the uninstaller manually.) It's normally recommended to avoid this situation by including these options in your [Setup] section:
DisableDirPage=auto
DisableProgramGroupPage=auto
Using these options will make Inno skip asking these questions for an upgrade install, which helps to prevent the user accidentally making orphan copies. (If the user does intentionally want to move the installation, they can still do it by uninstalling first.)
Note that I've sidestepped your question a bit, since as written it doesn't make sense -- if there are multiple copies, there's no possible way to automatically determine which are "superfluous", since that's purely a judgement call on the part of the user. What I've tried to explain here is that your design should aim to discourage this happening accidentally.
Related
Scenario
An application is being installed via NSIS. As is required by NSIS, an uninstaller with an Uninstaller.dat is provided as well.
It is desired to collect all files that are to be removed during deinstallation using
!insertmacro UNINSTALL.LOG_OPEN_INSTALL
!insertmacro UNINSTALL.LOG_CLOSE_INSTALL
which are both provided by the AdvUninstLog plugin. However this is apparently impossible. If an uninstallation already exists on a machine and the plugin is active, the installation process starts taking an absurd amount of time, i.e. 5-10 minutes. That is because the ${Locate} "${TargetDir}" "/L=FD" "${UnLog_Install_Func_CallBack}" calls of the plugin begin searching the installation directory for files, endlessly. I am not clear as to why this behavior occurs. My suspicion is, that the Uninstall.dat contains files, that do not exists anylonger and have been deleted by users, causing long searches for the file. I am not certain of this, however.
Be that as it may, fact is, these calls cause lengthy waiting times for us and on client machines as well.
Attempts to deal with this
Omit !insertmacro UNINSTALL.LOG_OPEN_INSTALL and corresponding closing call. This will result in an empty Uninstall.dat, therefore the uninstaller becomes mostly useless.
Check if Uninstall.exe exists, if so assume a previous installation being present in target folder and omit !insertmacro UNINSTALL.LOG_OPEN_INSTALL and corresponding closing call. This works quite well, but will only collect all files once upon initial installation. Files that are added as part of updates, i.e. when users install over an existing installation, will no longer be recognized in the Uninstall.dat.
Attempt to edit Uninstall.dat during installation. Impossible, because apparently this file is read before installer sections and written after installer sections, so whatever I write to it will be wiped once the installer finishes, for my convenience.
Attempt to trigger an uninstallation before installing, using nsisExec. This is nonsense, because it will open a new uninstaller window above the installer window and take focus, as would be expected. This simply looks awful to the user, because suddenly there are two installation windows competing for their focus.
Possibly attempt to call uninstall before actual installation if a prior installation is detected. This, however, requires me to rewrite AdvUninstLog, because uninstallation is achieved using its macros and these are only valid for uninstall sections.
Questions
Why does it take forever to use !insertmacro UNINSTALL.LOG_OPEN_INSTALL in the first place?
What is the appropriate way to handle this problem?
I tried using RMDir /r $path, yet this had the exact same effect as just RMDir without /r, i.e. the folder is being deleted, however only once empty. What is going on there?
There are threads describing these issues since 2004, here are some examples:
http://forums.winamp.com/showthread.php?t=302976
https://gitlab.com/inkscape/inkscape/issues/300
https://nsis-dev.github.io/NSIS-Forums/html/t-356786.html
I am interested in finding a procedure to keep Uninstall.dat up-to-date, yet prevent absurdly long calls caused by the AdvUninstLog plugin. How can I achieve that?
I prefer the method used by another header (and the AdvUninstLog page also mentions this as an alternative):
https://nsis.sourceforge.io/Uninstall_only_installed_files
Like AdvUninstLog, an uninstall log is used to back out only the files and registry entries installed, though this header requires you to use macros that wrap your File, WriteRegStr, etc. calls.
I have found it's a good way to allow a cancelled installation to roll back its changes in conjunction with this header:
https://nsis.sourceforge.io/InstFiles_Cancel_-_Allowing_a_user_to_cancel_installation_during_InstFiles
(though note that if you need to be able to roll back an update, it's a bit harder as you'd need to make a backup of the existing install first).
This header has a lot of the same benefits of AdvUninstLog, but the benefit of AdvUninstLog over this one is that even if you're using wildcards with your File calls, your uninstall will only remove the files that were actually installed, but the cost is the potential for the slow performance that you've observed. In both cases you need to figure out how you want to deal with files added after the fact.
Re: Questions #1 and #2, even the AdvUninstLog page mentions this drawback (though not why). As for question #3, it's unclear, but perhaps you were trying to do it before closing the Uninstall.dat. In a pinch, you could always use "RMDir /r /REBOOTOK" and allow Windows to finish the cleanup after rebooting.
I am using Visual Studio 2013 installer to package my application. I then make a copy of the MSI, open it in Orca and remove all the dialogs to create a silent package. So I have two MSI's that should be the same other than one is silent and the other is not.
When I upgrade from a previous version (built in the same way) using the non-silent package, everything works perfectly.
However when I upgrade from a previous version using the silent package, it all works apart from I am left with 2 entries in Add/Remove programs. It all works though but looks ugly for the client. When i uninstall the latest version, Add remove programs still has the previous version listed in Add/Remove programs although actually the latest version is still installed.
As I say, the non-silent package works perfectly well, which leads me to think I must have everything setup correctly in Visual Studio and Orca must be doing something I didn't intend.
Any help would be much appreciated.
If you have two entries in Add/Remove Programs then the upgrade didn't work. A common reason is that one of the installs is Everyone and the other is Just me. If you delete the dialogs then you have altered the behavior that sets the ALLUSERS property, and your upgrade could default to Just me. In the absence of a decision to use one of these choices VS setups use ALLUSERS=2 which is defaulting to a per user Just me install, that's the likely reason. Elevation is involved too - VS setups would rather your MSI did a successful Just me instead of a failing Everyone if privilege state is not clear (and in MSI setups it often isn't).
You might need to go to the Property table and set FolderForm_AllUsers to "ALL" and ALLUSERS to 1 to force a per machine Everyone install.
How silent do you want it to be? If it requires elevation to install successfully then you need the elevation dialog to be shown or the install will fail silently if you force a per machine Everyone install.
I am using WiX to install a executable and I have used ManagedBootstrapperApplicationHost for CustomUI.
Is it possible to get the name of the feature being installed at the time of installation ?
If possible then how can we get the name of the feature ?
Any help would be appreciated.
Thanks.
Features aren't installed one after another. For example if 3 features are being installed, each with 10 files then the InstallFiles action will install all 30 files at the same time. Same thing with registry entries. So you can't display a UI that says "Installing Feature1" and then later on "Installing Feature2" because that doesn't happen. All you can know is that some list of features are being installed.
Your comment asks about finding out whether a feature installed successfully or not. This issue never comes up - there are never some features that install and others that fail. An MSI install is a transaction and it either all works or fails and rolls back and deletes changes it made so that the system is restored to its previous state.
It's not clear why the list of features is so important to display. If you use the MSI's internal UI there is a feature selection dialog where the user selects which features are to be installed; if you use the Burn UI the same thing is available, so the user can see what features have been chosen.
Inside the MSI the list of features being installed (after they've been selected) is in the ADDLOCAL property, but that's the internal name. It could be used to display a list of the features that were installed at the end, but again by definition what was chosen is installed otherwise the install would have rolled back entirely. I don't believe I've ever seen an install where the list of MSI features installed is displayed at the end - it's redundant info. It would be useful to know the scenario you have, or what problem you're trying to solve, and if you believe that you need to display a list because some might install and others might fail then there is no point, as I have said.
I have a question concerning software updates. Currently I install new releases into a different folder each time. The user is then required to re-enter configuration parameters. This of course is not too optimal. The software is Windows forms and I use the settings. Settings file.
So the question is what happens if I install a newer version into the same folder as a previous install? Will files just get replaced? What about if I have added settings in the new version? Will they be merged?
Anything to watch out for?
Thanks
When the MSIs are related, typically you can only have one instance of it installed at a time. If that's the case, first the earlier version may be uninstalled, so the question is whether the files that store the settings are removed by uninstalling your MSI.
If the MSIs are not related, you can get into a world of pain by overlapping their installations (probably breaking component rules by having two different components describe the same file in the same location, but with a different component code), yet the core question comes down to the same thing: will the updated installation lay down the file that stores the settings.
These are likely the same question, as the easiest way to remove or install a file is by including it in the MSI directly. (There are other ways, but I'm assuming you're not using those yet.) If the file is not part of the installation, nothing will happen to it, and the answer to your question comes down to what your application does when it runs with a settings file created in a different version. If the file is part of the installation, and component rules are not being broken, it will either be uninstalled then freshly installed (wiping any configuration), or per File Versioning Rules and Default File Versioning, the file will either be left untouched or completely replaced with the new version. Windows Installer doesn't know how to merge your settings file.
Thanks for taking the time to answer my question.
So bottom line I should just avoid these issues and install in another folder. I should also make a copy of the settings and put them in my own file which can be used to update my new installation. That would be the safest route I guess.
Thanks
We have an installer solution written in Visual Studio 2005 Installer; that calls a C# custom action and we have hit a known issue, regarding the fact that on an upgrade - the old install code is run and not the new code, because Windows is running a cached version of the custom action dll. We know this and although not over the moon about it - we have moved on.
When we release a new version of the installer and a user runs it, we now want it to check to see if an ealier version is installed - if there is one; we want to display a message telling them that they have to remove the old version via Add/Remove Programs. We know if they do a manual uninstall followed by an install, then all is fine and dandy - BUT it doesn't matter how many times we tell our users, via documentation; that this is what they have to do - they will still try and just run the new installer, without removing the old version first.
Therefore, we would like to put up a message and thus force them to to what they are told !! I've seen some installers do this ( though of course not sure what installer package was used to create these ). We only have VS 2005 and of course orca !!
Cheers,
Chris.
This can be done through a custom launch condition:
create a search which determines if the old version is installed (you can search for a component, registry entry or file)
use the search property as a custom launch condition
For example, if the search property is OLD_VERSION, the launch condition can look like this:
Condition: NOT OLD_VERSION
Description: An older version was found. Please uninstall it using "Programs and Features" in Control Panel.
When OLD_VERSION property is set to a value (an older version is found), this launch condition will show the message and stop the install process.
This doesn't quite make sense. Have you remembered to change the package GUID in your new setup? The package GUID identifies a specific setup file, and if two MSI files have identical GUID they will be treated as the same file regardless of whether they are or not. This could trigger a cached version of the MSI to be invoked and all sorts of hell breaks loose.
I would recommend reading up on "major upgrades" which will allow automatic uninstall of the existing version before the new version is installed. You also need to make sure you understand the basics of the technology before deploying to the wild. You must NEVER use identical package GUIDs for any MSI files. It's practically always wrong, and will lead to very mysterious problems.
I can't write up the whole major upgrade solution here, but basically it involves authoring the "Upgrade" table of your MSI to detect versions to uninstall. You need to change the package code, product code and version number (only 3 digits matter) and keep the same upgrade code (two MSI files with the same upgrade code "know" they are related - i.e they are from the same product family). Check MSDN for samples of major upgrades.
NB! If you have deployed MSI files with duplicate package GUIDs to your developer machine, it could have stray installs that must be cleaned up with MSIZap or similar. Use caution, or better yet test your new installer on a clean test system. Developer systems are full of junk and not generally good for MSI testing.