Adding Custom Actions

Windows Installer XML

Adding a Custom Action

This example shows how to author a binary custom action called "FooAction". A common example is a dll custom action that launches notepad.exe or some other application as part of their install. Before you start, you will need a sample dll that has an entrypoint called "FooEntryPoint". This sample assumes you have already reviewed the Creating a Skeleton Extension topic.

Step 1: Create a Fragment

You could directly reference the custom action in the same source file as the product definition. However, that will not enable the same custom action to be used elsewhere. So rather than putting the custom action definition in the same source file, let's exercise a little modularity and create a new source file to define the custom action called "ca.wxs".

<?xml version='1.0'?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
   <Fragment>
      <CustomAction Id='FooAction' BinaryKey='FooBinary' DllEntry='FooEntryPoint' Execute='immediate'
                    Return='check'/>
 
      <Binary Id='FooBinary' SourceFile='foo.dll'/>
   </Fragment>
</Wix>

Okay, that's it. We're done with editing the "ca.wxs" source file. That little bit of code should compile but it will not link. Remember linking requires that you have an entry section. A <Fragment/> alone is not an entry section. Go to the next step to link the source file.

Step 2: Add the custom action

We would need to link this source file along with a source file that contained <Product/> or <Module/> to successfully complete.

<?xml version='1.0'?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
   <Product Id='PUT-GUID-HERE' Name='Test Package' Language='1033' 
            Version='1.0.0.0' Manufacturer='Microsoft Corporation'>
      <Package Description='My first Windows Installer package'
            Comments='This is my first attempt at creating a Windows Installer database' 
            Manufacturer='Microsoft Corporation' InstallerVersion='200' Compressed='yes' />
 
      <Media Id='1' Cabinet='product.cab' EmbedCab='yes' />
 
      <Directory Id='TARGETDIR' Name='SourceDir'>
         <Directory Id='ProgramFilesFolder' Name='PFiles'>
            <Directory Id='MyDir' Name='Test Program'>
               <Component Id='MyComponent' Guid='PUT-GUID-HERE'>
                  <File Id='readme' Name='readme.txt' DiskId='1' Source='readme.txt' />
               </Component>
 
               <Merge Id='MyModule' Language='1033' SourceFile='module.msm' DiskId='1' />
            </Directory>
         </Directory>
      </Directory>
 
      <Feature Id='MyFeature' Title='My 1st Feature' Level='1'>
         <ComponentRef Id='MyComponent' />
         <MergeRef Id='MyModule' />
      </Feature>

      <InstallExecuteSequence>
         <Custom Action='FooAction' After='InstallFiles'/>
      </InstallExecuteSequence>
   </Product>
</Wix>

Those three lines are all you need to add to your Windows Installer package source file to call the "FooAction" CustomAction. Now that we have two files to link together our call to light.exe gets a little more complicated. Here are the compile, link, and installation steps.

C:\test> candle product.wxs ca.wxs
 
C:\test> light product.wixobj ca.wixobj –out product.msi
 
C:\test> msiexec /i product.msi

Now as part of your installation, whatever "FooAction" is supposed to perform, you should see happen after the InstallFiles action.