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

cla*_*aws 28 .net c# visual-studio-2008

我正在使用VS2008 C#.NET.

我在3个项目中创建了3个不同类的库.我写了一个使用这些库(dll)的应用程序.

正在发生的事情是每个项目都在编译成一个类库.所以,我有3个dll和1个exe.

相反,我希望以两种方式拥有这些:

  1. 只有类库汇编(dll),其中包含3个和1个exe.
  2. 只有一个EXE(里面的一切)::静态链接.

我怎么能这样做?我在VS2008中找不到静态链接的任何选项,也请提及命令行选项.

Jon*_*eet 43

ILMerge就是您追求的目标.

我不确定我是否真的称之为"静态链接" - 它只是将几个程序集合并为一个.(特别是,请不要觉得这是构建一个本机的,非托管的可执行文件.)但是,我认为这是你所追求的:)

更新:ILMerge现在是开源的,也可以作为NuGet包使用:

Install-Package ilmerge 
Run Code Online (Sandbox Code Playgroud)

  • @jonskeet我同意,我一直在搜索堆栈流,所有.netters认为ilmerge是静态链接.静态链接的目标(包括在c/c ++和编译时的Windows中)总是有一个独立的exe,绝对不需要其他任何东西......我最好重复一遍:除了有问题的exe之外绝对没有别的.没有一个其他dll需要或假设. (4认同)
  • @orip:我对静态链接的看法不止于此; .NET中的链接仍然有些动态 - 在执行时需要修复比静态链接的本机可执行文件更多的内容. (3认同)

Eri*_* J. 10

您可以将所有代码放入一个EXE项目中,使用第三方链接器(google .net静态链接器以获取多个选项),或者使用ILMerge,如此处所示.

第三方链接器通常也提供代码混淆,有些也可以静态链接.NET Framework.


Aid*_*lly 6

偶然发现了这个问题,并从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);
   }
};
Run Code Online (Sandbox Code Playgroud)


Jam*_* Ko 5

关于Jon Skeet的答案,ILRepack还是ILMerge的一个很好的开源替代品。您可以通过以下方式从NuGet安装它:

Install-Package ILRepack
Run Code Online (Sandbox Code Playgroud)