To create Windows Installer packages, WiX is used in a project I work on. And one day I needed to create a patch for an existing install package.
I started searching how it can be done. The first thing that Google found was this instruction. It suited my needs, more or less. Yet I didn’t manage to create the patch following this instruction. I overcame several obstacles, and then I faced another problem on the last step of the process: the tools didn’t see any modifications between the two different installations. Later I found out why the tools see no modifications. It proved that our packages didn’t store the sizes of files.
The instruction I talked above was written for version 2.0 of WiX. However version 3.0 is already used. It took me some time until I found the updated instructions on the WiX site. There are two of them:
- Creating patches using only WiX tools (since version 3.0);
- Using Patch Creation Properties (the way similar to version 2.0).
There was an issue with both ways: either instruction assumed there’s original .wsx file of the install package. I didn’t have one. After trying various approaches, including install package decompilation, I still didn’t manage to create patch. I even downloaded a fresh WiX build, but it didn’t help either.
Then I decided to start it all over and to begin with checking the instruction itself. I created a small package and an updated package. And I managed to create the patch between these two.
When I searched for solutions, I came across a post “Patching something you didn’t build with WiX using WiX”. It describes the procedure of creating patch from .msi files. That’s what I needed. Yet there were no details. The post stated that the command lines are the same as in “Building a Patch using the new Patch Building System – Part 3” post. But the instructions there simply repeat what’s written in the WiX documentation.
I used administrative install and option -ax instead of -xi, as it was described. And torch.exe failed with the same error as in the second comment: torch.exe : error TRCH0001 : The Windows Installer service failed to start. Contact your support personnel.
After I re-read all the comments carefully, I found a hint in the seventh comment: option -xo. This hint helped to create the patch.
Detailed Instruction
This instruction assumes you work in C:\patch.
-
Perform administrative install:
msiexec /a install.msi /qb TARGET=C:\patch\rtm
-
Copy the image:
xcopy /i rtm upp
-
Using Orca, change the package code in the updated install image:
- On the File menu, click Open.
- In the Open dialog, type C:\patch\upp\install.msi and click Open.
- On the View menu, click Summary Information.
- Find Package code field and click New GUID to the right of it. The package code will be updated. Click OK.
- On the File menu, click Save to save the package.
The Orca editor is part of Windows SDK.
- Update the files under C:\patch\upp with the new versions.
-
Evaluate the differences between the two packages:
torch -p -ax C:\patch\temp -xo rtm\install.msi upp\install.msi -out patch\diff.wixmst
-
Create patch description file patch.wsx. You can take it from Create your patch authoring in the sample root section of the WiX instructions.
I created my own based on it.
<?xml version="1.0" encoding="UTF-8"?> <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> <Patch AllowRemoval="yes" Manufacturer="Organization" DisplayName="Patch name" Description="Patch description" Comments="Patch comment" Classification="Update" Codepage="1251" > <Media Id="5000" Cabinet="ProductP.cab"> <PatchBaseline Id="RTM"/> </Media> </Patch> </Wix>
The
Id
in theMedia
element must be greater than the number of files in the original image; it should also take files from previous patches into account. If you’re authoring a second patch and the previous patch used 5000 asId
and updated 11 files, then this number must be greater than 5011. -
Create the patch itself:
candle patch.wsx light patch.wixobj -out patch\patch.wixmsp pyro patch\patch.wixmsp -out patch\patch.msp -t RTM patch\diff.wixmst
- The patch is ready. It’s time to verify it works as expected. To do it, install the original install package, then install the patch and check the files were really updated.
In my case patch installation wasn’t smooth: the patch needed to update files which were not KeyPath of a Component. I guess no one thought about it when the installation package was created. In order to install the update correctly, property REINSTALLMODE must contain a mode. It was issued as warning by pyro.exe. So one needs to use the following command line:
msiexec /p patch.msp /qb REINSTALL=ALL REINSTALLMODE=omusa
Without /qb option, the full UI with Modify, Repair, Remove buttons is displayed, which is not quite great. I tried to click Modify and then click Next; patch installed successfully in this case. I didn’t try to click other buttons.
March 27, 2011 at 18:49
Can you please explain the 4th point (Update the files under C:\patch\upp with the new versions.)
How to update and how files came her?
March 27, 2011 at 19:20
According to step 2, the
upp
is the same asrtm
.So in step 4, I took the updated files from a newer build and put them to the corresponding places. In my case, there were only several files that needed updating. (Other files, however, were binary different after a re-build.)
April 10, 2011 at 00:20
Hi alexyv. I was successful in creating the patch and it worked perfect with test files. But now using the same steps with original files, I am puzzled.
I have lots of sql files too which my installer executes on the sql server. But I am not able to create any custom action in this patch which will execute my sql files present in patch.
Can you please post some sample code for same?
April 11, 2011 at 10:48
Sunil,
Do you have the custom action which executes your SQL files in the original MSI?
If yes, then you should make sure the condition of that action is true when patching. If not, then you should add a new custom action in the updated MSI and re-create your patch.
More details on your package structure can also help. You can send me a message to iasoft (at) nm.ru.
April 14, 2011 at 12:52
Sunil,
Take a look at Create a sql server database at a specified location at Stack Overflow. Answers to it contain links to WiX SQL extension. I hope it helps you.
April 18, 2011 at 17:14
Hi,
I created patch file using the following ways.
1) Using pyro and torch , I have created patch(.msp) and its
working fine. But when I made any changes in merge modules that is not
reflected after patch is installed.
2) Using .pcp, I have created patch(.msp) file. When I installing
the patch, it is showing “Repair”. But no changes are reflected.
I used msiexec /p patch.msp /qb REINSTALL=ALL REINSTALLMODE=omusa also.
So I used Orca to view the changes. First , opened the targeted msi,
then Transform->View Patch. In that, I can able to see the changed
files. But after installing the patch, that wont be reflected.
I cannot able to find the solution for this problem.
Please advice.
April 19, 2011 at 12:45
Hi Preethi,
Try to run your patch with verbose logging, I think it could be because of conditions set in the merge modules.
Does
REINSTALL=ALL REINSTALLMODE=omusa
not help with the 1st approach?(I believe you creating patch by comparing the original MSI and the new one. Because what I described in the post may not work with merge modules.)
October 2, 2014 at 12:43
Hi Alexey,
Thank for your instruction. This post help me a lot. However, in case my software have 2 version 1.1.2 and 1.1.3. Version 1.1.3 add more 3 files, I can create the patch file. But when I install patch file, I encountered error: “The file ‘My file 01’ cannot be installed because the file cannot be found in cabinet file ‘ProductP.cab’. This could indicate a new network error, an error reading from the CD-ROM, or a problem with this package”. How can I overcome this issue?
October 4, 2014 at 16:29
Hi Minh,
I’m really glad this instruction helped you.
Sorry but I don’t know the answer to your question. It looks Windows Installer engine knows it should install new files but it doesn’t know where to get them from. Do both MSI packages have cabinets attached to them?
You can run the patch with detailed logging, see Create an MSI log file, it could explain where Windows Installer tries to find the files.
June 18, 2015 at 15:30
Thanks this worked nicely.
August 18, 2015 at 06:12
Hi Alexey,
Thanks for your share.But have a question :
can your procedures generate GAC dll update?
November 19, 2015 at 15:09
Hi Harlan,
I don’t know whether it will work for DLLs in GAC. I haven’t worked with GAC, yet if I understand correctly, you don’t usually update DLLs in GAC: you install the new version of the DLL (the new assembly) and remove the old version (or probably create redirection policy so that apps use only the new version).
Theoretically, this approach should work but I don’t know the low-level details.