将.NET App转换为x86本机代码

有一个完全用C#编写的程序,它以.NET Framework 2.0为目标。 有没有办法我可以以某种方式编译(翻译)托管EXE到本机的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)的这种使用带来的不便之外,总共大约2.5 Mb,远远大于所需的500 Kb甚至1 Mb。

所以,我们没有其他选择,只能通过编译器将我们的.NET应用程序转换为本机应用程序,但问题仍然存在 – 我们应该使用什么编译器以及我们在哪里可以找到…

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

如果你能提供一些有关问题的有用提示和建议,你自己使用Singularity OS和Bartok Compiler的经验,或者我忽略了解决问题的其他方法以及解决问题的方法,我将非常感谢你。

非常感谢你提前!

最后,使用Mono的Full AOTfunction(在Callum Rogers的建议下)我设法生成了缺少CLI头的program.exe.dll。 所以它看起来像一个原生的DLL。 但是,我无法弄清楚如何将该DLL转换为exe或使其运行。 此dll似乎也没有暴露任何感兴趣的function,如主要function。

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

在mono-project.com网站和Miguel de Icaza的博客 (和iPhone信息 )上阅读相关内容。

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

interface IFoo { ... void SomeMethod (); } 

并且您将必须编译您使用的所有库的DLL。

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

2018年更新

在Build 2018,微软宣布支持Windows桌面应用程序的WinNet 3.0路线图 (Winform和WPF)

2017年更新

对于控制台应用程序,您可以使用.net核心自包含部署(SCD) 。 即使是一个hello world应用程序,你的软件包也会达到50MB +。 您仍然需要安装VC运行时。

更新

作为@ jenix的评论 ,.NET Native仅适用于Windowsapp store应用(UWP)。 经过3年的宣布,这仍然是正确的,桌面的.net native可能会被microsoft删除。 所以这个答案不再适用了。

========

Microsoft在Build 2014上发布了.NET Native Preview

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

宣布.NET原生预览
Microsoft .NET Native

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

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

不太确定除了精心重写应用程序之外你还能做很多事情。 为了简化已经加重的过程,您可以使用Reflector(进入Microsoft C ++)之类的东西来反汇编.NET应用程序,并使用它作为基础来启动并仅使用本机C ++引用替换托管C ++引用。