Showing posts with label WIX. Show all posts
Showing posts with label WIX. Show all posts

Wednesday, July 6, 2011

WIX: Sleep between Custom Actions during installation

If you require to pause your installation between some custom actions, you can use the following:
<Property Id="QtExecDeferred" Value='"ping" -n 15 127.0.0.1'/><CustomAction Id="QtExecDeferred" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="deferred" Return="check" Impersonate="no"/>
The QtExec allows to run command line silently.

WIX: How to run Command Line silently

WIX provides a Custom Action that allows to run Command line silently - Quiet Execution Custom Action

You should use it exactly the same way as listed in the WIX example. Just put your command in the Properties value.

<Property Id="QtExecCmdLine" Value='"command" parameters'/><CustomAction Id="QtExecExample" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="immediate" Return="check"/>

Make sure the command has double quotes. For example: '"ping" -n 15 127.0.0.1'

Don't forget to add the WixUtilExtension extension during building the msi package.

Saturday, November 13, 2010

Executing PowerShell script for SharePoint in msi.

If you want to execute PowerShell script in msi written with WIX you may face some problems. Here I explain issues I had in my project:
To execute the script you need to create custom action which runs PowerShell. Note that you cannot run SharePoint Management Shell (at least I didn't find how to do that :). But you can run PowerShell and load SharePoint snap-in inside the script:


<CustomAction Id="PSExecute" Property="PS" ExeCommand="&'[FOLDER]\install-extension.ps1'" Execute='deferred' Return='check'/> 


The script execution may fail due to some reasons. For example, SharePoint Administration service is not running, PowerShell Execution Policy prevents scripts from running, you run msi under account who is not SharePoint Farm administrator. Maybe there are another reasons that I don't know yet ;)

When the script is executed from msi, the PowerShell console is running but you should be a very fast person to catch its output :) So, it is required to add logging into your script. Using Start-Transcript is the only that I'm able to use. Refer to the following post for more information about Start-Transcript.

One more useful thing is "throw 'ERROR'" to abort the script execution if needed. For example SP-GetObject and SP-AddSolution cmdlets may throw errors during execution but they will not cause the script to be completed with error. And installer completes successfully but it actually does not do anything. You can add throw 'ERROR' where is needed and installation ends with Fatal Error.

Tuesday, June 22, 2010

WIX Patch: replace keypath and restart service

I need to create a small update (patch) for my application. I have large application with about 2000 of files. Source project comprises 13 wxs files. A file list is generated by the "heat" command. So, each file is represented as a single component and become a key path (key file) for the component.
During the update I want to replace one dll which is used by a service. So, I have to stop the service, replace the dll and start the service.
After few days of investigation I found out the following:
There are at least two options for patch creation using WIX:
1. Using Purely WiX
2. Using Patch Creation Properties

I prefered the first one.

Commands for the patch creation are discribed in the link above. I did the following:
1. Modify the component for the file to be replaced:
originally was:
<Component Id="cmp1000" Guid="GUID">
<File Id="file1000" KeyPath="yes" Source="$(var.Root)\File.dll" />
</Component>

change to:
<Component Id="cmp1000" Guid="GUID">
<ServiceControl Id='StopServicePatch' Name='ServiceName' Stop='install'/>
<File Id="file1000" KeyPath="yes" Source="{new path}\File.dll" />
<ServiceControl Id='StartServicePatch' Name='ServiceName' Start='install'/>
</Component>
The source file path has been changed as well as ServiceControl actions are added.
2. Build two msi files with the same name
3. Create msp patch file

But if you now run the patch by double clicking on the .msp file, it does not work as expected - it runs UI and asks to choose option for the original application - modify, repair or remove.
4. To install the patch run the following command line:
msiexec /p patch.msp LIMITUI=1 REINSTALLMODE=emus

setting the LIMITUI property restricts UI and the patch is installed without displaying any dialog windows.
the REINSTALLMODE specifies type of reinstallation to be performed. By default the REINSTALLMODE is "omus", but in this case my dll is not replaced as it has the same version number. So, I changed property to "emus" and now the dll is replaced by the patch.

in the log file of the patch installation I see the file is repalced:
Patch Modified Files List:
MSI (s) (A4:64) [15:38:51:275]: File = file1000: Final State = Install
...
File: C:\Program Files (x86)\MyApp\File.dll; Overwrite; Won't patch; Existing file is of an equal version

Wednesday, May 5, 2010

Check if related product is already installed

If your application depends on some another basic application, you need to check if the basic application is already installed. You can use the FindRelatedProducts action.
Use the following steps:
1) Define the UpgradeCode of the basic product:
<Upgrade Id="PUT_YOUR_GUID_HERE">
<UpgradeVersion OnlyDetect="yes" Minimum="1.0.0.0" IncludeMinimum='no' Property="BASICINSTALLED" />
</Upgrade>
2) Specify a Custom Action performed if the basic product is not installed:
<CustomAction Id='NotBasic' Error='The basic product should be installed on the server.' />

3) Schedule the custom action execution
<InstallUISequence>
<Custom Action='NotBasic' After='FindRelatedProducts'>NOT BASICINSTALLED</Custom>
</InstallUISequence>

During installation, Windows Installer define a Product Code for the specified Upgrade Code and assign it to the BASICINSTALLED property. If there is no products installed with the Upgarde Code, the property is not defined. In this case the Custom Action will be performed and installation completes.

Note: The property assignment will be skipped if the basic appliaction is installed on per-machine mode but your application is installing in per-user mode.
The following log is written:
FindRelatedProducts: current install is per-user. Related install for product '{Product_Code_GUID}' is per-machine. Skipping...

Wednesday, April 28, 2010

Useful links for WIX UI.

WIX provides you with sets of built-in UI dialogs. To add a dialog set, add the reference the WixUIExtension:
light Product.wixobj -out Product.msi -ext WixUIExtension 
Built-in dialog sets in WIX Tutorial
But what if I need to customize my installation?
The following articles could be usefult to understand how to customize installation dialogs:
Wix Tutorial - Lesson 8
Extending UI
Windows Installer - User Interface Reference
Will try to consolidate all this information into the one article.

Tuesday, March 2, 2010

Generate list of source files

If you need to install a lot of files during setup there are the following tools to generate fole with list of sources:
There is the native tool in WIX package:
From my experience:
Used the following command line:
heat dir "C:\Folder" -cg SGroup -dr INSTALLDIR -out HeatFiles.wxs -gg -sfrag -srd
It generates single component for a file even if all files are located in the same folder. Later, I plan to do upgrades for the original msi, so it can be difficult to maintant the file with such big list of components. Also, when you need to do an update for the original msi the component GUIDs are changed. It may cause issues during installation of the update.

I prefer to use Mallow tool:
It was originally developed for WIXv2
But there is the newest version for Wix v3.
Uses the following command line:
mallow -d "C:\Folder" -t files.wxs -w INSTALLDIR -a SourceDir
It generates single component for all files in a folder. It allows to change original file and preserve component GUIDs - this is very usefull when you create update for your msi. In this case it adds change log in the top of the file.
you need to use the folowing command line:
mallow -d "C:\Folder" -s files.wxs -t files.wxs -w INSTALLDIR -a SourceDir

WIX - first steps