My Blahg

March 13, 2007

WiX, MSI, Windows, Microsoft, and Testing

Filed under: dotnet, Rants, WiX — treyhutcheson @ 12:44 pm

Be warned, this is a rant.

I love the concept behind WiX. I love the idea of authoring the source for an msi package, without having to use a clunky GUI, and having to pay thousands of dollars for that GUI “privilege.” But I’ve got issues with it. More specifically, I’ve got issues with the entire Windows Installer approach, and Microsoft’s “philosophical directions” in general.

Great, so now I can write xml files, and use a compiler and linker to generate an MSI. This model fits very well with tools such as NAnt and CruiseControl. Right now I’ve got a separate solution devoted to building an msi. I’ve got some c# code to act as custom NAnt tasks to cover some gaps in WiX. I’ve got an NAnt script to build the NAnt extension dll. I’ve also got a few .wxs files and fragments for the msi package. And I’ve got another NAnt script that uses the custom NAnt tasks to generate certain .wxs files on the fly, compile them, link them, and deploy the final msi.

But where do I go from there? How does one test an msi? I want a tool that can be automated to test my msi. That is a huge gap, and something I’m afraid I’ll never see Microsoft address to my satisfaction. I know some testing scenarios are not automated, but many are.

Think about it – this is an oversimplification, but an msi database is little more than a series of declarations. Those declarations should be testable, without requiring a tester to manually invoke the msi and provide inputs to the UI. Let’s say your msi placed a few files in a custom folder. I should be able to write a test case with assertions for each of those files. The test runner could decompose the msi database, and assert each condition against the declarations in the msi. Such a tool would be complicated, especially in regards to sequencing and custom actions, but I’ll take a tool that is 50% usable than no tool at all. And it’s not just about files. One could assert on xml file writes, registry changes, shortcut creations, etc. One could even write these assertions declaratively, much like authoring the MSI package itself. But, you may ask, what about dialogs and such that collect input and options from the user? Use a custom data feed to provide that information for each test case. Again, declaratively.

I don’t consider such a tool to be under the domain of WiX. After all, NUnit is not a part of the c# compiler. But I think an automated test harness, and all that goes with it, is absolutely required if WiX itself is to gain widespread adoption. Imagine – your project could have an end-to-end integration script. Every time code is checked in, CruiseControl would retrieve the code from the repository. It would then build the project with NAnt(substitute your tool here), then perform unit tests with NUnit, then move on to any other build-time processes like integration tests or metrics analysis. Finally, an msi could be generated, then the msi itself could be validated and tested. Then comes deployment.

Unfortunately, I don’t see such a tool ever being realized. It’s simply too complex, because MSI itself is too complex. MSI is too complex, because Windows itself is a nightmare(this is coming from a life-long windows guy). MSI has to support everything: shortcuts, drivers, registry changes, COM, you-name-it. Then you’ve got the fact that UI is baked into MSI. You’ve got all the rules associated with any UI, and that breeds complexity. Then you’ve got to support different packages and configuration options, the ability to repair installations, and perform rollbacks.

My point is that Windows Installer is just too damned complicated. My project must deploy the JRE, but the JRE is only available as an executable with an embedded MSI. But one cannot chain msi’s, so I had to go with a private jre deployment approach. That means that my package must include each individual physical resource of the jre itself. That means that each of those must be advertised in the msi, which means that ultimately I have to have a .wxs file somewhere that contains declarations for all 600 files, and each file’s associated guid. And I have to do the same thing with Tomcat. That’s another 832 file declarations. If I could have simply launched each component’s own installation package, it would have saved me weeks of effort.

And that leads me to my ultimate point. In my old blog, I touched on the topic only occasionally. Microsoft is bound by principles that, over time, I have come to loathe. One example is automated testing. Microsoft only supported automated testing as an afterthought. And when support was finally provided, we saw the typical “embrace and extend” philosophy. Microsoft just had to put it’s own face on testing, rather than just natively support tools such as nant and nunit. Another example is security. With Visual Studio 2003 at least, my user account had to have adminitrator privileges to debug a web application? It was the year 2003, and Microsoft still didn’t get the concept of running as a non-privileged user. Has any one ever tried running XP under a non-privileged user? You can’t defrag your drive. You can’t double click on the clock in the system tray to look at the calendar, even if you don’t want to change the system clock. You can install almost *nothing*. And the runas command only works half the time. And yet another example is Visual Studio itself. Would you like to hook into the deserialization chain for a dotnet-generated web service proxy? Tough chance. Want typed exceptions from a web service proxy? Nope. Want to get an unsafe pointer to a generic structure? Can’t.

We constantly see changes from Microsoft, usually in terms of usability. But it seems that 100% of my development over the past 3 years involves beating my head against some built-in limitation to one Microsoft framework or another, pounding out workarounds for some obscure fringe Windows condition or another, or having to special case code and configurations for remnants of a decade old platform. As an example, I get a warning when I build my msi that Windows 98 only supports something like 832 components for a package, or something like that. Well, I can ignore that because this is an xp only install. But where in the hell did the number 832 come from? Why is it a limitation for Windows 98? I predict that in 5 years, that limitation will rear its ugly head and prevent me from doing something simple, like deploying an xml file in Vista.

Sorry – this rant has turned to rambling. The theme of the post, however, should be obvious. In summary, I believe there exists a large gap somewhere after WiX, for testing. And I also believe that we will never see that gap addressed simply because automation, testing, and extensibility have never been Microsoft’s core competencies. And if Microsoft ever does consider the gap important, we’re likely to see a tool with some goofy limitation, like having to write test cases in Foxpro or something.

Blog at WordPress.com.