I've learned some interesting facts about MSI-based setups in the past few days. Working together, they can cause some really tricky and nasty issues if you are unaware of them. (In other words, this is why I'm still at work at 2:00 in the morning.)
This is more proof that MSI setup is not something you can pick up overnight -- you really need to be aware of a lot of "gotchas".
Fact #1 is scary all by itself. If the feature's level is 0, it will not be touched by the installer. This may or may not be what you want.
Setting the level to 0 is a commonly used method to hide a feature under certain conditions. The logic is: IF (condition) THEN set Level=0. However, you must be absolutely certain that the condition is FALSE if the product is being uninstalled. If the condition evaluates to TRUE, and the feature has been installed somehow, the feature will be left behind (orphaned) when the rest of the product is uninstalled. There will be no way to uninstall the feature. The feature's components are forever stuck on the user's computer. You've just screwed up your customer's machine. Bad programmer, no donut.
As a quick example, consider the following condition (if true, the feature's level will be set to 0):
The intent is probably to hide the feature if .NET 2.0 is not installed (.NET 2.0 is a prerequisite for the feature). However, if the user uninstalls .NET 2.0 before uninstalling the product, the condition becomes true during uninstall, the feature's level is set to 0, and the feature is orphaned. Bang, you're dead.
Now let's assume that your users are smart enough to not uninstall .NET 2.0 before uninstalling your product. Being the devious users that they are, they'll probably find some other way to break your install. This is where facts #2 and #3 come in.
Assume your user is using Vista with UAC enabled. The user installs your product as usual. Later on, the user wants to uninstall. He goes to "Programs and Features" (formerly Add/Remove Programs), right-clicks on your product, and selects "Change", then from the installer's UI selects "Remove". Here's what happens:
Solutions to these issues will be considered in my next blog. Stay tuned!