Yes WiX, I really DO want to do that…

Consider this MSI fragment( created in Orca and transformed to XML by MSI2XML ):

<table name=”InstallUISequence”>
<col key=”yes” def=”s72″>Action</col>
<col def=”S255″>Condition</col>
<col def=”I2″>Sequence</col>
<row>
<td>Dialog1</td>
<td/>
<td>1</td>
</row>
</table>

It’s not a real installer, it’s a `fake` MSI that was created just for fun and just to show what Windows Installer is capable of doing once you free yourself from coloring between the lines.

Now MSI2XML can easily round trip the table data without passing a whole lot of judgement. Just for fun I thought I’d see what it’s like in WiX to do this. I take the XML and reconstitute the MSI and then use Dark to create a wxs project. Now WiX takes lot’s and lot’s of issues with the source even though it is a perfectly formed MSI database that will actually do what it was intended to do. Let’s ignore most of this for a moment and talk about the Sequence tables.

In my XML you’ll notice that only the InstallUISequence table is defined and it’s pretty sparse….. it only contains a single action, a call to a UI Interface Wizard called Dialog1 (yes, unique name I know…)

Now note the XML that dark creates to represent this:

<InstallUISequence>
<Show Dialog=”Dialog1″ Sequence=”1″ />
</InstallUISequence>

This snippet sounds like what I describe, right…. a single sequence with a single action. But that’s not what candle/light does with it. It automatically goes and creates:

AdminExecuteSequence ( 8 actions )
AdminUISequence ( 4 actions )
AdvtExecuteSequence ( 7 actions )
InstallUISequence ( 6 actions instead of 1 )
InstallExecuteSequence( 13 actions )
In order to get a successfully round trip’d resultant MSI ( pedantic error checks for the time being ) the XML actually needs to look like:

<AdminUISequence>
<CostInitialize Suppress=”yes”/>
<FileCost Suppress=”yes”/>
<CostFinalize Suppress=”yes”/>
<ExecuteAction Suppress=”yes”/>
</AdminUISequence>
<AdminExecuteSequence >
<CostInitialize Suppress=”yes”/>
<FileCost Suppress=”yes”/>
<CostFinalize Suppress=”yes”/>
<InstallValidate Suppress=”yes”/>
<InstallInitialize Suppress=”yes”/>
<InstallAdminPackage Suppress=”yes”/>
<InstallFiles Suppress=”yes”/>
<InstallFinalize Suppress=”yes”/>
</AdminExecuteSequence>
<AdvertiseExecuteSequence>
<CostInitialize Suppress=”yes”/>
<CostFinalize Suppress=”yes”/>
<InstallValidate Suppress=”yes”/>
<InstallInitialize Suppress=”yes”/>
<PublishFeatures Suppress=”yes”/>
<PublishProduct Suppress=”yes”/>
<InstallFinalize Suppress=”yes”/>
</AdvertiseExecuteSequence>
<InstallUISequence>
<CostInitialize Suppress=”yes”/>
<FileCost Suppress=”yes”/>
<CostFinalize Suppress=”yes”/>
<ValidateProductID Suppress=”yes”/>
<ExecuteAction Suppress=”yes”/>
<Show Dialog=”Dialog1″ Sequence=”1″/>
</InstallUISequence>
<InstallExecuteSequence>
<CostInitialize Suppress=”yes”/>
<FileCost Suppress=”yes”/>
<CostFinalize Suppress=”yes”/>
<ValidateProductID Suppress=”yes”/>
<InstallValidate Suppress=”yes”/>
<InstallInitialize Suppress=”yes”/>
<InstallFinalize Suppress=”yes”/>
<PublishFeatures Suppress=”yes”/>
<PublishProduct Suppress=”yes”/>
<ProcessComponents Suppress=”yes”/>
<UnpublishFeatures Suppress=”yes”/>
<RegisterUser Suppress=”yes”/>
<RegisterProduct Suppress=”yes”/>
</InstallExecuteSequence>

Now I can understand that for a real MSI would want all of those actions/sequences by default, and I also understand that some pople are going to want to quickly dismiss this use case as `fake` and `invalid`, but consider this prospective:

Shouldn’t a successful decompiler/compiler story result in the creation of a binary that is identical ( or as close as possible ) to the original binary? To me it seems like Dark should respect ( and warn of course ) that this was the original configuration of the database and author XML to represent it. Instead dark seems to try to read between the tea leaves and say `well I know this is what you are, but I really think you should be this…`.

In the past I’ve worked on some pretty big, complex installer frameworks that delivered dozens of installers by consuming dozens of product assests in different configurations with different brandings. The frameworks are so big and so active that it’s not practical to just dump it all at once and replace it with an entirely different system. You have to refactor individual layers and components while maintaining the existing contracts. While doing this refactoring I’ve attempted to incorporate WiX in my solutions, but unfortunatly it’s been issues like what I just described that have forced me to use other tools like MSI2XML which are much more respectful of what I’m trying to accomplish.