Windows Installer and the creation of WiX

Bender the Greatest picture Bender the Greatest · May 19, 2011 · Viewed 9.5k times · Source

We currently use WiX for building our MSI files, and as such it is the only MSI builder I have had experience using. I know you can build installers natively in Visual Studio though. What are the differences between using WiX and Windows Installer, and what the pros and cons are of each?

Answer

Stein Åsmul picture Stein Åsmul · Aug 24, 2012

I just want to add some more specific technical information on the Windows Installer technology itself, and some of the history leading up to the creation of the WiX toolkit since this post may be found by people who are just getting into the field of installers, WiX and Windows Installer.

This is intended as a quick introduction to WiX and MSI from a developer's perspective. There is also a somewhat popular serverfault.com article that might be useful to grasp Windows Installer's benefits: The corporate benefits of using MSI files (many developers dislike Windows Installer, but the corporate deployment benefits are actually quite significant - perhaps worth a quick skim if you think MSI is more trouble than it is worth).

The origin of the WiX toolkit

MSI files are essentially stripped down SQL Server databases stored as COM-structured storage files. This is the file format used in Microsoft Office (note that MS Office used to use OLE / COM files - but newer versions now use Office Open XML), and it was designed as a way to store hierarchical data within a single file. Essentially a file system within a file with storage streams of various types - one of which is the files to install inside one or more cab files .

Early on MSI files / databases were best modified directly using third-party tools such as InstallShield, Advanced Installer and Wise Package Studio (no longer available due to legal issues - see a comparison of currently available MSI tools).These tools stored the MSI file in its native "installable" format as a COM structured storage file. This meant your MSI file was both source and executable - and in binary format. This made source control of your installation project difficult. Binary diffs on different MSI databases were difficult, and due to database referential integrity even the most basic changes in the MSI will cascade through dozens of tables and make it difficult to see what changed even for trained eyes.

WiX came around as a way for developers to allow the creation of a binary MSI file from regular text source files. Just like a regular EXE binary, an MSI binary is "compiled" from WiX text XML files. This is a quantum leap in terms of managing your release process and understanding changes in the MSI file. The toolkit is very comprehensive and much more intuitive for a developer and features a degree of "automagic" in that it shields the developer from some of the intricacies of the MSI database schema since changes are made in an XML format with its own schema and not the database itself. In effect WiX takes MSI from its database origins into the "XML age" of today so that developers work with text files, and the MSI files can be seen as compiled executables as opposed to database source files.

It is actually possible to make good MSI files without knowing too much about the inner workings of the MSI file - provided you follow WiX best practices - and trust me as a developer you will want to stay out of MSI files. They are complex, and distinctively unorthodox and counterintuitive for a developer mindset. It has to do with the complexity of storing a whole installer as a single database. It is almost entirely declarative and not procedural - but some parts are sequential and define installation order. Lots of moving parts and a clockwork of "conspiratory complexity" (gotchas that you discover as you thought everything was fine).

These sequencing constructs are some of the most complex parts of an MSI involving "elevated rights" and file system operations run as a database transaction. When you learn MSI as a developer you are bound to feel that "something is wrong with this design", and the truth is that the whole technology was designed around the deployment requirements for Office back in the day - and it became as complex as it had to be. Furthermore MSI files may be a preview of things to come - perhaps Windows will use SQL Server as its main storage solution in the future, and MSI is the first step in turning deployment into a "declarative language" or a huge SQL statement for what is going to happen on the target system during deployment? This is just speculation though.

Some practical WiX advice

Keep it simple, follow best practice and whatever you do don't fight the design - it fights back. If WiX can't do it, it is likely trying to help you avoid deployment problems. Fight your manager to simplify or change requirements, not MSI - for once it's easier :-).

Most of the time we find that unusual setup designs and the use of custom actions cause a lot of unnecessary complexity, or deployment anti-patterns if you like, and the problem can often be avoided by small changes in application design, or the use of built-in MSI constructs. A good manager will allow efforts to simplify deployment, but they need to understand why it is necessary. I like licensing as an example of how you can do things differently and make deployment simpler by avoiding old fashioned or needlessly, complicated application and deployment solutions.

Avoid unnecessary (read/write) custom actions at all cost - they quadruple a setup's complexity and risk. Ask here on Stack Overflow and search to see if there is a built-in alternative. In most or at least many cases, there are equivalent built-in constructs in MSI to get the job done.

This particular advice can not be overstated. In my personal opinion, read-only custom actions (that may set properties) are the opposite: they are recommended. They do not cause significant extra risk in most cases - since they make no changes on the system requiring rollback support, and can be used very effectively to gather setup logic in one place - and crucially they work well between co-workers to allow picking up each other's work when written in simple scripting languages such as JavaScript (some clunky aspects when dealing with the MSI API) or VBScript (poor error handling and overall language features, but well tested with the MSI API. Frankly it seems like Microsoft is trying to "kill" the language. JavaScript is at least "alive and well" in heavy use for web-stuff).

To wrap up things with regards to scripts: there is general agreement among deployment specialists that script actions of all types are in general hard to debug, vulnerable to anti-virus interference and lacking in language features needed to implement advanced coding constructs. In conclusion: it is hard to write robust code with scripts - of any type. Managed code custom actions are possible (.NET), but due to their requirement of .NET being installed, the safe recommendation is to write custom actions in C++. This allows minimal dependencies, very good debugging and advanced language constructs. There is a long "discussion" of this issue here: pros and cons of different custom action types (not great, just a dump of real-world experience). It might be worth a skim though - custom actions are the leading cause of deployment failures (link to my propaganda against them), and this brings us to the next point: the overall complexity of deployment (and how to deal with it).

The Complexity of Deployment

Deployment is the complex process of migrating heterogeneous target computers from one stable state to another