Let's say you want to do a simple C++ Custom Action for something like, say, dumping a property to a file. I'm going to assume at least some knowledge of C and C++. There are two parts to this - building the C++ DLL (I'm using visual studio .net 2003 in this example) which contains your custom action, and the wix script which when inserted into your wix source file, will schedule and execute that DLL.

The C++ Dll Function

Per the windows installer documentation, C/C++ functions as used by the windows installer must use the '__stdcall' calling convention, and take a single parameter of 'MSIHANDLE'. Note that to get access to the MSI stuff you should include msi.h and msiquery.h, and link to msi.lib. You must also export the function from the dll - you can do this either by using the module definition file if you have one, or by putting a comment in for the linker. I'll use the second option. At any rate. If you go to visual studio, create a new win32 dll project with nothing in it, and paste the following code, it should create a valid function call for use by MSI.

#pragma comment( linker, "/EXPORT:MyExampleFunction=_MyExampleFunction@4" )  extern "C"  UINT __stdcall MyExampleFunction(MSIHANDLE hInstall)  {     //read the property from the installer into a buffer     char buffer[255]; DWORD buflen = sizeof(buf)     MsiGetProperty(hInstall,"ProductCode?",buffer,&buflen);     //good practice would include checking the return values, but this is a trivial example so I'm not going to bother.
//now that we have the property, write to a file     FILE* hFile = fopen("C:\\testfile.txt","w");     fwrite(buffer,sizeof(char),buflen,hFile);     fclose(hFile);
return 0;  }

This should compile, and you should now have a DLL which contains the exported function MyExampleFunction which can be called from the windows installer.

While in the body of the function you can pretty much do what you like, you must declare the function using a similar style declaration to what I've done above, and your function must return 0. Any other return values will cause the installation to fail, unless you specify Return="ignore" in your CustomAction​?​​ definition below.

WiX code to sequence and execute this action

Firstly, we have to insert the dll into our MSI package so that we can get access to it. Do it via a simple 'Binary' entry anywhere in your 'Product'

<Binary Id="MyExampleDll" src="C:\ExampleDll\Release\MyExampleDll.dll"/>

Now we have this, we can define the installer custom action which will call this function out of the dll.

<CustomAction Id="CaExampleFunction" BinaryKey="MyExampleDll" DllEntry="MyExampleFunction" />

With that done, we can sequence the CustomAction​?​​. I'm going to sequence it in the InstallExecuteSequence​?​​, just after InstallInitialize​?​​. This doesn't imply any sequencing rules, it's just because for my trivial example I had to put it somewhere.

<InstallExecuteSequence>    <Custom Action="CaExampleFunction" After="InstallInitialize" />  </InstallExecuteSequence>

So there we have it. There is a certain amount of 'fluff' involved, but once you're aware of what to do, it's pretty simple. Good luck!

- Orion Edwards