.NET应用程序的链接器现状(也称为“请问,我可以有个链接器吗”2009版)

71
许多人可能熟悉Joel Spolsky最受欢迎的博客文章之一,Please Sir, May I Have a Linker,在这篇文章中,他呼吁找到一种方法来消除对.NET框架的依赖,以便开发和销售独立应用程序。
当时,Visual Studio开发团队的Jason Zander回答了他对这个话题的看法,认为这个话题有些无关紧要 - 修复运行时的安全问题(以及其他问题)是他们的主要关注点。总体而言,小的额外开销是值得的。
快进到2009年。现在有一些团队声称拥有C#链接器。(甚至Jason Zander自己也说过实现一个链接器不需要太多努力。)与.NET 1.0可爱的几十兆下载相比,我们现在有一个巨大的200-300 mb跨平台完整的.NET 3.5安装程序,其中包含x86、x64和ia64版本的.NET。微软减少运行时大小的建议包括:
  • 解压可再分发文件,删除不需要的目标平台,然后重新组合
  • 使用仅下载适用于您平台的库的Web引导程序
  • 使用Client Profile安装程序(2008年底推出),其中包含有限的库,并且仅适用于x86

更糟糕的是,据我所知(如果我错了,请纠正我),客户端框架甚至不会在Windows中注册为已安装.NET 3.5。这意味着如果计算机上安装了多个.NET 3.5客户端应用程序,则没有一个应用程序会看到彼此,并且运行时将一遍又一遍地重新安装!

我真的不知道微软在想什么。即使假设最坏的情况是针对一个目标平台(例如,x64),并且只需要包括那些库,您仍然需要在您的应用程序上增加高达60 mb的开销。即使是最著名的.NET应用程序之一Paint.NET,也因为庞大的.NET依赖关系而安装应用程序存在困难。如果他们在分发免费应用程序方面存在问题,那么其他国家怎么办?最终,他们必须制作一个引导程序,在安装自己的应用程序之前安装Microsoft Installer 3.1,.NET运行时引导程序和所有其他依赖库

那么怎么样呢?链接器。有没有好用的链接器,或者一个工具使得构建C#应用程序不需要用户安装庞大的.NET运行时?

更新:看起来有几个选择:

Mono:

.NET:

看起来Mono工具正在被使用,那.NET基础的工具呢?你有没有其他经验?或者我们只能等待微软将其推送给所有人使用3.5版本?我不敢想象等待.NET 4.0发布需要多长时间...


ILMerge有没有一个可以这样做的选项? - configurator
你说得太对了!!!从微软下载一个42M的网络摄像头驱动程序安装程序,结果还要下载.NET 3.0 - 在1.5 M ADSL上花费了超过10分钟...我只是想用个网络摄像头而已... - Dmitry Khalatov
如果微软没有如此拖延推广.NET 3.5版本,那就不会太糟糕了。如果他们像在.NET 2.0中所做的那样,在最新的服务包中包含它,大多数人就不必处理这些麻烦事了。 - Robert P
我尝试了Rustemsoft,但它无法实现。以下是Obfuscato底部的消息:“不建议链接.NET框架程序集。” - Nick
thinstall链接有误。应该是http://www.vmware.com/products/thinapp/。 - Simon
上次我使用thinstall时,它并不是一个链接器,而是一个打包工具,它只是将所有依赖项包装和压缩成看起来像EXE的文件。非常令人印象深刻且运行良好,但它并不是真正的链接器。 - DarinH
8个回答

50

关于Mono Linker的案例。

我不能谈论这里列出的其他软件,但作为Mono Linker的作者,我可以告诉你它是做什么的以及它不是做什么的。

Mono Linker只是一个托管链接器,因此根据定义,它接受程序集,并删除程序运行所不必要的部分。它不会将程序集合并在一起,也不会将其制作成本地程序。

虽然有一个名为ILMerge的Mono.Merge克隆版本,但它不完整,而且其作者没有维护它。要生成同时包含Mono运行时和程序集的本地程序,Mono提供了mkbundle工具

此外,由于它只是一个修改程序集的托管工具,如果您提供强名称的程序集,并且您没有私钥来重新签名它们,则无法运行这些程序集。

我写了几篇关于链接器的博客文章:

关于我们使用Linker的经验。Linker目前在Mono项目的两个部分中使用。它用于生成我们分发给人们嵌入我们的C#编译器Mono.CSharp.dll的程序集。您可以在PDC上观看Miguel的演示,其中描述了我们如何做到这一点。这非常简单,是Linker的基本用法,它是一个可定制的工具,编写自定义步骤非常容易。
Linker的更复杂的用途是我们创建Moonlight程序集的方式(Moonlight是我们的Silverlight实现)。程序集是桌面程序集的子集。因此,我们链接我们的桌面程序集以减小它们的大小,并使用自定义步骤将公共API转换为匹配Silverlight的API。
所以,Linker有一些相当粗糙的边缘,例如命令行界面或者你必须真正知道你在做什么,否则你可能会得到一些奇怪的程序集,但总体而言,它对我们来说非常有效。

2
链接器也被用于Monotouch,以解决苹果不允许在iPhone上安装(字节码)解释器和虚拟机的问题。 - Matthew Lock
6
马修:嗯,并不完全是。链接器在MonoTouch中用于减小最终应用程序的大小。越过JIT限制的是AOT编译器。 - Jb Evain

5

http://www.xenocode.com/

这是我们使用的工具。迄今为止,在一年或更长时间的有限使用后(可能在野外安装了500个左右),没有出现任何问题。

而且价格相当合理。他们有一些更昂贵的完全虚拟化软件(将您的应用程序与其他应用程序甚至操作系统捆绑在一起)。但我们不需要那么多。我们大约一年前的成本是400美元。我认为现在它的价格有点更高,但比Thinstall便宜得多。

而且他们有很棒的演示可以下载,例如IE 8。无需安装。


5

FWIW

长期以来,Mono已经拥有一个链接器

这里是如何使用mkbundle的示例


尽管链接器很好用,但它并不能完全解决这个特定的问题。Mono的链接器是托管型的,只能用于托管程序集。 - Jb Evain
sambo99,你有过相关经验吗? - Robert P

3

客户端配置文件会以特殊的方式在 Windows 上进行注册,因为您不希望仅具有客户端配置文件的计算机与拥有完整 .NET 3.5 的计算机混淆。

客户端配置文件:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\DotNetClient\v3.5\Install 

完整的 .NET 3.5:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5\Install

2
我曾经(用笔名“Mr Analogy”)在Joel的论坛上争论需要一个链接器一段时间,直到他写下那篇文章。链接器的过度使用似乎证明了我的担忧(可悲的是)。

http://www.thinstall.com/

根据我与一些人的交流,这个软件相当受欢迎,尽管最近我了解到它的许可证费用很高(每个应用程序需要2千美元/年的许可证)。他们似乎是针对IT公司而不是软件开发商。你在他们的网站上找不到价格信息,这表明(在我看来)它很昂贵。

2

链接有效。费用为$1249。我猜那是.NET税。很高兴我们已经转向基于Web的开发。 - Clay Nichols

2

我从未使用过它,但是我听说您可以使用.NET Reactor做类似的事情。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接