Sar*_*els 51 .net dll ilmerge assemblies c#-4.0
两个问题:
1)ILMerged程序集中不包含基本.NET程序集
从.NET 3.5/Visual Studio 2008升级到.NET 4/Visual Studio 2010后,我在后期构建中使用ILMerge时遇到问题.我有一个解决方案,其中有几个项目的目标框架设置为".NET Framework 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
Run Code Online (Sandbox Code Playgroud)
如果我不指定.NET 4框架目录的位置,我会从ILMerge得到"Unresolved assembly reference not allowed:System"错误.如果我不指定MSTest目录的位置,我得到"不允许未解析的程序集引用:Microsoft.VisualStudio.QualityTools.UnitTestFramework"错误.
上面的ILMerge命令工作并生成DLL.但是,当我在另一个.NET 4 C#项目中引用该DLL并尝试使用其中的代码时,我收到以下警告:
无法解析主要引用"MyILMergedDLL",因为它对.NET Framework程序集"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 API的人不应该添加对它引用的任何库的引用.我怎么能绕过这个?
2)仅在使用合并程序集时出现TypeLoadException
编辑:除此之外,即使我System.Xml在使用MyILMergedDLL.dll的使用者项目中添加引用,使用MyILMergedDLL.dll中的一些代码也会产生以下异常:
System.TypeLoadException:无法从程序集'MyILMergedDLL,Version = 1.0.1.1,Culture = neutral,PublicKeyToken = ...'加载类型'System.Func`2'.
这是我的消费者项目中的代码; 造成这条线的TypeLoadException是第二条线:
var keys = new[] {"a", "b", "c"};
var row = new Row(keys);
Run Code Online (Sandbox Code Playgroud)
Row抛出它的特定构造函数TypeLoadException是在公共类中定义的MyILMergedDLL,当我在引用单个项目DLL时使用此构造函数时,它可以正常工作.只有当我在引用IL合并的DLL时才使用此构造函数,我才会获得异常.我不知道发生了什么事.
这是构造函数:
public Row(IEnumerable<string> keys) : base(keys) { }
Run Code Online (Sandbox Code Playgroud)
而base其所提到有这样的代码:
foreach (string key in keys.Where(
key => !string.IsNullOrEmpty(key)
))
{
_dic.Add(key, string.Empty);
}
Run Code Online (Sandbox Code Playgroud)
Han*_*ant 48
有一个非常最近发布解决问题的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接口上.
这些类型和其他一些类型从一个程序集移动到另一个程序集.使用正确的参考组件是一项艰巨的要求.你必须使用:
/lib:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0"
Run Code Online (Sandbox Code Playgroud)
调整以匹配您的特定计算机和目标框架版本.
Con*_*ngo 22
这是使用.NET 4.0的Visual Studio 2010 SP1的"Post Build String".我正在构建一个包含所有子.dll文件的控制台.exe.
"$(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
Run Code Online (Sandbox Code Playgroud)
基本提示:
高级提示:
如果您遇到问题,请在"Post Build"命令之前添加"echo".然后,在Visual Studio中打开"输出"窗口(View..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
Run Code Online (Sandbox Code Playgroud)
更新
将其添加到我的"Post Build"步骤中,它用一个组合的.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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
55178 次 |
| 最近记录: |