C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML
With an installer class that automates NGEN precompilation, we improve Windows Forms startup time. The code must be run automatically at install time.
Steps. First, your installer class will need to know lots of details about the runtime and use several commands. I list some steps to prepare for automating NGEN.exe in your C# application.
Next: This is the command line you can type into the terminal or console to run NGEN.exe at any time on your computer.
Tip: It is the essential line that our installer class must use automatically to invoke NGEN.
Example command line [path to NGEN]ngen.exe install [path to assembly]assembly.exe
Module. You need to use an installer module, 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.
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.
Next: We show the method you must add to your installer class to make an installer module that runs NGEN.exe at install time.
Installer. Here is the Install method that we need to put in the Installer Class. Here is most important part—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(); } }
MSI setup. 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.
Tip: This is accomplished through the VS GUI and just takes some exploration and trial and error.
Run the new setup.exe created. Use Process Explorer 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.
Results. My 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.
Note: The test program was precompiled with NGEN. It slightly improved startup time.
NGEN timings before and after: Windows Forms Before, no precompilation: 0.2556 seconds After, NGEN: 0.2184 seconds [faster]
Summary. We developed a NGEN installer class in the C# language. NGEN images are essentially native programs, and often about as fast as native programs, at least when starting up. The .NET Framework is still required.