ILMerge和.NET 4.0存在严重问题

10
我实在想不出来如何使我的.NET 4应用程序与ILMerge正确合并。即使设置了/targetplatform、/lib、/ndebug,并添加了自定义的ILMerge.exe.config文件,输出文件也无法正常工作(它似乎无法“找到”已合并的库)。
我已经尝试过thisthis但都没有成功。如果不使用配置文件,甚至无法构建,但是使用配置文件时也无法正常工作。没有配置文件,我始终会收到错误消息“不允许未解决的程序集引用:PresentationFramework”。
这是我当前正在使用的ILMerge命令的状态,作为后期生成事件:
ilmerge.exe /out:C:\Users\Logan\Development\Projects\OrangeNote\OrangeNote\bin\Release\OrangeNote.exe 
  /ndebug /targetplatform:v4,C:\Windows\Microsoft.NET\Framework\v4.0.30319 
  /lib:"C:\Windows\Microsoft.NET\Framework\v4.0.30319" 
  /lib:"C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies" 
  "C:\Users\Logan\Development\Projects\OrangeNote\OrangeNote\obj\Release\OrangeNote.exe" 
  "C:\Users\Logan\Development\Projects\OrangeNote\OrangeNote\..\..\..\Libraries\Lucene.Net\src\Lucene.Net\bin\Release\Lucene.Net.dll" 
  "C:\Users\Logan\Development\Projects\OrangeNote\OrangeNote\..\..\..\Libraries\Ookii.Dialogs\src\Ookii.Dialogs.Wpf\bin\Release\Ookii.Dialogs.Wpf.dll" 
  "C:\Users\Logan\Development\Projects\OrangeNote\OrangeNote\..\..\..\Libraries\SharpZipLib\bin\ICSharpCode.SharpZipLib.dll" 
  "C:\Users\Logan\Documents\Visual Studio 2010\Projects\HumanInterfaceProject\HumanInterfaceProject\bin\Release\HipLib.dll"

您对我做错的事有何想法吗?


4
我只需要简单地添加以下内容来解决这个问题:/lib:"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\WPF" - Daniel B
5个回答

8

我见过一种将.dll文件合并到WPF中的建议是将dll作为嵌入式资源添加到项目中,然后通过编程方式将dll加载到程序集中。

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);

   }

};

see: http://blogs.msdn.com/b/microsoft_press/archive/2010/02/03/jeffrey-richter-excerpt-2-from-clr-via-c-third-edition.aspx


太好了,谢谢!甚至ILMerge的作者Mike Barnett也认为这是一个解决方案,所以对我来说已经足够好了。 :) - devios1
1
请注意,这将使得无法对dll文件进行Ngen。 - Peter
这对于类库是不起作用的:向下滚动以查看答案链接中关于此事的Jeffrey Ritcher评论,评论日期为2010年7月28日下午3:14。 - Dean
如果您不想手动嵌入所有DLL,可以在这里查看:https://dev59.com/cnNA5IYBdhLWcg3wSrqa#4995039 - Ludovic Feltz

8

这似乎有一个损坏的链接。但是现在Costura作为Fody的附加组件已经成为NuGet包。http://www.nuget.org/packages/Costura.Fody/ - corylulu

7
我给ILMerge的作者Mike Barnett发送了电子邮件,他解释说它根本不适用于WPF应用程序,但很遗憾,当我告诉他我已经让它可以在我的WPF 3.5应用程序中使用时,他感到惊讶。由于它并没有得到真正的支持,所以现在我将其视为无法使用,并等待其他替代方案的出现。
另外,我尝试过来自Eziriz的.NET Reactor,它的效果非常好,但价格是180美元,对于我的业余项目来说,我还不愿意花这个钱。但这比Red Gate提供的其他商业替代方案要便宜得多,所以我想提一下。
更新:Mike Barnett现在认为接受的答案是最佳解决方案。据他所说,如果他知道这是可能的,他第一次写ILMerge时就不会这样做。

好的信息。感谢反馈。 - Simon P Stevens
作为 .NET Reactor 的商业用户,我必须提到我总是无法合并程序集。它似乎已经成功合并了,但当你运行合并后的应用程序时,你会遇到奇怪的活动。 - Ying
当我只使用嵌入(而不是合并)且没有任何复杂的安全措施时,它似乎运行得非常好。我对我的程序进行了一次测试,一切都完好无损。 - devios1

6
虽然ILMerge不能更新WPF资源字符串,但是它可以通过将参考程序集目录而不是运行时目录传递给/targetplatform来合并具有WPF引用的程序集,例如:/targetplatform:v4,"C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\Profile\Client"(适用于.NET 4.0客户端框架)。 我使用这种方法来合并Rx的System.Reactive.dll,该dll引用了Dispatcher,但实际上没有任何WPF资源。

3
我注意到你们的一个程序集叫做“dialogs.wpf”。目前,ILMerge不能正确地合并带有WPF资源的程序集。关于这个问题,网络上没有太多信息,但是这篇论坛帖子提到了可能的解决方案,这个问题的回答中也提到了几种可能性,但是得票最高的建议只是购买商业替代品——我不知道这对你是否可行。这里有一次讨论解释了为什么它不起作用,还有一个建议在xaml中更改资源引用可能有助于解决问题

我不相信那个程序集中实际上有任何WPF资源,但我并不完全确定(回家后会检查)。我的主要可执行文件肯定有,但这似乎不是问题所在。不过我会进一步调查此事。感谢您的回复。 - devios1

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