【问题标题】:Converting .NET App to x86 native code将 .NET 应用程序转换为 x86 本机代码
【发布时间】:2009-11-22 14:42:33
【问题描述】:

有一个完全用 C# 编写的针对 .NET Framework 2.0 的程序。 有没有一种方法可以以某种方式将托管的 EXE 编译(翻译)为本机的,这样它就可以与 .NET 无关?我知道可能有用于此目的的商业产品......但它们有点贵。

问题是我们要在没有安装 .NET Framework 的运行 Windows XP 的计算机上部署程序。还要求程序的大小不得超过 500Kb(最大 1Mb),因为它是从 Web 服务器下载的(现在大小为 255Kb)。这就是为什么我们无法将成熟的 .NET FX(甚至是简化版)附加到下载程序的文件中。

显然,这是一个可怕的软件工程错误,应该早点发现并避免,这样我们就可以改用 C++ 等原生技术。

我们目前已经尝试过 Novell 的 Mono - 一种适用于 Linux、MAC 和 Windows 的 .NET Framework 的开源实现。 Mono 由 C# 编译器、IDE、运行时 (CLR) 和类库程序集(如 System.dll 和 mscorlib.dll - 很像安装到 GAC 的 .NET 类库程序集)组成。 我们试图做的是找到 CLR 文件并将它们与我们的程序文件和一些程序集一起发送。这样,可以通过在用户计算机上运行“mono program.exe”(命令提示符)来调用该程序。 除了对最终用户 CLR 文件(mono.exe 和 mono.dll)的使用带来的不便之外,最终用户 CLR 文件(mono.exe 和 mono.dll)的总大小约为 2.5 Mb,远大于所需的 500 Kb 甚至 1 Mb。

因此,我们别无选择,只能通过编译器将 .NET 应用程序转换为本机应用程序,但问题仍然存在 - 我们应该使用什么编译器以及在哪里可以找到...

目前,我偶然发现了 Microsoft Research 的 Singularity OS 项目。它是一个开源研究操作系统,用托管代码(至少部分)编写。 Singularity OS 包括一个 Bartok 编译器,操作系统使用该编译器将托管程序转换为本机程序(x86 32 位)。应该注意的是,Bartok 不能将 .NET 2.0 的所有方面都翻译成本机代码,但其中大部分都是。但是我还没有学会如何使用奇点...

如果您能为我提供一些关于该问题的有用提示和建议、您自己使用 Singularity OS 和 Bartok 编译器的经验或解决我忽略的问题的其他方法以及解决方法,我将非常感谢您。

提前非常感谢您!

最后,使用 Mono 的完整 AOT 功能(根据 Callum Rogers 的建议),我设法生成了一个缺少 CLI 标头的 program.exe.dll。 所以在我看来它就像一个原生 dll。但是我不知道如何将该 dll 转换为 exe 或使其运行。 此外,这个 dll 似乎没有公开任何感兴趣的函数,例如 main 函数。

【问题讨论】:

  • 你是想做这个跨平台,还是只是删除对框架库的依赖?
  • 我只是想删除 .NET Framework 的依赖项,以便它可以在没有安装 .NET FX 的 Windows XP 上运行。
  • 这是一个很好的问题,我什至可以补充一点,Windows 7 附带安装了 .NET 3.5 SP1。可悲的是,但有时会在目标计算机上找到旧版操作系统,但安装了旧版(最好的情况)或没有(最坏的情况)安装了 .NET。

标签: c# .net mono clr native


【解决方案1】:

查看 Mono 项目中的 AOT(提前)编译。这会将您的托管项目编译为 不需要 JIT 的本机 exe 或 elf 可执行文件(取决于您的目标系统)。这是用于将单声道应用程序放到 iPhone 上的技术(不允许使用 JIT/框架),并且还具有更快的启动时间、更低的内存使用量以及使人们更难反编译您的代码的额外好处。你说你已经在使用 Mono,所以它应该是兼容的。

阅读at the mono-project.com websiteat Miguel de Icaza's blog(和iPhone info)。

请注意,您不能使用动态代码或通用接口,例如

interface IFoo<T> {
...
    void SomeMethod ();
}

你必须编译你使用的所有库的 DLL。

PS:确保为您的问题使用“完整”AOT。

【讨论】:

  • 感谢您的回答。看来我之前曾尝试过以这种方式编译示例 Hello World 程序集,但它失败了。可能是因为它 [Mono 的 Full AOT] 不兼容所有处理器(我有 Intel Core 2 Duo)。但是,我将彻底检查 Full AOT,因为我可能做错了什么
  • 完整的 AOT 至少适用于 x86 和 x86-64,以及 ARM 和 PPC 处理器。
  • 最后,我设法生成了一个缺少 CLI 标头的 program.exe.dll。所以它看起来像一个原生 dll。但是我不知道如何将该 dll 转换为 exe 或使其运行。此外,这个 dll 似乎没有公开任何感兴趣的功能,例如主功能
  • 即使在使用完整 AOT 时,Mono 的使用部分也会被编译成 .exe,使其膨胀超过 500k 或 1 Mb。所以实际上这将在没有 .NET 的情况下运行,但它不会满足给定的大小限制。我担心除了在目标计算机上重写或强制安装 .NET Framework 之外别无他法。
  • 有没有人真正在 Windows 上进行完全 AOT 成功?它适用于 x86 上的 Linux,但似乎在 Windows x86 上不受支持。
【解决方案2】:

2018 年更新

在 Build 2018 上,Microsoft 宣布了支持 Windows 桌面应用程序(Winform 和 WPF)的.Net Core 3.0 roadmap

2017 年更新

对于控制台应用程序,您可以使用 .net core Self-contained deployments (SCD)。即使对于一个 hello world 应用程序,您的包也将超过 50MB。不过,您仍然需要安装 VC 运行时。

更新

作为@jenix's comment,.NET Native 仅适用于 Windows 应用商店应用程序 (UWP)。在它宣布 3 年后,这仍然是事实,.net native for desktop 可能会被微软放弃。所以这个答案不再适用了。

========

微软在 Build 2014 上宣布了 .NET Native Preview

使用 .NET Native Developer Preview,应用程序将作为完全独立的本机编译代码部署在最终用户设备上,并且不会依赖于目标设备/机器上的 .NET Framework。因此,使用 .NET Native 的目标机器上不需要 .NET 框架。

Announcing .NET Native Preview
Microsoft .NET Native

【讨论】:

  • @JenixGuy 是的,2 年后。
【解决方案3】:

有一个名为 CrossNet 的项目解析 .Net 程序集并生成非托管 C++ 代码,可以在任何标准编译器中编译。

【讨论】:

  • 它是否解析程序集或代码?很抱歉问这个问题,但这个项目让我感到困惑。
【解决方案4】:

不是真正的 .NET 到本机转换的解决方案,但也许这会有所帮助:http://www.yoda.arachsys.com/csharp/faq/#framework.required

【讨论】:

  • 谢谢。我会注意列表中提到的程序。然而,据我所知,这些程序并不便宜,但可能会有很大的负载,即我们的可执行文件的大小将超过所需的数字。
  • 链接似乎已失效。
【解决方案5】:

不太确定除了煞费苦心地重写应用程序之外还有很多事情可以做。为了减轻已经很繁重的过程,您可以使用 Reflector 之类的东西(到 Microsoft C++ 中)来反汇编 .NET 应用程序,并将其用作启动的基础,然后将托管的 C++ 引用替换为本地引用。

【讨论】:

  • 我希望能找到一种方法来避免用 C++ 重写整个应用程序,因为这将花费大量时间,最重要的是调试时间。
猜你喜欢
  • 1970-01-01
  • 2018-03-30
  • 1970-01-01
  • 2010-09-07
  • 2015-03-17
  • 2014-08-07
  • 2014-06-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多