如何将.NET应用程序编译为本机代码?

95

假设我想在一台没有.NET框架的机器上运行.NET应用程序,是否有办法将应用程序编译为本机代码?

16个回答

45

Microsoft有一篇文章介绍了如何将MSIL编译为本地代码Compile MSIL to Native Code

你可以使用Ngen.

本机映像生成器(Ngen.exe)是一个提高托管应用程序性能的工具。Ngen.exe创建本机映像,这些文件包含已编译的处理器特定机器代码,并将它们安装到本地计算机上的本机映像缓存中。运行时可以使用缓存中的本机映像,而不是使用即时(JIT)编译器编译原始程序集。

不幸的是,你仍然需要框架的库才能运行程序。据我所知,MS .Net框架SDK中没有功能可以将所有所需文件编译为单个可执行文件。


1
除了性能方面,我找不到使用它的其他原因。CLR 代码仍然可以像以前一样阅读,并且您仍然需要 .NET。很失望微软没有提供一个工具来解决我认为是一个大问题的问题(任何人都可以查看您的高级代码)。 - MasterMastic
我不同意Espo的观点。因为灰色文本中提到了“Runtime”,这意味着CLR和随之而来的.NET Framework,正如Chris所指出的那样。然而,NGen的观点是正确的。问题是,在不使用CLR/Runtime/.NET Framework的情况下,它们都是相同的。 - Jasmine
2
是时候兴奋了,看起来 .net 框架终于要得到本地编译器了 - http://msdn.microsoft.com/en-US/vstudio/dotnetnative - ferventcoder
将您的.NET可执行文件及其依赖树中的所有内容合并,然后进行Ngen,如果您想要一个独立于.NET的可执行文件。 - user11462042

33

正如其他答案所提到的,您可以使用.NET Native工具将应用程序编译为本机机器代码。然而,与那些答案不同的是,我将解释如何做到这一点。

步骤:

  1. 安装dotnet CLI(命令行界面)工具,它是新的.NET Core工具链的一部分。我们将使用它来编译我们的应用程序;你可以在这里找到一个好的文章:这里。

  2. 打开shell提示符并cd到您的应用程序目录。

  3. 输入以下内容:

    dotnet compile --native
    

就这样!完成后,您的应用程序将被编译成一个单独的二进制文件,如下所示:

原生编译的.NET Core可执行文件

它将是一个独立的可执行文件;不包括PDB、程序集或配置文件(太好了!)。


或者,如果您想要一个更快的程序,您可以运行以下命令:

dotnet compile --native --cpp

使用C++代码生成器(而不是RyuJIT)来优化您的程序,以便您的应用在AOT场景下更加优化。

您可以在dotnet CLI GitHub库上找到更多信息。


注意:此功能仅支持使用.NET Core构建的项目。(虽然加1) - Mahmoud Al-Qudsi
1
你忘记了一个非常重要的细节,那就是.NET Native需要Windows 10操作系统。 - Elmue
1
看起来似乎不能在 .NET Core 3.1 上工作,有任何更新吗? - user1005462
1
当我尝试使用dotnet compile时,发现它不可用。也许可以尝试使用dotnet build --self-contained作为替代。 - Bolpat

24

RemoteSoft制作了一个工具,可以将.NET应用程序编译为一个可在没有安装.NET的情况下运行的包。我对它没有任何经验:

RemoteSoft Salamander


6
我听说过的唯一一个不需要框架就可以完成它的工具。当然,它要价1249美元。 - Slapout
4
在过去几年里,我尝试过几次获取有关该产品价格或演示的信息或评估,但他们从未回复我的电子邮件,因此我认为他们的产品可能有些可疑。请你帮我将其翻译成中文。 - codenheim

20

20

我已经测试了几个工具,目前唯一支持.NET 3.5且拥有出色虚拟化功能的是XenocodePostbuild

使用ngen仍然需要安装.NET Framework,但使用这样的工具,所有托管代码都被编译成本地代码,因此您可以将其部署到没有框架存在的机器上。


11

是的,可以使用本机图像生成器Ngen。 但是,有一些事情需要注意:

  • 您仍然需要CLR来运行可执行文件。
  • CLR不会根据运行环境(例如486 vs. 586 vs. 686等)动态优化您的程序集。

总的来说,只有在需要减少应用程序启动时间时才使用Ngen会更加值得。


9
您可以使用.NET 7的一部分——NativeAOT(以前是CoreRT)。

该技术在某种程度上有一定限制,因为您不能过度依赖反射,但总体上您可以使用它来编译各种应用程序,如Web应用程序、WinForms应用程序和控制台应用程序。

截至.NET 7预览版5,您只需添加以下代码

<PropertyGroup>
   <PublishAot>true</PublishAot>
</PropertyGroup>

如果您想使用 NativeAOT 的每日构建版本,需要在您的项目文件中添加以下行。
<ItemGroup>
  <PackageReference Include="Microsoft.DotNet.ILCompiler" Version="8.0.0-*" />
</ItemGroup>

并将 dotnet8 Nuget feed 添加到您的 nuget.config 文件中,就像这样:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
 <packageSources>
    <!--To inherit the global NuGet package sources remove the <clear/> line below -->
    <clear />
    <add key="dotnet-public" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json" />
    <add key="dotnet8" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8/nuget/v3/index.json" />
 </packageSources>
</configuration>

您可以针对.NET 6应用程序进行定位,而在.NET 6中的ILTrim改进下,越来越多的代码都将准备好进行本机编译。

对于简单的应用程序,您可以尝试使用BFlat,这可能会给您带来更好的结果。


1
ILCompiler现在可以在NuGet Feed中获取:https://www.nuget.org/packages/Microsoft.DotNet.ILCompiler/ - M.Hassan

9

你可以这样做!但是你只能使用.NET 1.1(没有泛型可用):Mono Ahead-Of-Time编译(AOT)

然而,这意味着编译成本地代码,所以你将不能再部署一个单一的字节码程序集,而是需要为每个平台都准备一个程序集。

最初设计此技术是因为iPhone没有.NET或Mono,所以他们开发出了MonoTouch。


6
你可以使用名为.NET Native的新预编译技术进行操作。请在此处查看:http://msdn.microsoft.com/en-US/vstudio/dotnetnative
目前仅适用于Windows Store应用程序。 它执行单个组件连接。 因此,.NET Framework库静态链接到您的应用程序中。 所有内容都被编译为本机代码,IL程序集不再部署。 应用程序不运行CLR,而是运行一个精简优化的运行时环境(Mrt.dll)。
如上所述,NGEN采用混合编译模型,并依赖于IL和JIT进行动态场景。 .NET Native不使用JIT,但它支持各种动态场景。 代码作者需要利用运行时指令为.NET Native编译器提供关于他们希望支持的动态场景的提示。

1
+1 - 我已经等了多年才等到这一天。我希望世界对“虚拟机”的热衷能够早日结束,但无论如何,这一天终于到来了。我预计我们将会看到本地编译的复苏。正如你所说,目前它只适用于Windows商店应用程序,但桌面市场要求同等待遇只是时间问题。 - codenheim

5
你可以使用ngen.exe生成本地映像,但你仍然需要分发原始的非本地代码,并且目标计算机上仍然需要安装框架。这并不能真正解决你的问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接