Jonathan Perret made the following interesting comment on a previous blog entry:

...I find it worrisome that even when using such a powerful tool as WiX, one still has to memorize such oddities. I mean, if my app has a prereq it sounds obvious I don't want to require it to uninstall the app. Why can't WiX implement this for me ?

Do you think it is a fair analogy to say that if Orca is like an hex editor then WiX would be MASM ? I.e. powerful for experts but every bit as dangerous ?

I'm going to address those in the opposite order.  First, I often introduce the WiX toolset as the C/C++ compiler/linker for MSI files.  With C/C++ you can leak memory, deference NULL and all kinds of other things that the programmer probably didn't intend.  The WiX toolset will similarly allow developers to do things that might not be what they actually intended.

I think comparing the WiX toolset to MASM is cutting a bit too deep.  There are many things the WiX toolset handles that the developer never has to worry about.  Always lining up primary/foreign key references in the MSI database is an obvious one but there many others like the handling of the NULL property ([~]) in MULTI_SZ registry keys and the NT service groups and enabling distributed setup development through Fragments and linking.

So why doesn't the WiX toolset just handle everything for the developer?  The answer is quite simple: "Because a developer might actually need to do what you wanted protection from." 

In this particular case, I provided guidance that the Installed property should always be OR'd into your LaunchConditions.  Doing so ensures that you can uninstall the application even if the condition is wrong.  The WiX toolset could probably always automagically add "Installed OR" to LaunchConditions to make sure that this guidance is followed.

But what if you as a developer actually need to block the uninstall of your application for some very specific reason?  If the WiX toolset always adds "Installed OR" to the LaunchCondition the developer is now fundamentally screwed by the very tools that were supposed to be helping.  Being a developer, I know that stupid tools trying to be smart are one of the fastest ways to infuriate a developer.

Remember, one of the guiding principles of the WiX toolset is that if the Windows Installer supports the scenario then the WiX toolset does as well or it's a bug.

So the question now is how do we enable developers do what they need to do while helping them avoid known pitfalls?  I know of two methods, both of which are supported in the WiX toolset.

1.  Static code analysis.  Tools that understand the code and point out things that you probably did not intend are wickedly cool.  Visual Studio added static analysis features in VS2005.  The Windows Installer has actually had static analysis since the late 1990s.  It's called "validation" and msival2.exe and Orca both support it.  In WiX v3, light.exe now runs the same static code analysis after every build and there is a tool called smoke.exe that you can use to analyze MSI files without building.

That said, today there is no rule that checks for the Installed property in LaunchConditions but it seems like a great thing to open as a Feature Request, Jonathan.

2.  Higher level languages.  I am obviously biased but I don't believe you will find a better low-level language for creating Windows Installer databases than WiX.  You can edit the .wxs files directly, use a GUI that converts the WiX elements into graphical concepts, or build another language that generates .wxs files and build your MSI files that way.  Higher level languages can be more simplistic because they target a specific need.

For example, I haven't talked about ClickThrough much lately but if you look at the language required to describe an Isolated Application in ClickThrough, I think you'll agree it's much higher level.

<IsolatedApp xmlns="http://wix.sourceforge.net/schemas/clickthrough/isolatedapp/2006">
   <Package>
      <Feed>http://localhost/ct/dc/DrizzleCast.feed</Feed>
      <UpdateRate>1</UpdateRate>
   </Package>
   <Application>
      <EntryPoint>DrizzleCast.exe</EntryPoint>
      <Source>C:\build\dc</Source>
   </Application>
</IsolatedApp>

For more information check out this blog entry about "domain specific languages".