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…
WiX can hardly be called a beginner friendly framework. Having used the framework for the last couple of days, here are a few tips and tricks I have picked up:
Checking the .Net version
Using the following, the installer fetches the version of the installed .Net framework. If the version matches the requirements all is well. If an older version is installed, the specified message is displayed. This will only inform the user of the missing installation, however, using a bootstrapper the framework (or other dependencies) can be installed together with your MSI.
GUID is the upgrade code of your product. THISVERSION is the current version of the MSI.
Scheduling the removal of the old version after InstallFinalize assures that only files that actually have changed are being replaced.
In order to troubleshoot a MSI installation, you need to turn on the log file. The easiest way is using this command:
msiexec /i product.msi /L*v log.txt
product.msi is the MSI to be installed, L means generate a log using v verbose logging and write to file log.txt.
WiX tutorial is a great tutorial, going from a simple installer to a mature package supporting upgrade with custom made UI.