警告:发现了相同依赖程序集的不同版本之间的冲突。

351

我正在开发一款.NET应用程序,由20个项目组成。其中一些项目使用.NET 3.5进行编译,其他一些项目仍是.NET 2.0项目(目前没有问题)。

问题在于,如果我包含一个外部组件,我总是会收到以下警告:

发现同一依赖程序集的不同版本之间存在冲突。

这个警告具体是什么意思?是否有可能排除这个警告(例如在源代码文件中使用 #pragma disable)?

21个回答

441

这个警告意味着两个项目引用了同一个程序集(例如System.Windows.Forms),但是两个项目需要不同的版本。您有几个选项:

  1. 重新编译所有项目以使用相同的版本(例如将所有内容移动到 .Net 3.5)。这是首选的选项,因为所有代码都是使用它们编译时依赖项的版本运行。

  2. 添加绑定重定向。这将抑制警告。但是,您的 .Net 2.0 项目将在运行时绑定到诸如 System.Windows.Forms 的 .Net 3.5 版本的相关程序集。您可以通过在 Visual Studio 中双击错误来快速添加绑定重定向。

  3. 使用CopyLocal=true。我不确定这是否会抑制警告。就像上面第二种方法一样,这意味着所有项目将使用 .Net 3.5 版本的 System.Windows.Forms。

以下是几种查找问题引用的方法:

  • 您可以使用类似于https://gist.github.com/1553265的实用程序
  • 另一种简单的方法是设置生成输出详细程度(工具、选项、项目和解决方案、生成和运行、MSBuild 项目生成输出详细程度、详细信息),然后在构建后搜索警告窗口,查看警告窗口上方的文本。(感谢pauloya在评论中提出此建议)

9
只需一种快速的方法即可在不使用实用程序的情况下找到它——如果您添加绑定重定向(作为选项2),它将显示涉及的引用——如果需要,然后可以使用其他方法来处理它,并从配置文件中删除绑定重定向。 - Brisbe
239
找到“有问题的引用”最简单的方法是设置生成输出详细程度(工具,选项,项目和解决方案,生成和运行,MSBuild 项目生成输出详细程度,详细),然后构建后,在输出窗口中搜索警告。请查看其上方的文本。 - pauloya
10
双击警告后的绑定重定向(步骤2)不要删除我的警告。我看到在 app.config 中添加了一个程序集,我怀疑它是原因,但在清理/重建后警告仍然存在。此外,我已尝试步骤3,但没有成功。有任何想法吗? - angularsen
13
如果它们不是来自你自己的项目的引用,会怎样?例如,我引用了一个依赖于 Newtonsoft.Json, Version=6.0.0.0 的项目,并且我还引用了另一个依赖于 Newtonsoft.Json, Version=4.5.0.0 的项目。 - Edward Ned Harvey
3
@brian-low,我可以建议您将“生成输出详细程度”设置(如@pauloya在评论中所建议的)作为选项与链接实用程序一起添加到您的答案中吗?(免责声明:实际上我试图编辑答案来做到这一点,但经过审核后被拒绝了 :)) - Rick Riensche
显示剩余5条评论

46

基本上,当你引用的程序集的“Copy Local”设置为“True”时,就会发生这种情况,这意味着DLL的副本将与你的exe一起放置在bin文件夹中。

由于Visual Studio也会复制被引用程序集的所有依赖项,因此可能会出现引用同一个程序集的两个不同版本的构建。如果你的项目在不同的解决方案中,那么这种情况更有可能发生,因为它们可以分别编译。

我解决这个问题的方法是,在程序集项目中将“Copy Local”设置为False。只对你需要程序集来运行最终产品的可执行文件/ Web应用程序进行设置。

希望这有意义!


35

我想发布 pauloya 在上面评论中提供的解决方案。我认为这是找到有问题的引用的最佳解决方案。

找出哪些是“有问题的引用”的最简单方法是设置生成输出详细程度(工具、选项、项目和解决方案、生成和运行、MSBuild 项目生成输出详细程度、详细),然后在构建后在输出窗口中搜索警告。请查看其上方的文本。

例如,当您在输出面板中搜索“冲突”时,您可能会发现类似于以下内容:

3>  There was a conflict between "EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" and "EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089".
3>      "EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" was chosen because it was primary and "EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" was not.

正如您所看到的,EF版本5和6之间存在冲突。


5
既然我已经得到这个信息,那么如何消除错误呢?我知道冲突出在哪里,但是我找不到项目引用了冲突版本的地方。 - Bassie
嗨@Bassie,首先要做的是检查您的NuGet包文件,并确定是否需要将所有文件更新到包的相同版本。 您可以通过运行类似于update-package [your package name] -version 6.0.0 -reinstall的命令来执行此操作,如我在这里的答案中所述https://dev59.com/o-o6XIcBkEYKwwoYJA7p#26891914。 - user1477388
@Bassie,你可以按照警告建议的方式,在app.config文件中添加绑定重定向!(如果更新不是一个选项的话。) - BrainSlugs83
@Bassie 请看我的回答,我会向您展示如何获取导致不匹配问题的不同程序集/.dll。 - newprint

29

在 Visual Studio 上,如果您右键单击解决方案并选择管理 NuGet 包,则会出现一个"整理"选项卡,该选项卡可以将所有包设置为相同的版本。


23

我在我的一个项目中遇到了同样的问题,但是以上方法都没有帮助解决警告。我检查了详细的构建日志文件,使用AsmSpy验证了在受影响的解决方案中每个项目使用了正确的版本,我仔细检查了每个项目文件中的实际条目 - 什么都没有帮助。

最终发现问题是一个引用中存在嵌套依赖关系。这个引用(A)又需要另一个版本的(B),而这个版本被所有其他项目直接引用。更新引用所在的项目中的引用解决了该问题。

Solution A
+--Project A
   +--Reference A (version 1.1.0.0)
   +--Reference B
+--Project B
   +--Reference A (version 1.1.0.0)
   +--Reference B
   +--Reference C
+--Project C
   +--Reference X (this indirectly references Reference A, but with e.g. version 1.1.1.0)

Solution B
+--Project A
   +--Reference A (version 1.1.1.0)

希望上面的内容展示了我的意思,我花了几个小时才找到答案,希望其他人也能从中受益。


1
同样的问题在这里。然而,我没有机会将引用更新到新版本。我尝试使用一个 App.config:虽然它对应用程序有效,但 Visual Studio 2010 在构建期间似乎忽略了它。 - Thomas Weller
1
哇,我已经遇到这些问题两个月了,但一直找不到原因解决。出现问题时只在调试期间崩溃,在某些情况下,手动替换 bin 文件夹中讨厌的 .dll 才能解决问题。调试真的很痛苦。当我看到你的答案时,意识到这正是我遇到的问题,并且我在短短的五分钟内就解决了它 :) - Dennis Puzak

9

我刚刚收到了这个警告信息,然后清理了解决方案并重新编译(Build -> Clean Solution),然后它就消失了。


11
只有在重新构建解决方案之后才能实现。 - Luke
这救了我!我昨天以来一直在尝试其他解决方案,但这个解决了我的问题。包括上面的评论^。谢谢! - MuntingInsekto

6

我曾经遇到过同样的问题,在web.config中进行了以下更改后得以解决。

这是因为我在使用Newtonsoft.Json 4.0运行应用程序导致的。

更改前:

<dependentAssembly>
  <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
  <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>

致:

<dependentAssembly>
  <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
  <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="4.5.0.0" />
</dependentAssembly>

这对我来说是解决方案。我有一个绑定重定向到更高的版本,只有当我移动到较低的版本时才起作用。 - mrwaim
1
为什么?对我来说很奇怪。我不使用EF,但我认为我们总是想要升级到最新版本? - Hoàng Long
1
@HoàngLong 因为你引用的版本是旧版,但你包含的版本是新版。 - BrainSlugs83

3
如果您正在使用Nuget管理依赖项,则我有另一种方法可以完成此操作。我发现有时VS和Nuget不匹配,Nuget无法识别您的项目是否已经同步。 packages.config会显示一些内容,但是在“引用 - 属性”中显示的路径可能会指示其他内容。
如果您愿意更新依赖项,请执行以下操作:
1.从“解决方案资源管理器”中,右键单击项目,然后单击“管理Nuget包”。
2.在左侧窗格中选择“已安装的包”,记录您安装的包。如果您有很多包,请先将packages.config复制到桌面上,以便可以通过Google交叉检查它来查看安装了哪些Nuget包。
3.卸载您的包。没关系,我们马上就会把它们添加回来。
4.立即安装所需的包。 Nuget不仅会为您获取最新版本,还会更改您的引用,并为您添加绑定重定向。
5.对于所有项目都要这样做。
6.在解决方案级别上,执行清理和重建。
您可能希望从较低的项目开始,逐个完成每个项目的重建,并逐步完成更高级别的项目。
如果您不想更新依赖项,则可以使用软件包管理器控制台,并使用语法Update-Package -ProjectName [yourProjectName] [packageName] -Version [versionNumber]

2
最初的回答:我刚刚花了一些时间调试同样的问题。请注意,问题可能不是在不同项目之间,而是在同一项目中依赖于不同版本的相同dll/程序集的几个引用之间产生的。在我的情况下,问题是单个项目中来自两个不同NuGet包的FastMember.dll版本不匹配。当我得到一个项目时,由于缺少NuGet包,它无法编译,VS拒绝恢复缺少的包。通过NuGet菜单,我手动更新所有NuGets到最新版本,这时出现了警告。
在Visual Studio 工具 > 选项 > 生成和运行 > MSBuld项目生成输出详细程度:(设置为)诊断。输出窗口中查找There was a conflict between行。以下是我得到的输出部分:
1>  There was a conflict between "FastMember, Version=1.5.0.0, Culture=neutral, PublicKeyToken=null" and "FastMember, Version=1.3.0.0, Culture=neutral, PublicKeyToken=null". (TaskId:19)
1>      "FastMember, Version=1.5.0.0, Culture=neutral, PublicKeyToken=null" was chosen because it was primary and "FastMember, Version=1.3.0.0, Culture=neutral, PublicKeyToken=null" was not. (TaskId:19)
1>      References which depend on "FastMember, Version=1.5.0.0, Culture=neutral, PublicKeyToken=null" [C:\Users\ksd3jvp\Source\Temp\AITool\Misra\AMSAITool\packages\FastMember.1.5.0\lib\net461\FastMember.dll]. (TaskId:19)
1>          C:\Users\ksd3jvp\Source\Temp\AITool\Misra\AMSAITool\packages\FastMember.1.5.0\lib\net461\FastMember.dll (TaskId:19)
1>            Project file item includes which caused reference "C:\Users\ksd3jvp\Source\Temp\AITool\Misra\AMSAITool\packages\FastMember.1.5.0\lib\net461\FastMember.dll". (TaskId:19)
1>              FastMember, Version=1.5.0.0, Culture=neutral, processorArchitecture=MSIL (TaskId:19)
1>      References which depend on "FastMember, Version=1.3.0.0, Culture=neutral, PublicKeyToken=null" []. (TaskId:19)
1>          C:\Users\ksd3jvp\Source\Temp\AITool\Misra\AMSAITool\packages\ClosedXML.0.94.2\lib\net46\ClosedXML.dll (TaskId:19)
1>            Project file item includes which caused reference "C:\Users\ksd3jvp\Source\Temp\AITool\Misra\AMSAITool\packages\ClosedXML.0.94.2\lib\net46\ClosedXML.dll". (TaskId:19)
1>              ClosedXML, Version=0.94.2.0, Culture=neutral, processorArchitecture=MSIL (TaskId:19)

请注意,项目文件项包括引用“C:\Users\ksd3jvp\Source\Temp\AITool\Misra\AMSAITool\packages\ClosedXML.0.94.2\lib\net46\ClosedXML.dll”。 ClosedXML.dll 来自 ClosedXML NuGet,并依赖于 FastMember.dll 1.3.0.0。此外,项目中还有 FastMember Nuget,它有 FastMember.dll 1.5.0.0。版本不匹配!
因为我有绑定重定向,所以我卸载了 ClosedXMLFastMember NuGets,并安装了最新版本的 ClosedXML。这解决了问题!

2
这实际上取决于您的外部组件。在.NET应用程序中引用外部组件时,会生成一个GUID来标识该组件。当您的项目之一引用的外部组件与另一个程序集中的另一个组件具有相同的名称但版本不同时,就会出现此错误。
当您使用“浏览”查找引用并添加错误版本的程序集时,或者您在代码存储库中拥有与本地安装的组件不同版本的组件时,有时会发生这种情况。
请尝试查找哪些项目存在这些冲突,从引用列表中删除组件,然后再次添加它们,确保指向相同的文件。

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