.net - 将 ILMerge 与 .NET 4 库结合使用

标签 .net dll assemblies c#-4.0 ilmerge

两个问题:

1) 基本 .NET 程序集未包含在 ILMerged 程序集中

从 .NET 3.5/Visual Studio 2008 升级到 .NET 4/Visual Studio 2010 后,我在构建后使用 ILMerge 时遇到问题。我有一个解决方案,其中有几个项目的目标框架设置为“.NET”框架4”。我使用以下 ILMerge 命令将各个项目 DLL 合并为单个 DLL:

if not $(ConfigurationName) == Debug
  if exist "C:\Program Files (x86)\Microsoft\ILMerge\ILMerge.exe"
    "C:\Program Files (x86)\Microsoft\ILMerge\ILMerge.exe"
      /lib:"C:\Windows\Microsoft.NET\Framework64\v4.0.30319"
      /lib:"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies"
      /keyfile:"$(SolutionDir)$(SolutionName).snk"
      /targetplatform:v4
      /out:"$(SolutionDir)bin\development\$(SolutionName).dll"
      "$(SolutionDir)Connection\$(OutDir)Connection.dll"
      ...other project DLLs...
      /xmldocs 

如果我不指定 .NET 4 框架目录的位置,则会从 ILMerge 收到“不允许未解析的程序集引用:系统”错误。如果我不指定 MSTest 目录的位置,则会收到“不允许未解析的程序集引用:Microsoft.VisualStudio.QualityTools.UnitTestFramework”错误。

上面的 ILMerge 命令起作用并生成一个 DLL。然而,当我在另一个 .NET 4 C# 项目中引用该 DLL 并尝试使用其中的代码时,我收到以下警告:

The primary reference "MyILMergedDLL" could not be resolved because it has an indirect dependency on the .NET Framework assembly "mscorlib, Version=4.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" which has a higher version "4.0.65535.65535" than the version "4.0.0.0" in the current target framework.

如果我随后删除 /targetplatform:v4 标志并尝试使用 MyILMergedDLL.dll,则会收到以下错误:

The type 'System.Xml.Serialization.IXmlSerializable' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.

看来我不必这样做。无论谁使用我的 MyILMergedDLL.dll API,都不必添加对其引用的任何库的引用。我该如何解决这个问题?

2) 仅在使用合并程序集时出现 TypeLoadException

编辑:除此之外,即使我确实在使用 MyILMergedDLL.dll 的消费者项目中添加了对 System.Xml 的引用,也利用了 MyILMergedDLL 中的一些代码.dll 给出了这个异常:

System.TypeLoadException: Could not load type 'System.Func`2' from assembly 'MyILMergedDLL, Version=1.0.1.1, Culture=neutral, PublicKeyToken=...'.

这是我的消费者项目中的代码;导致 TypeLoadException 的行是第二行:

var keys = new[] {"a", "b", "c"};
var row = new Row(keys);

引发 TypeLoadException 的特定 Row 构造函数是在 MyILMergedDLL 的公共(public)类中定义的,当我在引用单独的项目DLL,它工作得很好。只有当我在引用 IL 合并的 DLL 时使用此构造函数时,才会出现异常。我不知道发生了什么。

这是构造函数:

public Row(IEnumerable<string> keys) : base(keys) { }

它所引用的base具有以下代码:

foreach (string key in keys.Where(
    key => !string.IsNullOrEmpty(key)
))
{
    _dic.Add(key, string.Empty);
}

最佳答案

有一个very recent release解决 x64 问题。如果仍有问题,请直接与 Mike Barnett 联系(mbarnett at microsoft dot com)

<小时/>

附录。您的 /lib:"C:\Windows\Microsoft.NET\Framework64\v4.0.30319" 选项有一些非常非常错误的地方。最近 .NET 4.5 发布后,这给很多程序员带来了麻烦。该目录适合 .NET 4.0 引用程序集。它的内容被 4.5 程序集覆盖,您不能再使用它来定位 .NET 4.0 安装。你得到的运行时错误非常尴尬,程序无法再找到某些类型。通常在[Extension]属性上进行轰炸,有时在ICommand接口(interface)上进行轰炸。

这些类型以及其他一些类型已从一个程序集移至另一个程序集。使用正确的引用组件是一项严格的要求。您必须使用:

 /lib:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0"

进行调整以匹配您的特定计算机和目标框架版本。

关于.net - 将 ILMerge 与 .NET 4 库结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2961357/

相关文章:

.net - 与容器上RabbitMQ的连接问题

c# - 从内存中加载库/模块

windows - 在 Windows .rc 文件/dll 中使用字符串类型资源标识符

c# - 程序集绑定(bind)和重定向

c# - 将程序集作为进程运行

.NET WF4 : Should it be in the middle of everything?

c# - 如何在C#中获取URL路径

.net - 与所有网络计算机通信,无论 IP 地址如何

c++ - 从 Netbeans 中的应用程序项目生成 .dll

c# - 将 InMemory 编译程序集加载到当前域