How to Handle .NET Framework Native Images in Software MSI Installation Packages?


When you find in a file which is suffixed by “.ni” in an application capture (For eg: Aclayers.ni.dll), this is an indication that it is a native image for an assembly. (The base assembly can be found in the application installation directory). These files cannot be added directly to the MSI package. Instead, it needs to be done through a .NET executable(ngen.exe).
In this below article, we look at the basics and implementation of this process.

Overview of Native Image Generator:

The Native Image Generator (ngen.exe) creates a native image from a managed assembly and installs it into the native image cache on the local computer. The native image cache is a reserved area of the global assembly cache. Once you create a native image for an assembly, the runtime automatically uses that native image each time it runs the assembly. You do not have to perform any additional procedures to cause the runtime to use a native image. Running Ngen.exe on an assembly allows the assembly to load and execute faster, because it restores code and data structures from the native image cache rather than generating them dynamically.

How Native Generator Works

Ngen.exe does not use standard assembly probing rules to locate the assemblies you specify on the command line. Ngen.exe looks only in the current directory for assemblies that you specify. Therefore, to allow Ngen.exe to locate your assemblies, you should either set your working directory to the directory that contains the assemblies you want to create native images for or specify exact paths to the assemblies.

This tool can be located at <drive>:\WINNT\Microsoft.NET\Framework\<version>\ngen.exe

This tool is used to create a native Image from a .NET assembly and installs it into the native image cache on that computer. Since assembly image is present on the local machine cache loading of the assembly becomes faster because .NET reads data from the native image than generating them dynamically (JIT). Pre-compiling assemblies with Ngen.exe can improve the startup time for applications, because much of the work required to execute code has been done in advance.

The default usage for NGen is extremely simple: ngen install aclayer.dll

This will generate native images for aclayer.dll and all of its dependencies and create a native image for this dll in C:\Winnt\Assembly\Native Images as aclayer.ni.dll.

This process can be quite slow. For larger applications you may wish to use the /queue option which will queue up aclayer.dll, and all of its dependencies, so that they will be converted by the Native Image Service. This will happen in the background, at the service’s earliest convenience. Once the native image is generated it will be stored in the native image cache and used automatically.

Usage:

While Installing:
Identify the Assembly which creates these native images, mention the same path in these scripts. Example: C:\Program FIles\DWG TrueView 2008\AcLayer.dll. For multiple assemblies use the function mentioned.

Use this script in your MSI Package.

Option Explicit
Dim wshShell, ngen, FSO, windir, assembly,PrgFiles
Set wshShell = CreateObject(“WScript.Shell”)
Set FSO = CreateObject(“Scripting.FileSystemObject”)
windir = wshShell.ExpandEnvironmentStrings(“%Windir%”)
PrgFiles = wshShell.ExpandEnvironmentStrings(“%ProgramFiles%”)
ngen = windir & “\Microsoft.NET\Framework\v2.0.50727\ngen.exe”

if FSO.FileExists(ngen) then
assembly=chr(34) & PrgFiles & “\DWG TrueView 2008\AcLayer.dll” & chr(34)
Generate(assembly)
end if

set FSO = nothing
set wshShell = nothing

Function Generate (Byval file)
Dim strCmd,wshShell1
Set wshShell1 = CreateObject(“WScript.Shell”)
strCmd= chr(34) & ngen & chr(34) & ” install ” & file
wshShell1.run strCmd,0
Set WshShell1 = nothing
End function

While Un-Installing:

Option Explicit
Dim wshShell, ngen, FSO, windir, assembly,PrgFiles
Set wshShell = CreateObject(“WScript.Shell”)
Set FSO = CreateObject(“Scripting.FileSystemObject”)
windir = wshShell.ExpandEnvironmentStrings(“%Windir%”)
PrgFiles = wshShell.ExpandEnvironmentStrings(“%ProgramFiles%”)
ngen = windir & “\Microsoft.NET\Framework\v2.0.50727\ngen.exe”

if FSO.FileExists(ngen) then
assembly=chr(34) & PrgFiles & “\DWG TrueView 2008\AcLayer.dll” & chr(34)
DeleteImages(assembly)
end if

Function DeleteImages (Byval file)
Dim strCmd,wshShell1
Set wshShell1 = CreateObject(“WScript.Shell”)
strCmd= chr(34) & ngen & chr(34) & ” uninstall ” & file
wshShell1.run strCmd,1
Set WshShell1 = nothing
End function

Note: To run Ngen.exe, you must have administrative privileges. Hence, run this CA in deferred/System Context mode.