有一个完全用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 AOT功能(在Callum Rogers的建议下)我设法生成了缺少CLI标头的program.exe.dll。 所以它看起来就像一个原生的dll。但是,我无法弄清楚如何将该DLL转换为exe或使其运行。 此dll似乎也没有暴露任何感兴趣的函数,如main函数。
答案 0 :(得分:10)
从Mono项目中查看AOT(Ahead Of Time)编译。这会将您的托管项目编译为本机exe或elf可执行文件(取决于您定位的系统)不需要JIT 。这是用于将单声道应用程序添加到iPhone(不允许使用JIT / Framework)的技术,并且还具有更快的启动时间,更低的内存使用率以及使人们更难以反编译代码的额外好处。你说你已经在使用Mono了,所以它应该是兼容的。
了解at the mono-project.com website和at Miguel de Icaza's blog(以及iPhone info)。
请注意,您不能使用动态代码或通用接口,例如
interface IFoo<T> {
...
void SomeMethod ();
}
您必须编译所有库的DLL。
PS:确保为您的问题使用“完整”AOT。
答案 1 :(得分:9)
2018年更新
在Build 2018,微软宣布.Net Core 3.0 roadmap支持Windows桌面应用程序(Winform&amp; WPF)
2017年更新
对于控制台应用,您可以使用.net core Self-contained deployments (SCD)。即使是一个hello world应用程序,你的软件包也会达到50MB +。您仍然需要安装VC运行时。
更新
作为@jenix's comment,.NET Native仅适用于Windows应用商店应用(UWP)。经过3年的公告,这仍然是正确的,桌面的.net native可能会被microsoft删除。所以这个答案不再适用了。
======
Microsoft在Build 2014上发布了.NET Native Preview
使用.NET Native Developer Preview,应用程序将作为完全独立的本机编译代码部署在最终用户设备上,并且不会依赖目标设备/计算机上的.NET Framework。因此,使用.NET Native的目标计算机上不需要.NET框架。
答案 2 :(得分:3)
有一个名为CrossNet的项目解析.Net程序集并生成非托管C ++代码,可以在任何标准编译器中编译。
答案 3 :(得分:1)
不是真正的.NET到本机转换的解决方案,但这可能会有所帮助:http://www.yoda.arachsys.com/csharp/faq/#framework.required
答案 4 :(得分:0)
不太确定除了精心重写应用程序之外,还有很多事情可做。为了简化已经加载的过程,您可以使用Reflector(进入Microsoft C ++)之类的东西来反汇编.NET应用程序,并将其作为基础来启动,并将托管C ++引用替换为本机版本。