WiX + Ngen = Profit
Ngen.exe (Native Image Generator) is used to compile assemblies ahead-of-time (AOT) instead of the usual just-in-time (JIT) compiling. Running Ngen after an installation allows your application to enjoy faster loading times at the expense of a slower installation, a worthwhile tradeoff in many cases. How do you run Ngen at the end of a MSI installation using WiX? The answer is by using a Custom Action.
First add a new Custom Action project to the solution containing your WiX projects:
Note that I have chosen the 3.5 framework in order to get the Custom Action to play nice with WiX 3.5. You can still use this task to compile 4.0 assemblies.
Now add a reference to your new Custom Action from the WiX project:
After renaming the class and doing a bit of coding, we are left with this:
Inside our RunNgen class we have the OnInstallation method marked with the CustomAction attribute. This is the method that will be called from the WiX-project.
Inside the GetNgenProcess method we have a couple of points of interest. First, the ngenPath specifies the path to the Ngen executable. assemblyPath contains the path to our main executable. IDIR and EXECUTABLE are both properties coming from the WiX project, more about them later. The argument passed to ngen.exe, install “[assemblyPath]”, instructs Ngen to generate native images for the executable and its dependencies and lastly install the images in the native image cache.
We are not interested in showing the user the gory details from the Ngen process, thus we redirect the standard output and do not show the console.
The standard output is captured in our StreamReader and logged to file at the end of the process.
Now IDIR and EXECUTABLE needs to be specified within the product tag in our WiX project:
“a_directory_id” is the id of the directory containing our installation and “name_of_executable” is the name of the main executable.
In order to inform WiX of the Ngen action, we specify the follow after the Product tag:
You should recognize “OnInstallation” as the name of the Custom Action method. SourceFile specifies the path to the assembly containing the custom action. The added “CA” at the end of the assembly name specifies that this is indeed a Custom Action.
To call the Ngen action, add the following to the InstallSequence:
And there you have it! The Custom Action we have created can be used by any WiX project and can easily be further tweaked if other usage scenarios arise. One example could be an application containing multiple executables.
If you need to debug your actions, the Debugger.Launch() method can be called from the Custom Action. Just remember to remove it before shipping…