Adventures of a Setup Developer

my musings about setups and other things in my life

  Home  |   Contact  |   Syndication    |   Login
  30 Posts | 1 Stories | 11 Comments | 105 Trackbacks

News

Article Categories

Archives

Post Categories

General

Regular Reads

Tools

When I talk to my fellow developers and other installation developers about the WIX Toolset, they do not fully understand the implications of the WIX Toolset in its own right but map its features to their favorite installation development tools. The WIX Toolset mostly ensures that you follow the best practices while authoring packages. The biggest advantage of the WIX Toolset over other applications is the support for distributed development. I have raved and ranted about this in my previous blog entries but I would substantiate it with actual WXS code this time. For starters, WXS file is an XML file that has to follow the schema as specified in the wix.xsd file in the 'doc' folder of your distribution. Rob has an excellent demo on distributed development with the WIX toolset. But the quality of video is very poor and the sample files are not yet available for us to tweak around with. So I have come up with my own example.

Let us assume the following scenario. There are group of installation and application developers in the organization working on a setup project. Let us allocate roles (purely hypothetical. I am not a manager <grin/>) for our convenience. Let us assume that the application developers take care of maintaining a catalog of components and resources that go into the product. The second developer takes care of assigning the appropriate components into the respective merge modules or features in a product. Let another developer be responsible for creating UIs. Additionally, each application developer creates his own fragments of files by hand or by using a simple tool. Let us assume that we have to package three files.

  1. Notepad.exe
  2. ReadMe.txt
  3. Calc.exe

Notepad.exe and Readme.txt are a logical unit and hence we would put them in a single component called Notepad.exe and set Notepad.exe as the key file of the component. We would also have Readme.txt as a companion file for Notepad.exe such that the versioning logic of Readme.txt is controlled by the versioning logic of Notepad.exe. Calc.exe is a standalone application that does not have anyother files. So here we go. The application developer codes his file named Dev1.wxs. Pretty simple isn't it?

<!--Dev1.wxs-->
<Wix xmlns="http://schemas.microsoft.com/wix/2003/01/wi">
  <Fragment>
    <DirectoryRef Id="INSTALLDIR">
      <Component Id="Notepad.exe" Guid="12CC008F-89A6-422d-868B-B066606FFD99" DiskId="1">
        <File Id="Notepad.exe" Name="Notepad.exe" LongName="Notepad.exe" KeyPath="yes" src="$(env.BUILDPATH)\Notepad.exe">
            <Shortcut Id="LaunchNotepad" Advertise="no" Description="Launches Notepad" Directory="DesktopFolder" Name="Notepad" LongName="Launch Notepad" WorkingDirectory="INSTALLDIR" Icon="Notepad.ico"/>
        </File>
        <File Id="Readme.txt" Name="Readme.txt" LongName="Readme.txt" CompanionFile="Notepad.exe" src="$(env.BUILDPATH)\Readme.txt"/>
      </Component>
    </DirectoryRef>
    <Icon Id="Notepad.ico" src="$(env.BUILDPATH)\Notepad.ico"/>
 
</Fragment>
</Wix>

Now the second application developer creates his file dev2.wxs.

 

<!--Dev2.wxs-->
<
Wix xmlns="http://schemas.microsoft.com/wix/2003/01/wi">
  <Fragment>
    <DirectoryRef Id="INSTALLDIR">
      <Component Id="Calc.exe" Guid="2C5ECB67-E585-4301-BAF4-5380FE6C26AB" DiskId="1">
        <File Id="Calc.exe" Name="Calc.exe" LongName="Calc.exe" KeyPath="yes" src="$(env.BUILDPATH)\Calc.exe"/>
      </Component>
    </DirectoryRef>
  </Fragment>
</Wix>

By now, the UI guy would have created a new WXS file for UI or stole the UI from a premade package. I normally steal UI from premade(I just coined this word) packages like Orca or some UI generated by freeware installers. Writing UI code for MSI using the WIX toolset is not exactly a pleasurable experience. <sigh/> So here goes the UI file. I am not going to include the WXS file here but if you need it, you can send me an email at vagmi.mudumbai@gmail.com. Now we have a file called dialogs.wxs which just has a bunch of dialogs, binaries, error texts, UITexts and properties defined for the UI.

Now we have to piece together each of these files and link them to our product. This is the MyProduct.wxs file which contains the feature-component mapping and the rest of the installation logic.

<!--MyProduct.wxs-->
<
Wix xmlns="http://schemas.microsoft.com/wix/2003/01/wi">
  <Product Id="148E08FF-D7C4-46ed-8D4D-601C67FE0AFD" Language="1033" Name="MyProduct" Version="1.0.0" UpgradeCode="B7FE793A-800D-4c14-8CB4-B00AA84FF685" Manufacturer="Vagmi">
    <Package Id="D1192FCD-BA01-4d8f-BA7B-663CE9934BDE" Compressed="yes" Description="My WIX Installation" InstallerVersion="200" Languages="1033" Manufacturer="Vagmi"/>
    <Media Cabinet="Data.cab" EmbedCab="yes" Id="1"/>
    <Directory Id="TARGETDIR" Name="SourceDir">
        <Directory Id="ProgramFilesFolder" Name="PFiles">
            <Directory Id="INSTALLDIR" Name="Vagmi"/>
        </Directory>
        <Directory Id="DesktopFolder" Name="DTFOLDER"/>
    </Directory>
    <UI>
        <InstallUISequence>
            <Show Dialog="SetupCompleteError" OnExit="error" />
            <Show Dialog="SetupInterrupted" OnExit="cancel" />
            <Show Dialog="SetupCompleteSuccess" OnExit="success" />
            <Show Dialog="SetupInitialization" After="LaunchConditions" />
            <ResolveSource Before="CostFinalize"><![CDATA[Not Installed And Not PATCH]]></ResolveSource>
            <Show Dialog="InstallWelcome" After="MigrateFeatureStates"><![CDATA[Not Installed And (Not PATCH Or IS_MAJOR_UPGRADE)]]></Show>
            <Show Dialog="SetupResume" After="InstallWelcome"><![CDATA[Installed And (RESUME Or Preselected) And Not PATCH]]></Show>
            <Show Dialog="MaintenanceWelcome" After="SetupResume"><![CDATA[Installed And Not RESUME And Not Preselected And Not PATCH]]></Show>
            <Show Dialog="SetupProgress" After="MaintenanceWelcome" />
        </InstallUISequence>
    </UI>
    <Feature Id="TheOnlyFeature" ConfigurableDirectory="INSTALLDIR" Level="1" Title="TheOnlyFeature" Description="TheOnlyFeature">
        <ComponentRef Id="Notepad.exe"/>
        <ComponentRef Id="Calc.exe"/>
    </Feature>
  </Product>
</Wix>

As you can clearly see, the complex job of creating an installer package is split among the developers. This is a great feature as it does away with Merge Modules and all the associated hassles with modularization. Further changes or corrections can be made independently without affecting other parts of the installation. The only part that needs automation is the generation of WXS fragments for the developers. Although it is a simple piece of code to write, we cannot expect all developers to be conversant with XML and learn the WIX toolset. All we need is for them to specify the files and the destinations in a tool and a tool that should generate minimal WXS code for these fragments. I do not think that should be a problem considering the level of automation installation and build teams adopt for other tasks.

Building these is a straight forward task.

  • Compile the files using the following command.
    candle dev1.wxs dev2.wxs dialogs.wxs myproduct.wxs

    This would produce dev1.wixobj, dev2.wixobj, dialogs.wixobj and myproduct.wixobj
  • You can then link the generated object files using light.
    light -out build/product.msi dev1.wixobj dev2.wixobj dialogs.wixobj myproduct.wixobj

The myproduct.msi file would be generated in a folder named 'build' under the current directory.

posted on Tuesday, November 23, 2004 7:03 PM

Feedback

# re: Using the WIX Toolset for Distributed Development 1/4/2005 10:39 AM Christopher Painter
Neat concept, but I can't wonder if its a solution to a problem that doesn't exist. My concern is where do you find multiple developers on a large project that even care about authoring installs let alone understand setup best practices? I've found that it often works best to have a setup expert be responsible for the overall setup project and give him authority to direct the developers on matters of intergration.


# re: Using the WIX Toolset for Distributed Development 4/13/2005 8:45 PM owen Corpening
I find the problem to be reusability of the stuff: say you have a dislog, the simplest case being the welcome panel. Lots of work went into it, the sizing, artwork, fonts, layout, etc.

You want to have all the companies' setups use it. How to accomplish this? Cut paste? What about when it is updated?

I wish dialogs could be saved to .wxi files with parameters like methods for events, then the <?include MyCompanyWelcomeDialog.wxi ?> statement could have the parameters like:

<?include MyCompanyWelcomeDialog.wxi NextDialog="LicenseDlg" ?>

Then those setups not requiring a license would be able to have:

<?include MyCompanyWelcomeDialog.wxi NextDialog="UserReg" ?>

# Unit Testing MSI Packages... Maybe 8/30/2005 9:19 PM vagmi's personal blog
I was recently reading the article by Marting Fowler on Continuous Integration. Our team has set process to have daily builds of the MSI package along with the binary builds. It would have been an easier task with the WIX Toolset but most of our code stil

# Breeds of Setup Engineers 8/30/2005 9:27 PM vagmi's personal blog
A little earlier, Chris had put this comment on my blog about Using The WIX Toolset for Distributed Development.Firstly, I believe that Chris and I belong to different breeds of setup engineers. Chris uses tools like AdminStudio, DevStudio and Repackager

# re: Using the WIX Toolset for Distributed Development 8/18/2006 9:44 PM BlogPolice
Christopher Painter is a BLOG-nuisance.

Get a LIFE you GOON..........

# re: Using the WIX Toolset for Distributed Development 12/21/2006 9:25 AM Nick West
Owen Corpening:

Until I came across setup utilities such as WIX, I did not know that languages even existed where each function/method/dialog specified the function/method/dialog that was to be called next. I find this quite unbelievable. Imagine if every method in my C# program had to specify, in the last statement, the name of the method to be called next. The language would be unusable. Yet this is exactly what WIX does! Of course you should be able to write his custom dialog box without needing to have a separate version for every possible pair of dialogs that can occur before and after it in the sequence.

Setup utilities are so backwards that we don't use them. We now write .NET programs in C# to install our software. It is so much easier to put together a .NET form than to mess with WIX custom dialogs.

# re: Using the WIX Toolset for Distributed Development 1/16/2007 10:34 AM The Setup Kid
Wix rules, however I understand the pain about the dialog coding. So, we moved to external UI authored in C# in which we created an OO based dialog framework. In the framework we coded all the common dialogs we could think of (welcome, EULA, country selection, SQL connection information, etc...) with base functionality that is easily extended. Authoring of a UI for an install to us now means grabing a common dialog, set various properties if needed (product specific wording, etc...), then adding it to a dialog sequence. All dialogs are based off of one dialog, so if one needs a 'custom dialog'...derive from the base dialog, whip up the new dialog, add it to the sequence and move on. All the back, next, cancel, window positioning, etc... logic is handled automatically. We've got support for maintenance mode, injecting additional dialogs into the sequence during runtime, etc..., etc...

We're also using managed custom actions in which we've developed a rather extensive library of common installation routines. Using OO we've been able to define a consistent bahavior for all custom actions within an installation (again, all CA's derived from a single CA) so that creating of a CA involves only focusing on the 'business logic' of the action. No more messy stuff of checking session run modes within deferred custom actions, etc... all that has been moved to shared logic and dealt with automajically. We've even gone so far as to use generics such that a given setup author can author their custom action code in a single line of code.

i.e. VerifySPService : VerifyService<SP> {}

My point here is, that Wix is an awesome tool for generating setups that leverage windows installer. Yes, the UI authoring is rather cumbersome, but you don't have to use it for that. Nor does one have to go to the other extreme and write the entire setup app in .NET and throw away WiX and the benefits that properly authored windows installer based installs bring to your customer.


Back to the subject of Wix Framents...

If you've ever split your installation file payload into merge modules just to help break apart / modularize your setup, then had to patch your installation and add a file to that merge module, you would very soon recognize that maybe you should have used fragments.

Fragments are great for splitting up file payload (or heck, even Wix include files for that matter). But IMO using them for Dialogs is taking it a step too far...

# how do we create an xml as to give options to pick different items from a list 3/13/2007 2:11 PM archana
hi
i am doing a project using WIX where i am suppose to create a installation package where there are multiple msi and the user must be able to select a few msi s from the list and the install the one which are selected

# re: Using the WIX Toolset for Distributed Development 8/24/2007 1:16 AM John McFadyen
In reference to a very old post by C Painter. I am currently on a huge distribution with thousands of files being updated each day.

I completely understand what your saying about finding a dev who knows how to write MSI installers. Often they have no comprehension of this at all (not to say that couldnt do its just out of scope for most)

Anyway back to the post, the current site has globally dispersed teams all developing for a single application. Each app component is written in different states / locations and then all compiled at a single site.

As such using the mulitple wxs file system vagmi has detailed it essential for us. Not down to the degree of 1 file per dev but more so hundreds of files per group of devs.

all this is then constructed by a single MSI dev who incorporates all other devs info using the method outlined here.

As for Archana WiX cannot do what you ask, unless each MSI you are referring to is setup as a feature of a single msi or each of the MSI's is nested inside a parent MSI which is quite untidy particularly due to the product code inheritance that happens when nesting.

You may be better off with a custom solution or split the msi's into features of a single msi.

John


# re: Using the WIX Toolset for Distributed Development 8/22/2008 8:01 AM Andy
Not only can this be used for Distributed Development but it should be possible to reuse fragments in different projects.

Post Feedback

Title:
Name:
Email: (never displayed)
Url:
Comments: 
Please add 6 and 2 and type the answer here: