Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Mobile

How to create installation patches for VS.NET deployment projects

4.33/5 (16 votes)
28 Oct 20054 min read 3  
Automaticaly create Windows installer patches.

Introduction

I found myself wondering how to create patches for my application. I looked at several third-party tools like Wise and InstallShield and some freeware installers and found that they were all overkill for what I needed. My distribution needs were simple, but my projects were large. I clearly needed a way to easily create patches.

The VS.NET deployment project is very easy to use, much easier than working with the Windows Installer SDK directly. This ease of use comes at a cost; VS.NET deployment projects eliminate many of the features and flexibility of the SDK in order to simplify the build process.

After reviewing the Windows Platform SDK documentation and several examples on MSDN I came up with this automatic build process for creating a MSP patch file.

Using the code

This procedure creates patch.msp files which contain the differences between the VS.NET deployment project current Release and Debug installers and the original installers you will place in a TargetImages folder. It requires that the VS.NET deployment project build properties be set to Package files=In setup file.

  1. Install the Microsoft Platform SDK.
  2. Install Orca.Msi located at C:\Program Files\Microsoft Platform SDK\Bin\.
  3. Copy TEMPLATE.PCP located at C:\Program Files\Microsoft Platform SDK\Samples\SysMgmt\Msi\Patching\ to your deployment project folder and rename it to patch.pcp.
  4. Double click the patch.pcp file to open it in ORCA.
  5. Add a record to the ImageFamilies table and set Family to fam1.
  6. Add a record to the PatchSequence table and set PatchFamily to fam1 and Sequence to 1.0.0.
  7. In the Properties table, select the value for PatchGUID and right click it. Select paste new GUID.
  8. In the Properties table, select the value for PatchOutputPath and set its value to Patch\patch.msp.
  9. Add a record to the Properties table and set its name to MinimumRequiredMsiVersion and its value to 200.
  10. Add a record to the TargetImages table and set these values: Target=target, MsiPath=TargetImage\setup.msi, Upgraded=upgrade, Order=1, IgnoreMissingSrcFiles=0.
  11. Add a record to the UpgradedImages table and set these values: Upgraded=upgrade, MsiPath=UpgradedImage\setup.msi, Family=fam1.
  12. Create a TargetImage\Release folder in your deployment project folder and copy the installer MSI of your first release install into it.
  13. Create a TargetImage\Debug folder in your deployment project folder and copy the installer MSI of your first debug install into it. If you do not create and distribute debug installs you can skip this step.
  14. Create a new patch.cmd file in your deployment project folder and add the following commands to it:
    if "%1"=="" %0 Debug Release Done 
    
    @SETLOCAL 
    @set path=%path%;"C:\Program Files\Microsoft Platform 
                         SDK\Samples\SysMgmt\Msi\Patching"
    @set PatchTmp=C:\~VSTMP 
    
    :loop 
    if "%1"=="Done" goto end 
    
    if not exist %1\*.msi goto nopatch 
    if not exist TargetImage\%1\*.msi goto nopatch 
    
    :ok 
    rmdir /s /q %PatchTmp% 
    mkdir %PatchTmp% 
    mkdir %PatchTmp%\TargetImage 
    mkdir %PatchTmp%\UpgradedImage 
    mkdir %PatchTmp%\Patch 
    
    for %%a in (TargetImage\%1\*.msi) do copy %%a %PatchTmp%\setup.msi 
    msiexec /qb /a %PatchTmp%\setup.msi TARGETDIR=%PatchTmp%\TargetImage 
                                     /L*v %PatchTmp%\TargetImage\setup.log 
    del %PatchTmp%\setup.msi 
    
    for %%a in (%1\*.msi) do copy %%a %PatchTmp%\setup.msi 
    msiexec /qb /a %PatchTmp%\setup.msi TARGETDIR=%PatchTmp%\UpgradedImage 
                                    /L*v %PatchTmp%\UpgradedImage\setup.log 
    del %PatchTmp%\setup.msi 
    
    copy patch.pcp %PatchTmp% 
    set PatchDir=%CD% 
    chdir %PatchTmp% 
    msimsp -s patch.pcp -p Patch\patch.msp -l Patch\patch.log 
                                                   -f %PatchTmp%\Tmp -d 
    
    rmdir /s /q %PatchTmp%\TargetImage 
    rmdir /s /q %PatchTmp%\UpgradedImage 
    rmdir /s /q %PatchTmp%\Tmp 
    chdir %PatchDir% 
    
    mkdir Patch 
    mkdir Patch\%1 
    copy %PatchTmp%\Patch\*.* Patch\%1\*.* 
    rmdir /s /q %PatchTmp% 
    
    :nopatch 
    shift 
    goto loop 
    
    :end 
    pause
  15. Edit your deployment project and change the version property. This is required so that the patch compiler (msimsp.exe ) sees a different version. Important: When it asks to update the ProductCode and PackageCode, you must answer No. PackageCode is a hidden property which VS.NET automatically updates each time you build the deployment project; but, ProductCode must not be changed for the patch compiler to work. The patch compiler will refuse to create working patches of major upgrades and it determines this by the ProductCode being changed, not by the Version number.
  16. Build your deployment project. If you use both Debug and Release configurations be sure to build both of them. The fact that the UpgradeCode and ProductCode have not changed, and the hidden PackageCode has changed will indicate to patch compiler that the updated version is a minor update instead of a major upgrade.
  17. Run the patch.cmd batch program. This process can take several minutes to complete depending upon the size and complexity of your original deployment projects. The patch compiler will compare each file in both setup projects to determine which files have changed and either create a delta between the files, or include the whole file if there are too many changes. Be sure to check the patch.log files to see what files were included in your patch and to be sure everything compiled correctly with no errors.

Points of interest

If you use configurations with names other than Release and Debug, you will need to modify line 1 of the patch.cmd file to name the configurations you use, but make sure Done is specified as the last word on that line so that the command will exit properly.

You can specify different locations for your msimsp.exe file and the temporary folder to use by editing the set commands at the beginning of the batch program. Note that the PatchTmp variable specifies a folder which will be totally created and totally deleted by this batch program, so don't specify a temp folder needed by Windows or any other program. I also recommend specifying a temporary location with as short a name as possible. I have had problems running msimsp in folders with very long full path names.

History

  • August 20th, 2005 - Initial version.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here