【发布时间】:2010-09-07 22:11:28
【问题描述】:
假设我想在 .NET 框架不可用的机器上运行 .NET 应用程序;有什么办法可以将应用程序编译成原生代码?
【问题讨论】:
标签: .net compilation native-code
假设我想在 .NET 框架不可用的机器上运行 .NET 应用程序;有什么办法可以将应用程序编译成原生代码?
【问题讨论】:
标签: .net compilation native-code
Microsoft 有一篇文章描述了如何Compile MSIL to Native Code
您可以使用Ngen。
本机图像生成器 (Ngen.exe) 是一种提高 托管应用程序的性能。 Ngen.exe 创建本机映像,它 是包含编译的文件 特定于处理器的机器代码,以及 将它们安装到本机映像中 缓存在本地计算机上。这 运行时可以使用来自 使用即时缓存代替 (JIT) 编译器编译原始 组装。
不幸的是,您仍然需要框架中的库才能运行您的程序。我所知道的 MS .Net 框架 SDK 没有任何功能可以让您将所有必需的文件编译成单个可执行文件
【讨论】:
正如这里的一些其他答案所提到的,您可以使用 .NET Native 工具将您的应用程序编译为本机机器代码。然而,与这些答案不同的是,我将解释如何做到这一点。
步骤:
安装 dotnet CLI(命令行界面)工具,它是新的 .NET Core 工具链的一部分。我们将使用它来编译我们的应用程序;你可以找到一篇关于它的好文章here.
打开一个 shell 提示符并 cd 进入您的应用目录。
输入这个:
dotnet compile --native
就是这样!完成后,您的应用将被编译为单个二进制文件,如下所示:
它将是一个独立的可执行文件;不包含 PDB、程序集或配置文件(万岁!)。
或者,如果你想要一个更快的程序,你可以运行这个:
dotnet compile --native --cpp
这将使用 C++ 代码生成器(而不是 RyuJIT)优化您的程序,因此您的应用针对 AOT 场景更加优化。
您可以在 dotnet CLI GitHub repo 找到更多信息。
【讨论】:
RemoteSoft 制作了一个工具,可以将 .NET 应用程序编译成可以在不安装 .NET 的情况下运行的包。我没有任何经验:
【讨论】:
Microsoft 已宣布其 .NET Native Preview 将允许在不安装框架的情况下运行 .NET 应用程序。
看一看:http://blogs.msdn.com/b/dotnet/archive/2014/04/02/announcing-net-native-preview.aspx
常见问题解答:http://msdn.microsoft.com/en-US/vstudio/dn642499.aspx
您可以从这里下载 Microsoft .NET Native for VS2013:http://msdn.microsoft.com/en-US/vstudio/dotnetnative
【讨论】:
是的,使用原生图像生成器 Ngen。但是,您需要注意一些事项:
总而言之,只有在您需要减少应用程序的启动时间时才值得使用 Ngen。
【讨论】:
你可以!但是,您仅限于 .NET 1.1(没有适合您的泛型): Mono Ahead-Of-Time compilation (AOT)
然而,这意味着编译是真正原生的,因此您将无法再部署一个单一的字节码程序集,您需要每个平台一个。
最初设计它是因为没有适用于 iPhone 的 .NET 或 Mono,所以这就是他们制作 MonoTouch 的方式。
【讨论】:
您可以使用称为 .NET Native 的新预编译技术来做到这一点。在这里查看:http://msdn.microsoft.com/en-US/vstudio/dotnetnative
目前它仅适用于 Windows 应用商店应用。它执行单个组件链接。因此 .NET Framework 库静态链接到您的应用程序中。一切都编译为本机,不再部署 IL 程序集。应用不针对 CLR 运行,而是针对称为托管运行时 (Mrt.dll) 的精简优化运行时
如上所述,NGEN 使用混合编译模型并依赖 IL 和 JIT 处理动态场景。 .NET Native 不使用 JIT,但它支持各种动态场景。代码作者需要利用Runtime Directives 向.NET Native 编译器提供他们希望支持的动态场景的提示。
【讨论】:
您可以使用 ngen.exe 生成原生镜像但您仍然需要分发原始的非原生代码,并且仍然需要安装框架在目标机器上。
这并不能解决你的问题,真的。
【讨论】:
2019 答案:使用dotnet/corert。它可以将 .NET Core 项目编译成独立的 .exe 文件。没有依赖项(kernel32.dll 等系统库除外)。我敢打赌这正是 OP 所需要的。
来自其 GitHub 主页:
CoreRT 编译器可以将托管的 .NET Core 应用程序编译为易于部署的本机(特定于架构)单文件可执行文件。它还可以生成独立的动态或静态库,供以其他编程语言编写的应用程序使用。
【讨论】:
.NET 的本质是能够安装已编译为 MSIL 的应用程序,然后通过 JIT 或 Ngen,将 MSIL 编译为本机代码并存储在本地缓存中。它从来没有打算生成一个可以独立于 .NET 框架运行的真正的本机 .exe。
也许有一些黑客可以做到这一点,但对我来说听起来并不安全。需要框架的动态太多了,比如:动态程序集加载、MSIL代码生成等。
【讨论】:
从 2021 年起,您可以使用 NativeAOT(以前称为 (CoreRT)[https://github.com/dotnet/corert])。
这项技术有点限制,因为你不能过多地依赖反射,但总的来说你可以用它编译应用程序的范围。 Web 应用、WinForms 应用、控制台应用。
您需要做的就是添加到您的项目文件中
<ItemGroup>
<PackageReference Include="Microsoft.DotNet.ILCompiler" Version="7.0.0-*" />
</ItemGroup>
并像这样将dotnet-experimental Nuget 提要添加到您的 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="dotnet-experimental" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-experimental/nuget/v3/index.json" />
</packageSources>
</configuration>
您可以针对 .NET 5 应用程序,但随着 .NET 6 中的 ILTrim 改进,越来越多的代码将准备好进行本机编译。
对于简单的应用程序,您可以尝试使用BFlat,这可能会给您带来更好的结果。
【讨论】:
编译成Native的主要原因是为了保护你的代码,否则编译的MSIL就像在客户端机器上部署源代码一样。
NGEN编译成native但也需要部署IL代码,这个目的只是为了减少启动时间,但也没有用。
CoreRt 是 alpha 版本,仅适用于简单的 helloworld 类型的应用程序。
.Net Core 编译成单个可执行文件,但它也不是原生 exe,这只是 IL 代码的压缩文件,它会在运行时将代码解压缩到 temp 文件夹中。
我的来自 Microsoft 的简单问题是,如果 RyuJIT 可以即时将 IL 编译为本机,那么为什么不可以提前 (AOT) 编译相同的 IL。
【讨论】:
看起来像 net core RT 可行的解决方案; 很快所有应用程序都将转到 .net 核心; https://www.codeproject.com/Articles/5262251/Generate-Native-Executable-from-NET-Core-3-1-Proje?msg=5753507#xx5753507xx https://docs.microsoft.com/en-us/archive/msdn-magazine/2018/november/net-core-publishing-options-with-net-core
未测试可能与旧的 win .net sdk 可能类似。
【讨论】:
试试这个 (http://www.dotnetnative.online/) 将 .net 编译的 exe 编译成本机 exe,我试过这个,它新但很好。
【讨论】:
我认为这是不可能的。您还需要分发 .NET FW。如果您想将 .NET 应用程序编译为本机代码,请使用 NGen tool
【讨论】: