How to properly NGen .NET application during installation
I'm using Inno Setup
to generate setup program for my application, and I would like to write a script to NGen my application during installation. I want the code to be able to NGen files targeting x86
, x64
, or AnyCPU
. I want to be able to NGen on 32bit
and 64bit
systems. How can I achieve this?
I've found a couple of helpful links:
Getting the .NET Framework directory path http://nsis.sourceforge.net/Get_directory_of_installed_.NET_runtime Where I've found it is a quite complex problem - there can be up to 4 different versions of NGen application:- for CLR 2.0 and 32bit systems
- for CLR 2.0 and 64bit systems
- for CLR 4.0 and 32bit systems
- for CLR 4.0 and 64bit systems
And it is even more complicated开发者_JAVA技巧 by the fact the application can target 32bit CPU and run on 64bit system.
So what came to my mind was a function looking like this:
function NGenFile(file: String; targetCPU: TTargetCPU; targetCLR: TTargetCLR): Boolean;
and call it somewhere in [Code]
after successful isntallation:
NGenFile(ExpandConstant('{app}\application.exe'), tcpu64, tclr20);
NGenFile(ExpandConstant('{app}\library1.dll'), tcpu64, tclr40);
NGenFile(ExpandConstant('{app}\library2.dll'), tcpu32, tclr20);
NGenFile(ExpandConstant('{app}\library3.dll'), tcpu32, tclr40);
NGenFile(ExpandConstant('{app}\library4.dll'), tcpuAny, tclr20);
NGenFile(ExpandConstant('{app}\library5.dll'), tcpuAny, tclr40);
And it would work like this:
application.exe (tcpu64, tclr20)
On 64bit system it would generate native image targeting 64bit CPU and CLR 2.0, Result := True On 32bit system it wouldn't do anything, Result := Falselibrary1.dll (tcpu64, tclr40)
On 64bit system it would generate native image targeting 64bit CPU and CLR 4.0, Result := True On 32bit system it wouldn't do anything, Result := Falselibrary2.dll (tcpu32, tclr20)
On 64bit system it would generate native image targeting 32bit CPU and CLR 2.0, Result := True On 32bit system it would do the same as on 64bit systemlibrary3.dll (tcpu32, tclr40)
On 64bit system it would generate native image targeting 32bit CPU and CLR 4.0, Result := True On 32bit system it would do the same as on 64bit systemlibrary4.dll (tcpuAny, tclr20)
On 64bit system it would generate native image targeting 64bit CPU and CLR 2.0, Result := True On 32bit system it would generate native image targeting 32bit CPU and CLR 2.0, Result := Truelibrary5.dll (tcpuAny, tclr40)
On 64bit system it would generate native image targeting 64bit CPU and CLR 4.0, Result := True On 32bit system it would generate native image targeting 32bit CPU and CLR 4.0, Result := True
So to make it work, I need to know 4 different paths to .NET runtime directory. This is what I've found:
32bit system CLR 2.0
Get value of "InstallRoot" in "HKLM\Software\Microsoft\.NETFramework", save to value1 Get name of first value in "HKLM\Software\Microsoft\.NETFramework\Policy\v2.0", save to value2 value1 + "v2.0." + value2 + "\ngen.exe" => win Example: "c:\Windows\Microsoft.NET\Framework\v2.0.50727\ngen.exe" I assume this will work the same on 32bit and 64bit systems32bit system CLR 4.0
Get value of "InstallRoot" in "HKLM\Software\Microsoft\.NETFramework", save to value1 Get name of first value in "HKLM\Software\Microsoft\.NETFramework\Policy\v4.0", save to value2 value1 + "v4.0." + value2 + "\ngen.exe" => win Example: "c:\Windows\Microsoft.NET\Framework\v4.0.30319\ngen.exe" I assume this will work the same on 32bit and 64bit systems64bit system CLR 2.0
How to get InstallRoot for 64bit .NET Framework? Example: "c:\Windows\Microsoft.NET\Framework64\v2.0.50727\ngen.exe"64bit system CLR 4.0
How to get InstallRoot for 64bit .NET Framework? Example: "c:\Windows\Microsoft.NET\Framework64\v4.0.30319\ngen.exe"
I'm actually not sure if the "InstallRoot" value on 64bit systems would point to InstallRoot of 32bit .NET, or 64bit .NET, so are the first 2 methods reliable for any system? And how would look like the second 2 methods? Is there any simpler way to achieve all of this?
What version of InnoSetup are you using? In the version I use (5.4.0a), there are already constants for to find the .NET root directory. From the InnoSetup help:
{dotnet20} .NET Framework version 2.0 root directory. {dotnet20} is equivalent to {dotnet2032} unless the install is running in 64-bit mode, in which case it is equivalent to {dotnet2064}.
An exception will be raised if an attempt is made to expand this constant on a system with no .NET Framework version 2.0 present.
{dotnet2032} 32-bit .NET Framework version 2.0 root directory.
An exception will be raised if an attempt is made to expand this constant on a system with no .NET Framework version 2.0 present.
{dotnet2064} 64-bit Windows only: 64-bit .NET Framework version 2.0 root directory.
An exception will be raised if an attempt is made to expand this constant on a system with no .NET Framework version 2.0 present.
{dotnet40} .NET Framework version 4.0 root directory. {dotnet40} is equivalent to {dotnet4032} unless the install is running in 64-bit mode, in which case it is equivalent to {dotnet4064}.
An exception will be raised if an attempt is made to expand this constant on a system with no .NET Framework version 4.0 present.
{dotnet4032} 32-bit .NET Framework version 4.0 root directory.
An exception will be raised if an attempt is made to expand this constant on a system with no .NET Framework version 4.0 present.
{dotnet4064} 64-bit Windows only: 64-bit .NET Framework version 4.0 root directory.
An exception will be raised if an attempt is made to expand this constant on a system with no .NET Framework version 4.0 present.
精彩评论