Error 2 The type <T> exists in both… with ILMerge

妖精的绣舞 提交于 2019-12-11 05:38:50

问题


I have 3 projects:

  • A_MainProject (startup project)
  • B_IntermediateProject
  • C_SharedClassLibrary

The depencies are:

A depends on B & C

B depends on C

and C depends on System only.

Every Project has it's own namespace.

As long as no ILMerge is installed, everything works fine.

If ILMerge is activated for Project A ("A_MainProject") everything still works fine and one self-contained executable for Project A is generated.

If ILMerge is now also activated for the B_IntermediateProject, I get the following error:

Error   2   The type 'C_SharedClassLibrary.SharedClass' exists in both 'c:\dev\ILMergeError\B_IntermediateProject\bin\Debug\B_IntermediateProject.exe' and 'c:\dev\ILMergeError\C_SharedClassLibrary\bin\Debug\C_SharedClassLibrary.dll'    C:\dev\ILMergeError\A_MainProject\Program.cs    12  A_MainProject

I use "MSBuild ILMerge task" 1.0.3-rc2 with "ILMerge" 2.13.0307 (from mbarnett).

The minimal solution contains 3 Projects with one class each. This version has ILMerge activated on only one project and works:

ILMergeError_stillworking.zip

This version has it also activated on project B and produces the error:

ILMergeError_error.zip

If I merge the two exes and the dll with ILMerge externally (ILMergeGUI) everything works fine.

Thank you in advance for answering, Xan-Kun


回答1:


The short answer is that you should only enable ILMerge on A, where it'll merge both A+B+C together.

The reason why you hit this error is that when you enable ILMerge on B, B will be repacked with all C types as well (B' = B+C). Hence when ILMerge triggers on A, it'll merge A+B'+C = A+(B+C)+C

Now 2 scenarios can happen:

  1. B uses C internally, and doesn't (publicly) expose any C type (e.g. as method argument or return value). In this case you can make it work through ILMerge options (/internalize on B and /allowDup on A), though you'll end up with twice every C type in the merged assembly A.

  2. B exposes C types, that are maybe used by A. In this case even if you manage to make the merge work, it'll fail at runtime, because A and B' reference different types (e.g. for a class c, B' references B'.c and A references C.c), And you'll get nasty type cast exceptions, because those are 2 different types (same name, same namespace, but different assemblies).

(They're nasty because they don't indicate the assembly mismatch, and exception only says that "c cannot be cast to c", which can be confusing to many)



来源:https://stackoverflow.com/questions/29806751/error-2-the-type-t-exists-in-both-with-ilmerge

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!