
NGEN optimizes startup time. With an installer class that automates NGEN precompilation, we greatly improve Windows Forms startup time. The code must be run automatically at install time.
NGEN timings before and after: Windows Forms
Program was precompiled with NGEN.
It improved startup time slightly.
Before, no precompilation: 0.2556 seconds
After, NGEN: 0.2184 seconds [faster]First, your installer class will need to know lots of details about the runtime and use several commands. I will list some steps for many of the things you need to do to automate NGEN.exe. This is the command line you can type into the terminal or console to run NGEN.exe at any time on your computer. It is the essential line that our installer class must use automatically to invoke NGEN. The highlighted parts would need to be replaced by you.
[path to NGEN]ngen.exe install [path to assembly]assembly.exe
You need to use an installer module in C#, add it to your assembly, and compile it. This installer module must know the full path of NGEN.exe and your assembly's name, which usually ends in .exe. These values can be found programmatically.

Steps. Go to the Project menu. In the project menu, go to Add New Item and then select "Installer Class" from the list. Create NgenInstaller.cs. In my projects, I used this name for the installer class. The next part of this article shows the source code and method you must add to your installer class to make an installer module that runs NGEN.exe at install time on your users' computers.
Here is the Install method that we need to put in the Installer Class we just made. Here is most important part of this article—the Install method we need to add. It overrides the default Install method, and runs the important system commands to NGEN.
NGEN installer class [C#]
using System.Collections;
using System.ComponentModel;
using System.Configuration.Install;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.IO;
/// <summary>
/// This is run as a custom action by an MSI installer.
/// It is used to call NGEN, which optimizes the assembly.
/// </summary>
[RunInstaller(true)]
public partial class NgenInstaller : Installer
{
public NgenInstaller()
{
InitializeComponent();
}
/// <summary>
/// An override function that is called when a MSI installer is run
/// and the executable is set as a custom action to be run at install time.
/// The native image generator (NGEN.exe) is called, which provides a
/// startup performance boost on Windows Forms programs. It is helpful to
/// comment out the NGEN code and see how the performance
/// is affected.
/// </summary>
/// <param name="stateSaver">No need to change this.</param>
public override void Install(IDictionary stateSaver)
{
base.Install(stateSaver);
// get the .NET runtime string, and add the ngen exe at the end.
string runtimeStr = RuntimeEnvironment.GetRuntimeDirectory();
string ngenStr = Path.Combine(runtimeStr, "ngen.exe");
// create a new process...
Process process = new Process();
process.StartInfo.FileName = ngenStr;
// get the assembly (exe) path and filename.
string assemblyPath = Context.Parameters["assemblypath"];
// add the argument to the filename as the assembly path.
// Use quotes--important if there are spaces in the name.
// Use the "install" verb and ngen.exe will compile all deps.
process.StartInfo.Arguments = "install \"" + assemblyPath + "\"";
// start ngen. it will do its magic.
process.Start();
process.WaitForExit();
}
}Here are the steps, from start to finish, you must take to make the installer class do its magic. It is clearly possible in other installers, but the instructions are different and I have no experience in that area.
Getting started. Make a setup project. Go to File -> New Project, and make an MSI installation project. Add output files. Add the C# project output files under the Install custom action. This is accomplished through the VS GUI and just takes some exploration and trial and error.

Compile and verify. Run the new setup.exe created. Use Process Explorer, running as administrator, to verify that no methods are JITted. Process Explorer has a JIT column that you can add, and if that number is zero when you run your program, the method worked. Also, mscorjit.dll should not be loaded.
Process ExplorerMy programs with NGEN take about half as much time to start up, and use fewer cycles and a bit less memory. NGEN generates native images for an assembly exe, meaning that the JIT compiler doesn't need to run at startup. See the figures at the top of the document.

We saw how you can put together a NGEN installer class in the C# language. Essentially, NGEN images are native programs, and often about as fast as native programs, at least when starting up. The .NET Framework is still required. It is sufficient to take the method here and use it directly. Finally, some framework calls, such as Regex methods, can defeat NGEN and force the JIT to run.
Windows Forms