假设我想在没有 .NET 框架的机器上运行 .NET 应用程序;有没有办法将应用程序编译为本机代码?
16 回答
Microsoft 有一篇文章描述了如何将MSIL 编译为本机代码
您可以使用Ngen。
本机映像生成器 (Ngen.exe) 是一种提高托管应用程序性能的工具。Ngen.exe 创建本机映像,这些文件包含已编译的特定于处理器的机器代码,并将它们安装到本地计算机上的本机映像缓存中。运行时可以使用缓存中的本机映像,而不是使用即时 (JIT) 编译器来编译原始程序集。
不幸的是,您仍然需要框架中的库才能运行您的程序。我所知道的 MS .Net 框架 SDK 没有任何功能可以让您将所有必需的文件编译成单个可执行文件
正如这里的其他一些答案所提到的,您可以使用.NET Native工具将您的应用程序编译为本机机器代码。然而,与那些答案不同,我将解释如何做到这一点。
脚步:
安装dotnet CLI (命令行界面)工具,它是新的 .NET Core 工具链的一部分。我们将使用它来编译我们的应用程序;你可以在这里找到一篇关于它的好文章。
打开 shell 提示符并
cd
进入您的应用程序目录。输入这个:
dotnet compile --native
就是这样!完成后,您的应用程序将被编译为单个二进制文件,如下所示:
它将是一个独立的可执行文件;不包含 PDB、程序集或配置文件(万岁!)。
或者,如果你想要一个更快的程序,你可以运行这个:
dotnet compile --native --cpp
这将使用 C++ 代码生成器(而不是 RyuJIT)优化您的程序,因此您的应用程序针对 AOT 场景更加优化。
您可以在 dotnet CLI GitHub 存储库中找到更多信息。
RemoteSoft 制作了一种工具,可将 .NET 应用程序编译成无需安装 .NET 即可运行的包。我没有任何经验:
微软已经宣布了它的.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
您可以从此处下载适用于 VS2013 的 Microsoft .NET Native:http: //msdn.microsoft.com/en-US/vstudio/dotnetnative
是的,使用Ngen,本机图像生成器。但是,您需要注意以下几点:
- 您仍然需要 CLR 来运行您的可执行文件。
- CLR 不会根据它运行的环境(例如 486 与 586 与 686 等)动态优化您的程序集
总而言之,只有在需要减少应用程序的启动时间时才值得使用 Ngen。
你可以!但是,您仅限于 .NET 1.1(没有适合您的泛型): Mono Ahead-Of-Time 编译 (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,但它确实支持各种动态场景。代码作者需要利用 运行时指令向 .NET Native 编译器提供他们希望支持的动态场景的提示。
您可以使用 ngen.exe 生成本机映像,但您仍然需要分发原始的非本机代码,并且它仍然需要在目标计算机上安装框架。
这并不能解决你的问题,真的。
2019 答案:使用dotnet/corert。它可以将 .NET Core 项目编译为独立.exe
文件。没有依赖项(除了系统库,如kernel32.dll
)。我敢打赌,这正是 OP 所需要的。
从它的 GitHub 主页:
CoreRT 编译器可以将托管的 .NET Core 应用程序编译为易于部署的本机(特定于体系结构的)单文件可执行文件。它还可以生成独立的动态或静态库,供以其他编程语言编写的应用程序使用。
从 2021 年起,您可以使用 [NativeAOT](.NET 7 计划的一部分)(https://github.com/dotnet/runtimelab/tree/feature/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,它可能会给您带来更好的结果。
.NET 的本质是能够安装已编译为 MSIL 的应用程序,然后通过 JIT 或 Ngen,将 MSIL 编译为本机代码并在本地存储在缓存中。它从未打算生成可以独立于 .NET 框架运行的真正本机 .exe。
也许有一些黑客可以做到这一点,但对我来说听起来并不安全。需要框架的动态太多了,比如:动态程序集加载、MSIL代码生成等。
编译成 Native 的主要原因是为了保护您的代码,否则编译的 MSIL 就像在客户端机器中部署源代码一样。
NGEN编译成native但也需要部署IL代码,这个目的只是为了减少启动时间,但也没有用。
CoreRt 是 alpha 版本,仅适用于简单的 helloworld 类型的应用程序。
.Net Core 编译成单个可执行文件,但它也不是本机 exe,这只是 IL 代码的压缩文件,它会在运行时将代码解压缩到 temp 文件夹中。
我来自 Microsoft 的简单问题是,如果 RyuJIT 可以即时将 IL 编译成本机,那么为什么不可以提前编译相同的 IL (AOT)。
看起来像 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工具