Our TestClass from the dll has two constructors: default constructor sets the value of the greeting varibale to it's default value, but users are free to use the second constructor to set the greeting message to whatever they like.
Console application is using the default constructor, so the message we will see on the screen is the default message of the TestClass class.
Here are the values for properties related to upgrade.
Here I have localized values for installation package properties.
WiX source code for the installer for original version of our product
<?xml version='1.0' encoding='windows-1252'?>
<Wix xmlns='http://schemas.microsoft.com/wix/2003/01/wi'>
<?define SkuName = "TestApp"?>
<!-- Path variables -->
<?define APPROOT = "D:\MyLearning\WiX\Patching"?>
<?define PROJECT = "$(var.APPROOT)\Project\TestApp\TestApp\bin\Debug"?>
<?include ..\Include\UpgradeData.wxi ?>
<Product Id='$(var.ProductCode)'
Name='$(loc.ProductName)'
Language='$(loc.LangId)'
Version='$(var.ProductVersion)'
Codepage='1252'
Manufacturer='$(var.Manufacturer)'
UpgradeCode='$(var.UpgradeCode)'>
<Package Id='$(var.PackageCode)'
Description="$(loc.PackageDescription)"
Comments='$(loc.Comments)'
Manufacturer='$(var.Manufacturer)'
InstallerVersion='200'
Languages='$(loc.LangId)'
SummaryCodepage='$(loc.Codepage)'
Compressed='no'
AdminImage='no'
Platforms='Intel'
ReadOnly='yes'
ShortNames='no'
Keywords='Installer,MSI,Database' />
<?include ..\Include\Definitions.wxi ?>
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='LocalAppDataFolder'>
<Directory Id='INSTALLDIR' Name='TestApp'>
<Component Id='$(var.SkuName)' Guid='{835A4136-B01E-4F8B-8EA7-5D6F69B07A83}'>
<File Id='TestAppExe' DiskId='1' KeyPath='yes' Checksum='yes' Vital='yes'
Name='TestApp.exe'
Assembly='.net' AssemblyManifest='TestAppExe' AssemblyApplication='TestAppExe'
Source='$(var.PROJECT)\TestApp.exe' />
</Component>
<Component Id='TestLibDll_Component' Guid='{5BC55186-170E-475C-B77A-D80581FC88EC}'>
<File Id='TestLibDll' Name='TestLib.dll' DiskId='1' KeyPath='yes' Vital='yes'
Assembly='.net' AssemblyManifest='TestLibDll' AssemblyApplication='TestLibDll'
Source='$(var.PROJECT)\TestLib.dll' />
</Component>
</Directory>
</Directory>
</Directory>
<Feature Id='Complete' Level='1'>
<ComponentRef Id='$(var.SkuName)' />
<ComponentRef Id='TestLibDll_Component' />
</Feature>
</Product>
</Wix>
There is nothing special in here except one attribute:
<Package Id='$(var.PackageCode)' ... Compressed='no' ...
In order to create a patch we must have uncompressed source. One way of getting it is to create an administartive install and create a patch out of an administrative image. For this sample I am setting the Compressed attribute to no, which means that by default, none of the files will be embedded into the installer database. That can be overridden on the file by file basis by adding Compressed attribute to the File element, but I am not going to do that in this sample.
Here are commands to build the installer database:
d:\Wix\candle.exe RTM.wxs
d:\Wix\light.exe -out TestApp.msi RTM.wixobj -loc ..\Include\en-us.wxl
Updated application source code (QFE)
Program.cs:
using System;
using System.Collections.Generic;
using System.Text;
using TestLib;
namespace TestApp
{
class Program
{
static void Main(string[] args)
{
TestClass test = new TestClass("QFE version");
test.WriteLine();
}
}
}
Notice that now I am using non-default constructor providing my custom greetings message.
AssemblyInfo.cs:
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("TestApp")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("TestApp")]
[assembly: AssemblyCopyright("Copyright © 2008")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("10578ea5-d18c-41b1-bbf6-ccc9d4d695f2")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("1.0.1.0")]
[assembly: AssemblyFileVersion("1.0.1.0")]
Notice that both AssemblyVersion and AssemblyFileVersion attributes have changed their values from "1.0.0.0" to "1.0.1.0".
Thare are no changes in the dll source code.
WiX source code for the installer for updated version of our product
There are no changes to the original WiX source code except this one:
<?define PROJECT = "$(var.APPROOT)\Project\TestApp2\TestApp\bin\Debug"?>
That changes the path to the updated version.
Because this is a small update, the only property we need to change is the Revision Number Summary property (or, PackageCode, or, in WiX, the Id attribute of the Package element).
Now we have both original (RTM) and updated (QFE) versions of installer databases built. It is time to create a patch creation script.
Patch creation script (Patch.wxs)
Here is the source of Patch.wxs. This file is located in the Patch folder.
<?xml version='1.0' encoding='windows-1252'?>
<Wix xmlns='http://schemas.microsoft.com/wix/2003/01/wi'>
<?define SkuName = "TestApp"?>
<!-- Path variables -->
<?define APPROOT = "D:\MyLearning\WiX\Patching\SmallUpdate"?>
<?define RTM = "$(var.APPROOT)\RTM"?>
<?define QFE = "$(var.APPROOT)\QFE"?>
<?include ..\Include\UpgradeData.wxi ?>
<PatchCreation Id='{F8D2A922-EFE7-4BBF-8942-73A487453C2F}'
AllowMajorVersionMismatches='no'
AllowProductCodeMismatches='no'
CleanWorkingFolder='no'
WholeFilesOnly='no'
Codepage='1252' >
<PatchInformation Description="TestApp 1.0.0 Patch"
Keywords='Installer'
Comments='testApp comments'
Manufacturer='$(var.Manufacturer)'
Languages='1033'
Compressed='yes'
SummaryCodepage='1252' />
<PatchMetadata Description="TestApp 1.0.0 Patch"
DisplayName='TestApp 1.0.0 Patch'
TargetProductName='TestApp 1.0.0'
ManufacturerName='$(var.Manufacturer)'
MoreInfoURL='www.acme.com'
Classification='Hotfix'
AllowRemoval='yes' />
<Family Name='Patch101' DiskId='2' MediaSrcProp='PatchSrcPropName' SequenceStart='1000'>
<UpgradeImage Id='PatchQFE' SourceFile='$(var.QFE)\TestApp.msi'>
<TargetImage Id='PatchRTM' Order='1' IgnoreMissingFiles='no' SourceFile='$(var.RTM)\TestApp.msi' />
</UpgradeImage>
</Family>
<TargetProductCode Id='$(var.ProductCode)' />
</PatchCreation>
</Wix>
Use the following commands to build the Patch.msp:
d:\wix\candle.exe Patch.wxs
d:\wix\light.exe Patch.wixobj
Msimsp.exe -s Patch.pcp -p Patch.msp -l Patch.log
Now, install the original version of the product. Run the installed application. On my computer it is installed in C:\Users\alexshev\AppData\Local\TestApp folder. You should see the "Hello, World!" mesage.
Install the patch by running this command from the Patch folder:
msiexec /p Patch.msp REINSTALL=ALL REINSTALLMODE=omus
Run TestApp.exe again. This time it should print "QFE version" message.
Open Add/Remove Programs in the Control Panel applet. Turn on the view of the installed updates for the installed products. Find the TestApp application in the list of installed applications. You should see one update named "TestApp 1.0.0 Patch". Right-click on it and select "Uninstall". Continue with uninstallation. Run TestApp.exe again. You will see "Hello, World!" message again.