Friday, June 29, 2007

WiX: Building a Patch using the new Patch Building System - Part 3

This example is aimed at demonstrating the workflow and command lines required to build a patch using the Patch element and Pyro.exe. I would appreciate any feedback anyone has.

Setting up the Sample:

1. Create a Directory that you plan on running the sample from. I will call this directory the sample root

2. Under the sample root directory create two subdirectories called "1.0" and "1.1"

3. Create a text file in the 1.0 directory called Sample.txt and put some text in it telling you that it is the 1.0 version of the file.

4. Create a text file in the 1.1 directory called Sample.txt and put some text in it telling you that it is the 1.1 version of the file.

You should now have 2 sub-directories under your sample root called 1.0 and 1.1 each containing a Sample.txt file whose contents state which version it is.

5. Create your product authoring in the sample root folder called Product.wxs with the following contents:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Id="48C49ACE-90CF-4161-9C6E-9162115A54DD" Name="WiX Patch Example Product" Language="1033" Version="1.0.0" Manufacturer="Dynamo Corporation" UpgradeCode="48C49ACE-90CF-4161-9C6E-9162115A54DD">
        <Package Description="Installs a file that will be patched." Comments="This Product does not install any executables" InstallerVersion="200" Compressed="yes" />
        <Media Id="1" Cabinet="product.cab" EmbedCab="yes" />
        <FeatureRef Id="SampleProductFeature"/>
    </Product>
    <Fragment>
        <Feature Id="SampleProductFeature" Title="Sample Product Feature" Level="1">
            <ComponentRef Id="SampleComponent" />
        </Feature>
    </Fragment>
    <Fragment>
        <DirectoryRef Id="SampleProductFolder">
            <Component Id="SampleComponent" Guid="{C28843DA-EF08-41CC-BA75-D2B99D8A1983}" DiskId="1">
                <File Id="SampleFile" Name="Sample.txt" Source=".\$(var.Version)\Sample.txt" />
            </Component>
        </DirectoryRef>
    </Fragment>
    <Fragment>
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder" Name="PFiles">
                <Directory Id="SampleProductFolder" Name="Patch Sample Directory">
                </Directory>
            </Directory>
        </Directory>
    </Fragment>
</Wix>

6. Create your patch authoring in the sample root called Patch.wxs with the following contents:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Patch
        AllowRemoval="yes"
        Manufacturer="Dynamo Corp"
        MoreInfoURL="http://www.dynamocorp.com/"
        DisplayName="Sample Patch"
        Description="Small Update Patch"
        Classification="Update"
        >
       
        <Media Id="5000" Cabinet="RTM.cab">
            <PatchBaseline Id="RTM"/>
        </Media>
        <PatchFamilyRef Id="SamplePatchFamily"/>
    </Patch>
    <Fragment>   
        <PatchFamily Id='SamplePatchFamily' Version='1.0.0' Supersede='yes'>
            <ComponentRef Id="SampleComponent"/>
        </PatchFamily>
    </Fragment>
</Wix>

You should now have a Product.wxs and Patch.wxs file in the sample root.

Instructions for building a Patch using the sample:
Open a command prompt where you normally run the WiX tools from.
Required WiX executables:
Candle.exe
Light.exe
Torch.exe
Pyro.exe
Your WiX toolset version should be at least 3.0.3001.0

1. Build Target Layout:
> candle.exe -dVersion=1.0 product.wxs
> light.exe -sval Product.wixobj -out 1.0\Product.msi

2. Build the Upgrade Layout:
> candle.exe -dVersion=1.1 product.wxs
> light.exe -sval Product.wixobj -out 1.1\Product.msi

3. Create the transform between your products:
> torch.exe -p -xi 1.0\Product.wixpdb 1.1\Product.wixpdb -out Patch\Diff.Wixmst

4. Build the Patch:
> candle.exe Patch.wxs
> light.exe Patch.wixobj -out Patch\Patch.WixMsp
> pyro.exe Patch\Patch.WixMsp -out Patch\Patch.msp -t RTM Patch\Diff.wixmst

I am currently working on reducing the number of command line switches required for building a simple patch. Sometime soon I hope to have the commands somewhat simplified by making the defaults match up with the patch building system.

Verifying what you have done here works: 
1. Install the 1.0 Product by running 1.0\Product.msi
2. Go to "Program Files\Patch Sample Directory" and open up Sample.txt. You should see that it is the 1.0 version.
3. Close Sample.txt.
3. Install the Patch from the sample root Patch\Patch.msp.
4. Repeat step 2 and notice that Sample.txt now contains the new 1.1 content.
5. Go to Add/Remove Programs and make sure "Show Updates" is checked.
6. Uninstall the Patch and repeat step 2 to see that the file was rolled back to its original version.
7. Uninstall the Product itself to clean off your system.

This was originally posted here and may have additional comments.

Sunday, June 17, 2007

WiX: Building a Patch using the new Patch Building System - Part 2

I dont have much time today to write but I wanted to take a chance to answer a few questions that I've been asked a lot recently.
 
What is Pyro?
Pyro is the new tool in the WiX toolset that will pull together your patch authoring and your product transforms in order to build you an msp.

What is the new system and what is the old?
It is important to distinguish the new patch building system from the previous one provided by WiX. There has been some confusion and I want to try and clear it up. 

The Previous Way:
The PatchCreation element has been supported in WiX for a while to help people build patches. It essentially helps users build a pcp file which is then used as input to the PatchWiz tools. The PatchCreation element is not used in the new patch building system.

The New Way:The Patch Element is a newly added element that lets you describe the contents of your patch. It contains information about where the files your patch contains should be stored as well as summary information that describes your patch to your end user. It also supplies a mechanism to filter out specific changes to be included in your patch. When this element is passed to candle to be compiled and the resulting wixobj's are passed to light to link, the result is a WixMsp. This is an xml representation of the patch database (msp).

What Next?
The next thing I'd like to do is to provide a simple example of how to build a patch using Pyro.exe. I plan on getting this started in the next few days. Keep bugging me if I dont to remind me to do it and feel free to ask me more questions as this new functionality isn't all that well documented yet.

Friday, June 8, 2007

WiX: What is a WiX Extension?

A WiX extension is a dll that allows users to add their own custom elements, preprocessor functionality, and build customizations. These extensions take advantage of the various extension points in WiX. The most commonly used ones are Preprocessor, Compiler, and Binder extentions.

Mosts WiX extensions shipped with the WiX toolset are used to encapsulate common funtionality and make it easy for users to author things into their setups. They are targeted at solving setup problems in a standard way so everyone can benefit from and build on the WiX toolset.

Example: WixNetFxExtension.dll

Many people who write applications for the .NET Framework have various needs. I will discuss 2 here in an effort to describe 2 uses of extensions.

AppSearch (ComponentSearch, RegistrySearch, etc..):

Sometimes people want to find information about the system as part of their install. One way to get current system info is using an AppSearch.

Detecting if the .NET Framework is installed:

In reality, in order to detect if the .NET framework is installed, you need to search for a specific registry key and set a property if that key exists. Using the WixNetFxExtension you can just add the following to detect if the 2.0 Framework is installed.

<PropertyRef Id="NETFRAMEWORK20"/>

 The logic defining this property and all the logic behind it is stored in a WixLib which embedded inside the WixNetFxExtension.dll

Custom Actions:

Sometimes people want to do things that are not supported by Windows Installer. In this case they write custom actions. WiX provides a good mechanism for sharing custom actions.

Ngen’ing an Assembly:

To add a custom action to a product there is a lot of authoring to do. You need to define it and its binary, schedule it, and condition it. This doesn’t even consider that most custom actions come in sets, all sequenced at different times. This can all be done using a CustomActionRef in a similar way as the previous example.

After that, you need to populate any custom tables your custom action may rely on for its data. This is a lot complexity for users to author using standard WiX constructs. One use of a compiler extension can be to add your own element to the authoring and have that translate into a custom table in your msi that your customaction can read. The ngen custom actions have such an element.

<netfx:NativeImage Platform=”all” … />

The compiler will take this line and its context and populate a NativeImage table in the resulting MSI that will contain all the data needed by the ngen custom actions. The custom action also requires a dll binary in the binary table. In WiX v2 you had to ship your binary along with your extension. WiX v3 has support for binary WixLib’s. The key thing here is that the binary will get added into the WixLib for you and you don’t have to worry about shipping 2 separate files.

The resulting extension file:

The result of this is a .NET dll with a WixLib embedded in it as a resource. That WixLib then in turn has a cabinet at the beginning of it that contains the custom action binary. All of this nesting is handled for you by the linker and the binder so all you have to do to use stuff you put in your WixLib is add the extension to your candle and light command lines and reference the things defined in the WixLib from your product authoring.