C# .NET创建的库的静态链接

35
我正在使用VS2008 C#.NET。 我在三个项目中创建了3个不同类别的库。我编写了一个使用这些库(dll)的应用程序。
现在的情况是每个项目都编译成一个类库。所以我有3个dll和1个exe。
相反,我希望有两种方式:
1. 只有包含这3个库和1个exe的类库程序集(dll)。
2. 只有一个exe(所有内容都在内部):静态链接。
如何做到这一点?我无法在VS2008中找到任何静态链接的选项,请同时提及命令行选项。
5个回答

49

ILMerge 是你需要的工具。

我不确定我是否应该将其称为“静态链接” - 它只是将几个程序集合并为一个。 (请不要误解这是构建本地的非托管可执行文件。)但是,我认为这就是你想要的 :)

更新:ILMerge 现在开源了,并且也可以作为NuGet包使用:

Install-Package ilmerge 

3
我对静态链接的看法不仅如此;在.NET中进行链接仍然有一定的动态性 - 在执行时需要进行更多的修复工作,而与静态链接的本地可执行文件相比要更复杂。 - Jon Skeet
4
我同意,我在整个Stackflow上搜索了很久,所有的.net程序员都认为ilmerge是静态链接。静态链接的目标(包括在c / c ++和编译时的Windows时代)始终是要有一个完全独立的exe,除了所需的exe文件外不需要任何其他内容......我最好再重复一遍:除了问题中的exe文件之外,没有任何其他dll被需要或假定。 - PandaWood
你能否使用ILMerge将.NET Fx DLL链接进来,使.exe文件独立运行? - kdmurray
@kdmurray:不是的。ILMerge只创建一个单一的.NET程序集 - 它仍然需要CLR等来运行。 - Jon Skeet
1
@kdmurray:通过我的答案,您可以创建一个单一的.NET程序集,它不依赖于.NET运行时。 - Eric J.
显示剩余2条评论

10
你可以将所有代码放入一个EXE项目中,使用第三方链接器(谷歌搜索“.net静态链接器”以获取多种选项),或像这里所示一样使用ILMerge。
第三方链接器通常还提供代码混淆,有些还可以静态链接.NET Framework。

7

发现了这个问题,并从 Jeffrey Richter (http://blogs.msdn.com/b/microsoft_press/archive/2010/02/03/jeffrey-richter-excerpt-2-from-clr-via-c-third-edition.aspx) 中找到了另一种实现这些目标的方法:您可以将 .dll 嵌入到可执行文件中作为资源,然后重载 AssemblyResolve 事件以通过该方式加载程序集。引用来自链接的代码:

AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => {
   String resourceName = "AssemblyLoadingAndReflection." +
      new AssemblyName(args.Name).Name + ".dll";
   using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)) {
      Byte[] assemblyData = new Byte[stream.Length];
      stream.Read(assemblyData, 0, assemblyData.Length);
      return Assembly.Load(assemblyData);
   }
};

链接已失效。是否支持外部 DLL? - beppe9000

6

关于Jon Skeet的答案,ILRepack也是一个不错的开源替代ILMerge的选择。您可以通过NuGet安装它:

Install-Package ILRepack

2
你还应该看看ILMERGE-GUI。它是ILMerge的GUI封装器。

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