WiX tutorial

Lesson 10 Standard Libraries

There are a few additional libraries bundled with WiX helping us, installer developers to accomplish common tasks. We will examine them in detail but let's start with a simple sample first.

10.1 Custom Actions and User Interface

Our SampleListbox demonstrates how a custom action can collect data that is to be displayed in the user interface. We will use the WcaUtil custom action library bundled with WiX to help us accomplish this. This library contains many convenience functions that make it easier to write custom actions in C++. These include functions to get and set properties both in a raw format and formatted, modifying the installer databases or logging to the Windows Installer log file.

We will modify the stock UI slightly to accommodate a new dialog, InstallDlg. We've already seen in previous lessons how to accomplish this. So, there is nothing here we don't already know: we specify and schedule our custom action; we specify our listbox to be linked to a public property.

<CustomAction Id="FillingListbox" BinaryKey="FillListbox" DllEntry="FillListbox" />

<UI>
  <Dialog Id="InstallDlg" Width="370" Height="270" Title="[ProductName] Setup" NoMinimize="yes">
    ...
    <Control Id="FilledListbox" Type="ListBox" Sorted="yes" Indirect="no"
      Property="LISTBOXVALUES" X="10" Y="50" Width="200" Height="130" />
  </Dialog>

  <InstallUISequence>
    <Custom Action="FillingListbox" After="CostFinalize" />
    <Show Dialog="InstallDlg" After="FillingListbox" />
  </InstallUISequence>
</UI>

<Binary Id="FillListbox" SourceFile="FillListbox.dll" />

The custom action will use Wca to initiate and close our connection to the installer as well as to inject the values appearing in the public property, reflected in the listbox connected to this property:

#include <windows.h>
#include <msi.h>
#include <msiquery.h>
#include "wcautil.h"

#pragma comment(linker, "/EXPORT:FillListbox=_FillListbox@4")

extern "C" UINT __stdcall FillListbox(MSIHANDLE hInstall) {
  HRESULT hResult = WcaInitialize(hInstall, "FillListbox");
  if (FAILED(hResult)) return ERROR_INSTALL_FAILURE;

  MSIHANDLE hTable = NULL;
  MSIHANDLE hColumns = NULL;

  hResult = WcaAddTempRecord(&hTable, &hColumns, L"ListBox", NULL, 0, 3, L"LISTBOXVALUES", 1, L"Item 1");
  hResult = WcaAddTempRecord(&hTable, &hColumns, L"ListBox", NULL, 0, 3, L"LISTBOXVALUES", 2, L"Item 2");
  hResult = WcaAddTempRecord(&hTable, &hColumns, L"ListBox", NULL, 0, 3, L"LISTBOXVALUES", 3, L"Item 3");

  if (hTable)
    MsiCloseHandle(hTable);
  if (hColumns)
    MsiCloseHandle(hColumns);
  return WcaFinalize(hResult);
}

Apart from msi.lib, you also need to link against dutil.lib and wcautil.lib when building the DLL. Those files are installed with the WiX toolset.

10.2 Silence, Please!

The standard custom action to start an executable might not be the best solution if the program to be launched happens to be a console application rather than something with the usual graphical user interface. In these cases, we might want to avoid the command line console windows to flash up for a moment.

The standard WixUtil library has a special custom action called QtExec just for these occasions. It expects to find the command line to be run in a predetermined property called QtExecCmdLine. The execution can be either immediate or deferred.

<Property Id="QtExecCmdLine" Value="something.exe"/>
<CustomAction Id="SilentLaunch" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="immediate" Return="check" />

<InstallExecuteSequence>
  <Custom Action="SilentLaunch" After="..." />
</InstallExecuteSequence>

To run 64-bit executables, use the CAQuietExec64 and QtExec64CmdLine properties instead.

To build, we have to link against the standard library:

candle.exe Sample.wxs
light.exe -ext WixUtilExtension Sample.wixobj
Copyright © 2004-2010, Gábor DEÁK JAHN, Tramontána
Comments and contributions are most welcome                   Comments and contributions are most welcome
A note: some people use a very braindead spam filtering idea actually generating extra amounts of spam: asking the sender to reply to an acknowledgment message in order to be placed on a whitelist and allowed through. All those who do so, unfortunately, will never receive a reply from me: I refuse this idea both in theory and practice.