One of the frequent problems with the installations is when some file or registry entry is not removed from the system upon un-installation of the product. Clean removal is always highly desirable.
One major reason for that is badly authored installation, and especially, when installation author tries to change the logic of Installer by putting in various conditions, custom actions, and such. This is practically always bad idea.
Installer itself takes into account very big number of various deployment scenarios, such as advertising, managed installations, assigned installations, roaming profiles, running on terminal server, and more; the author in his efforts usually only considers the most obvious and straightforward scenario, which is practically the guarantee of problems whenever any other scenario is encountered.
Funny enough, Microsoft itself is good example of these practices - and the result is easy to see by checking out long articles with the names "How to remove <insert product name here>". Other companies create separate utilities to remove their products - Nero and Nvidia come to mind. Properly authored installation does not require special efforts to remove it.
The remedy lies in two basic principles.
don't create custom actions when it's not absolutely necessary. Remember, every custom action is essentially a black box for Installer, and unlike standard actions, everything your custom action does, if only your own responsibility. If you create a registry key by custom action, then you have to remove this key also by custom action, taking into account, again, all possible scenarios of deployment, including those you didn't even know existed.
run ICE validation and take care of everything it finds, even if you don't understand why it is necessary (but validation does).
Even then, some files can remain
Even with properly authored installation, some files will not be removed. And we are not talking about the user files created by the application, we are talking about the files created by the installation itself.
Two major reasons for this are:
1. for dll's, shared dll count>0
Let's look into #2.
2. component count >0 .
Different installations may share the same component (which is the smallest granular piece of the installation, representing a set of related files, registry entries, and may be some other things). The component is identified by its GUID in the installation, and Installer keeps track of all the components in all installed products under HKLM\software\microsoft\wi
Under Userdata there are several keys corresponding to the credentials on the machine (the machine itself, and the users), and under each there are all components of all products installed per-credential (i.e per-machine or per-user).
Each component goes under registry key with the name being converted GUID of the component in the installation; to find, take the first portion of the GUID, up to the dash, and invert it. For example,
} will become A8B60C14A3F84E34D89D2EC3C3B256AE
- if you look closely, you will notice inverted portions of the GUID in the string in the registry. The first three parts are mirrored and the last two parts have two characters reversed each time.
Under each such registry key, there's one or more string values representing the products that have installed this component. The name of the value represents the product code of the installation, in a similar way to the above. For example, product code
E} will be represented by the value named 3A84003FA9B8C8041B86928FB4
7837E4 in the registry.
If two installation install the same component, then the number of values will be more than one; if now one of these products is uninstalled, Installer will still keep the component in the system.
The decision about the fate of each component is made by Installer during the installation (or un-installation) and can be seen in the detailed installation log:
MSI (s) (68:C0) [09:40:32:993]: Component: registry; Installed: Local; Request: Absent; Action: Null
the above line is exactly what happens when the same component has been installed by two products, and one of them is now being uninstalled. Installer sees that the component is installed (Installed: Local), that uninstallation wants to remove it (Request: Absent), but the final decision is not to do anything (Action: Null) - because the component is still referenced by another product. So the value stays in the registry. Only when we uninstall the 2nd product as well, in its uninstallation log we will see
MSI (s) (68:D8) [09:43:04:037]: Component: registry; Installed: Local; Request: Absent; Action: Absent
so the Action is carried on, and the component is finally removed.
It would be highly desirable if Installer was putting in the log not only its verdict (Action) but also the reasons to it, but so far we are on our own - at least we see what it has decided.
The above was about removing the files and registry entries created by the installation itself. But besides them, every real-life application has its own files and registry keys representing user settings and user data. Should those be removed as well? Installation authors usually say yes, for the cleanest experience. However, there are reasons not to - such as possible future re-installation. Don't you want the user to return to your product? and if he does, wouldn't it be great to find all settings again in place? especially if is a trial being removed, there's always hope that the user will decide to go for the full version. So, if these files left behind aren't very large, the wise choice is to leave them in place, and this is the most common practice - even if you look at your Wii system, you will see the data left behind by the games you played years ago and already forgot.
The most intelligent products, however, ask the user during uninstallation: do you want to remove your user data? - and then does as it told. This is probably the most user-friendly way, and highly recommended.