如何在安装过程中正确使用 NGen .NET 应用程序

Pay*_*aya 5 .net c# installation inno-setup ngen

我正在Inno Setup为我的应用程序生成安装程序,我想在安装过程中为我的应用程序编写一个脚本到NGen。我想要的代码能够NGEN文件目标x86x64AnyCPU。我希望能够在和系统上使用NGen。我怎样才能做到这一点?32bit64bit

我找到了几个有用的链接:
获取 .NET Framework 目录路径
http://nsis.sourceforge.net/Get_directory_of_installed_.NET_runtime
我发现这是一个相当复杂的问题 - 最多可以有 4 个不同的版本的NGEN应用:

  1. 用于 CLR 2.0 和 32 位系统
  2. 用于 CLR 2.0 和 64 位系统
  3. 用于 CLR 4.0 和 32 位系统
  4. 用于 CLR 4.0 和 64 位系统

由于该应用程序可以针对 32 位 CPU 并在 64 位系统上运行,因此情况更加复杂。


所以我想到的是一个看起来像这样的函数:

function NGenFile(file: String; targetCPU: TTargetCPU; targetCLR: TTargetCLR): Boolean;
Run Code Online (Sandbox Code Playgroud)

[Code]在成功安装后调用它:

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);
Run Code Online (Sandbox Code Playgroud)

它会像这样工作:

  1. application.exe (tcpu64, tclr20)
    在 64 位系统上,它会生成针对 64 位 CPU 和 CLR 2.0 的本机图像,结果:= True
    在 32 位系统上,它不会做任何事情,结果:= 假

  2. library1.dll(tcpu64,tclr40)
    在64位系统,它会产生本机映像针对64位CPU和CLR 4.0,结果:=真
    在32位系统,它不会做任何事情,结果:=假

  3. library2.dll (tcpu32, tclr20)
    在 64 位系统上,它将生成针对 32 位 CPU 和 CLR 2.0 的本机映像,结果:= True
    在 32 位系统上,它会在 64 位系统上执行相同的操作

  4. library3.dll (tcpu32, tclr40)
    在 64 位系统上,它将生成针对 32 位 CPU 和 CLR 4.0 的本机图像,结果:= True
    在 32 位系统上,它会在 64 位系统上执行相同的操作

  5. library4.dll (tcpuAny, tclr20)
    在 64 位系统上,它将生成针对 64 位 CPU 和 CLR 2.0 的本机图像,结果:= True
    在 32 位系统上,它将生成针对 32 位 CPU 和 CLR 2.0 的本机图像,结果:= True

  6. library5.dll (tcpuAny, tclr40)
    在 64 位系统上,它将生成针对 64 位 CPU 和 CLR 4.0 的本机图像,结果:= True
    在 32 位系统上,它将生成针对 32 位 CPU 和 CLR 4.0 的本机图像,结果:= True


因此,要使其工作,我需要知道 .NET 运行时目录的 4 个不同路径。这是我发现的:

  1. 32 位系统 CLR 2.0
    获取“HKLM\Software\Microsoft\.NETFramework”中“InstallRoot”的值,保存到 value1
    获取“HKLM\Software\Microsoft\.NETFramework\Policy\v2.0”中第一个值的名称,保存到value2
    value1 + "v2.0." + value2 + "\ngen.exe" => win
    示例:"c:\Windows\Microsoft.NET\Framework\v2.0.50727\ngen.exe"
    我认为这在 32 位和 64 位系统上工作相同

  2. 32 位系统 CLR 4.0
    获取“HKLM\Software\Microsoft\.NETFramework”中“InstallRoot”的值,保存到 value1
    获取“HKLM\Software\Microsoft\.NETFramework\Policy\v4.0”中第一个值的名称,保存到value2
    value1 + "v4.0." + value2 + "\ngen.exe" => win
    示例:"c:\Windows\Microsoft.NET\Framework\v4.0.30319\ngen.exe"
    我认为这在 32 位和 64 位系统上工作相同

  3. 64 位系统 CLR 2.0
    如何获取 64 位 .NET Framework 的 InstallRoot?
    示例:“c:\Windows\Microsoft.NET\Framework64\v2.0.50727\ngen.exe”

  4. 64 位系统 CLR 4.0
    如何获取 64 位 .NET Framework 的 InstallRoot?
    示例:“c:\Windows\Microsoft.NET\Framework64\v4.0.30319\ngen.exe”

我实际上不确定 64 位系统上的“InstallRoot”值是否指向 32 位 .NET 或 64 位 .NET 的 InstallRoot,那么前两种方法对任何系统都可靠吗?第二种方法看起来如何?有没有更简单的方法来实现这一切?

mir*_*eil 4

您使用的 InnoSetup 版本是什么?在我使用的版本(5.4.0a)中,已经有用于查找.NET根目录的常量。来自 InnoSetup 帮助:

{dotnet20} .NET Framework 2.0 版根目录。{dotnet20} 相当于 {dotnet2032},除非安装在 64 位模式下运行,在这种情况下,它相当于 {dotnet2064}。

如果尝试在不存在 .NET Framework 2.0 版的系统上扩展此常量,则会引发异常。

{dotnet2032} 32 位 .NET Framework 版本 2.0 根目录。

如果尝试在不存在 .NET Framework 2.0 版的系统上扩展此常量,则会引发异常。

{dotnet2064} 仅限 64 位 Windows:64 位 .NET Framework 版本 2.0 根目录。

如果尝试在不存在 .NET Framework 2.0 版的系统上扩展此常量,则会引发异常。

{dotnet40} .NET Framework 版本 4.0 根目录。{dotnet40} 相当于 {dotnet4032},除非安装在 64 位模式下运行,在这种情况下,它相当于 {dotnet4064}。

如果尝试在不存在 .NET Framework 4.0 版本的系统上扩展此常量,则会引发异常。

{dotnet4032} 32 位 .NET Framework 版本 4.0 根目录。

如果尝试在不存在 .NET Framework 4.0 版本的系统上扩展此常量,则会引发异常。

{dotnet4064} 仅限 64 位 Windows:64 位 .NET Framework 版本 4.0 根目录。

如果尝试在不存在 .NET Framework 4.0 版本的系统上扩展此常量,则会引发异常。