Custom action project templates

New in this week’s WiX build 3.0.4123 are Visual Studio 2005 & 2008 templates for C++, C#, and VB custom action projects:

WiX Project Templates for Visual Studio

The C++ project sets you up with the WiX unmanaged CA utility library (wcautil), while the C# and VB projects use the DTF library for managed-code MSI custom actions. I assume you’re here because you want to read more about the latter.

When DTF first released with WiX last week, it included some sparse documentation about how to create a post-build step to package up your managed CA assembly in a form callable by MSI. I apologize to anyone who jumped on it right away and had trouble hooking things up (which was only made more difficult by a missing binary that had to be built from source). I should have had these templates ready then.

When you create a C# custom action project from the new template, the project has the necessary post-build step hooked up already. For the curious, those build rules are in %ProgramFiles%\MSBuild\Microsoft\WiX\v3.0\ Building the custom action project will produce an additional DLL in the target directory with the name $(TargetName).CA.dll. That is the DLL to be streamed into your MSI Binary table. Since that DLL exports ordinary entrypoints callable directly by the MSI engine, you can use it with any MSI authoring tool as if it was an unmanaged CA DLL.

The custom action build process will automatically package up any non-GAC’d assemblies that your CA depends on. (Make sure the Copy Local property is set to ‘true’ on the reference node if you want it included.) Those dependencies will include at a minimum the Microsoft.Deployment.WindowsInstaller.dll assembly from DTF. Additionally, any items in the project with a Build Action of ‘Content’ will be included in the CA package. CustomAction.config is the sole Content file in the template; your CA may require additional resources or data files at runtime.

In Votive, a convenient way to consume the custom action DLL in your setup is via a project reference:

  1. Create a solution with a WiX MSI or WiX Library project and a C# or VB custom action project.

  2. Add a reference from the WiX project to the custom action project.

  3. Author the custom action in your setup with WiX code similar to the fragment below. Note you may need to change some attributes in the XML, depending on your CA and how it executes.


  <Binary Id=MyCustomAction.dll

   SourceFile=$(var.CAProjectName.TargetDir)$(var.CAProjectName.TargetName).CA.dll />

  <CustomAction Id=MyCustomAction BinaryKey=MyCustomAction.dll

   DllEntry=CAMethodName Execute=immediate />


I hope this helps interested developers get started with managed custom actions. Future posts here will hopefully get into some actual coding.

Comments (8)

  1. Stefan says:

    Thank you! Exactly the info I was looking for!

  2. JonM says:

    Is this add-in going to be included in VS 2010 at some point?



  3. @JonM These project templates along with the Votive extension for Visual Studio 2010 are part of the WiX 3.5 package. I don't know what the plans are for future versions of Visual Studio.

  4. JonM says:

    Thanks for responding Jason. We just moved to using Wix3.0 in our production install creation so it will be some time before we get to use Wix3.5.

    However, I have been able to get this to work for us quite well. We have even scripted some of the process after the dll is created since we use makefiles. With what we have setup all you need is your cs file and a makefile that states that this type of dll needs to be created and voila you get a XXXXXX.CA.dll.

    I am currently writing up a doc for my team to reference so we can use C# for our future custom actions.


  5. Michael says:

    Having Issues getting this working.  When I turn on logging for my installed I get the following Error:

    Calling custom action SQLHarnessCA!SQLHarnessCA.CustomActions.CustomAction1

    Error: could not load custom action class SQLHarnessCA.CustomActions from assembly: SQLHarnessCA

    System.BadImageFormatException: Could not load file or assembly 'SQLHarnessCA' or one of its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded.

    File name: 'SQLHarnessCA'

      at System.Reflection.Assembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)

      at System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)

      at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)

      at System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)

      at System.AppDomain.Load(String assemblyString)

      at Microsoft.Deployment.WindowsInstaller.CustomActionProxy.GetCustomActionMethod(Session session, String assemblyName, String className, String methodName)

    My Wix File is put together like So:

    <Binary Id ="SQLHarnessCA.dll"

               SourceFile ="$(var.SQLHarnessCA.TargetDir)$(var.SQLHarnessCA.TargetName).CA.dll"></Binary>

       <CustomAction Id ="PreReqChecker"

                     BinaryKey ="SQLHarnessCA.dll"

                     DllEntry ="CustomAction1"



                     Return="check" />

    Am I missing something stupid?

  6. Michael says:

    The answer is yes I was missing something stupid… My Custom Action DLL was compiled using .Net Framework 4.0 and the 4.0 Framework hasn't been installed on the test machine yet, because that's part of what this Custom action is going to do…  I updated the DLL to Compile against the 2.0 Framework and everything appears to be working correctly now.

  7. Nicolas says:

    Thanks a lot for this clear explanation, you saved me so much time !

  8. *** says:

    Great post!!

    Thanks for your effort.