首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在.NET 4库中使用ILMerge

在.NET 4库中使用ILMerge
EN

Stack Overflow用户
提问于 2010-06-03 04:29:46
回答 6查看 58.5K关注 0票数 51

两个问题:

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

在从.NET 3.5/Visual Studio2008升级到.NET 4/Visual Studio2010之后,我在后期构建中使用ILMerge时遇到了问题。我有一个包含多个项目的解决方案,这些项目的目标框架设置为".NET Framework4“。我使用以下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的“不允许未解析的程序集引用:系统”错误。如果不指定程序集目录的位置,则会出现“不允许未解析的程序集引用: Microsoft.VisualStudio.QualityTools.UnitTestFramework”MSTest“错误。

上面的ILMerge命令运行并生成一个动态链接库。但是,当我在另一个.NET 4 C#项目中引用该DLL并尝试在其中使用代码时,我收到以下警告:

无法解析主引用"MyILMergedDLL“,因为它间接依赖于.NET框架程序集"mscorlib,Version=4.0,Culture=neutral,PublicKeyToken=b77a5c561934e089”,该程序集的版本"4.0.65535.65535“高于当前目标框架中的版本"4.0.0.0”。

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

类型“System.Xml.Serialization.IXmlSerializable”是在未被引用的程序集中定义的。必须添加对程序集'System.Xml,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089‘的引用。

看起来我不应该这么做。无论谁使用我的MyILMergedDLL.dll应用程序接口,都不必添加对它所引用的任何库的引用。我怎么才能避免这个问题呢?

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

编辑:除此之外,即使我在使用MyILMergedDLL.dll的消费者项目中添加了对System.Xml的引用,使用MyILMergedDLL.dll中的一些代码也会产生此异常:

System.TypeLoadException:未能从程序集“System.Func`2,MyILMergedDLL,Version=1.0.1.1,Culture=neutral,PublicKeyToken=...”加载类型“”。“”

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

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

抛出TypeLoadException的特定Row构造函数是在MyILMergedDLL的公共类中定义的,当我在引用各个项目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);
}
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2010-06-03 07:32:12

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

附录。你的/lib:"C:\Windows\Microsoft.NET\Framework64\v4.0.30319"选项有一些非常非常错误的地方。最近,在.NET 4.5发布后,这给很多程序员带来了麻烦。该目录是,而不是.NET 4.0参考程序集的正确目录。它的内容被4.5版的程序集覆盖,您不能再使用它来针对.NET 4.0安装。你得到的运行时错误是非常尴尬的,程序再也找不到某些类型。通常在扩展属性上爆炸,有时在ICommand接口上爆炸。

这些类型以及其他一些类型被从一个程序集移动到另一个程序集。使用正确的参考组件是一个坚如磐石的要求。You use必须使用:

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

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

票数 48
EN

Stack Overflow用户

发布于 2011-03-23 23:58:53

这是使用.NET 4.0的Visual Studio2010 SP1的“构建后字符串”。我正在构建一个控制台.exe,其中包含所有的子.dll文件。

"$(SolutionDir)ILMerge\ILMerge.exe" /out:"$(SolutionDir)\deploy\$(TargetFileName)" "$(TargetDir)$(TargetFileName)" "$(TargetDir)*.dll" /target:exe /targetplatform:v4,C:\Windows\Microsoft.NET\Framework64\v4.0.30319 /wildcards

基本提示:

  • 注意"\deploy\“目录:这是输出.exe文件结束的位置。
  • 注意"ILMerge\”目录。我将ILMerge实用程序复制到我的解决方案目录中(这样我就可以分发源代码,而不必担心记录ILMerge的安装)。

高级提示:

如果你发现它不工作的问题,在"Post Build“命令前添加一个"echo”。然后,在Visual Studio (View..Output)中打开"Output“窗口,并检查Visual Studio实际生成的确切命令。在我的特殊情况下,确切的命令是:

"T:\PhiEngine\CSharp\ILMerge\ILMerge.exe" /out:"T:\PhiEngine\CSharp\Server Side\deploy\NfServiceDataHod.History.exe" "T:\PhiEngine\CSharp\Server Side\NfServiceDataHod\bin\Debug\NfServiceDataHod.History.exe" "T:\PhiEngine\CSharp\Server Side\NfServiceDataHod\bin\Debug\*.dll" /target:exe /targetplatform:v4,C:\Windows\Microsoft.NET\Framework64\v4.0.30319 /wildcards

更新

添加到我的“构建后”步骤中,它用一个组合的.exe替换所有的.exe + .dll文件。它还保持了调试.pdb文件的完整性:

rem Create a single .exe that combines the root .exe and all subassemblies.
"$(SolutionDir)ILMerge\ILMerge.exe" /out:"$(TargetDir)$(TargetName).all.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll" /target:exe /targetplatform:v4,C:\Windows\Microsoft.NET\Framework64\v4.0.30319 /wildcards
rem Remove all subassemblies.
del *.dll
rem Remove all .pdb files (except the new, combined pdb we just created).
ren "$(TargetDir)$(TargetName).all.pdb" "$(TargetName).all.pdb.temp"
del *.pdb
ren "$(TargetDir)$(TargetName).all.pdb.temp" "$(TargetName).all.pdb"
rem Delete the original, non-combined .exe.
del "$(TargetDir)$(TargetName).exe"
rem Rename the combined .exe and .pdb to the original name we started with.
ren "$(TargetDir)$(TargetName).all.pdb" "$(TargetName).pdb"
ren "$(TargetDir)$(TargetName).all.exe" "$(TargetName).exe"
exit 0
票数 22
EN

Stack Overflow用户

发布于 2011-03-24 00:08:05

其他替代方案:

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2961357

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档