【问题标题】:Determine the source of an indirect dependency on incorrect .NET Framework version确定对不正确的 .NET Framework 版本的间接依赖的来源
【发布时间】:2012-06-06 00:02:11
【问题描述】:

我想知道如何确定此构建错误的来源;

Warning 4   The primary reference "MyNamespace.MyProject" could not be resolved because 
   it has an indirect dependency on the .NET Framework assembly "System.Xml, Version=4.0.0.0,
   Culture=neutral, PublicKeyToken=b77a5c561934e089" which has a higher version "4.0.0.0" than
   the version "2.0.0.0" in the current target framework.   MyNamespace.MyOtherProject

我理解这个错误的含义(以及其他 5 个对同一个项目喜欢它的人),但我不知道如何在我的情况下解决它。在这种情况下,“主要参考”(MyNamespace.MyProject)对 .NET 4.0.x 没有直接依赖关系。

主要参考仅依赖于我的另一个项目 (MyNamespace.MyCoreProject),构建的源项目 (MyNamespace.MyOtherProject) 也直接依赖于该项目。而且构建并没有抱怨 那个 项目间接引用了 .NET 4.0.x,所以我认为我可以排除这种情况。

主要参考直接依赖于三 (3) 个第 3 方 DLL,所有这些 DLL 也都以 .NET 2.0 为目标。

我已经使用 dotPeek 检查构建的库,并且看不到对使用 .NET 4.0 的任何内容的任何引用。

作品中唯一的其他潜在扳手是使用 PostSharp,它被 'MyNamespace.MyCoreProject' 直接引用(由主要参考项目引用),这可能会导致问题,因为我相信有一个相关的引用 PostSharp.dll 时出现 VS2010 错误(http://www.sharpcrafters.com/forum/Topic4444-4-1.aspx#bm4462),但是我也从构建链中删除了它,仍然看到这个错误,所以我假设我也可以排除那个

如果有人能告诉我为什么会这样,太棒了!如果没有,关于如何确定未命名的“间接引用”是什么的一些指导将同样有帮助!

顺便说一句,我已经尝试了以下所有工具来获取一些信息,但它们并没有告诉我很多我还不知道的信息(这是相关 DLL 的直接依赖项); - .NET 反射器 - 点窥 - IldAsm - 依赖(依赖步行者)

【问题讨论】:

  • 仅仅因为它没有引用任何 4.0 代码,并不意味着它不需要运行 4.0 二进制文件。
  • @ColeJohnson 如果什么都不依赖于 4.0 框架,那么我不需要 4.0 框架。我正在尝试找出需要 4.0 的内容。
  • 你去项目的属性里改过依赖框架了吗?
  • 看起来您有一个针对 .net2 构建的项目,该项目引用了一些 v4 程序集。查看参考资料,检查其中每一项的属性,其中一项或多项将是 v4。删除并替换为 .net 2 版本。
  • @ColeJohnson my 代码中的所有内容都针对 3.5(即 .NET 2.0 CLR)。

标签: c# visual-studio-2010 projects-and-solutions postsharp


【解决方案1】:

虽然我实际上还没有找到一个好方法来实际解决确定 MsBuild 如何确定它使用的引用的问题(为什么它不只是告诉我它是如何产生这些间接引用的,而不是让我猜测我不知道...)我已经解决了我的问题。

最后,我基本上删除了“主要引用”项目中的所有引用(这需要逐段排除所有代码 - 一个有点痛苦的过程)以确定假定的对 .NET 4.0 库的间接引用的来源是由引用的第 3 方 DLL 引起的。

但是,我确实相信这个问题背后的 MsBuild 中存在一个错误,因为;

  1. “浏览”将第 3 方 DLL 引用到我机器上的特定 DLL 文件 - 一个非常明确地仅依赖于 .NET 2.0 的文件
  2. 在构建中将“特定版本”设置为 true 并没有解决此问题
  3. MsBuild 似乎要向 GAC 获取此 DLL 的不同版本,并导致不正确的引用错误。

现在,另一个好奇是我已经有一段时间没有接触或更改相关的库了,所以这只是由于其他一些不相关的原因才开始发生 - 可能是什么,我不知道。

最后,我发现解决此问题的唯一方法是为每个相关库运行 gacutil /u 以删除以前安装/使用的 4.0 库版本。 (包里大约有 40 个,所以这也很痛苦!因为包的卸载程序没有删除 GAC 中的库)

这似乎让 msbuild 开始使用我告诉它的引用,而不是自己想出“使用这个文件”和“使用这个特定版本的含义。 p>

已解决,但我希望有一种更清洁的方式来做到这一点!

【讨论】:

  • 那你如何使用 gacutil 解决它呢?它确实需要命令提示符中的参数。
  • 究竟什么是“程序集显示名称”?整个事情通过公钥令牌?
【解决方案2】:

尝试对所有可疑程序集使用MSIL Disassembler 工具。

  1. 打开 Dll,单击 Ctr + M 并转到屏幕末尾。您可能会看到对某些 .NET 4 程序集的引用,例如:

AssemblyRef #1 (23000001)

Token: 0x23000001
Public Key or Token: b7 7a 5c 56 19 34 e0 89 
Name: mscorlib
Version: 4.0.0.0
Major Version: 0x00000004
Minor Version: 0x00000000
Build Number: 0x00000000
Revision Number: 0x00000000
Locale: <null>
HashValue Blob:
Flags: [none] (00000000)
  1. 使用inf ref # 查找从该.NET 程序集加载的类型作为搜索条件。 这是您可以在屏幕中找到的类型示例

    TypeRef #18 (01000012)

    令牌:0x01000012
    分辨率范围:0x23000001
    TypeRefName:System.Runtime.CompilerServices.CompilationRelaxationsAttribute

  2. 调查为什么使用该类型。

更新: 您是否尝试在 Tools\Options\Projects and Solutions\Build And Run 页面上将 set MSBuild Project Build Output Verbosity 设置为“Detailed”,然后重新构建解决方案?你可能会在 ResolveAssemblyReference 目标中看到一些东西

【讨论】:

  • 谢谢,我已经看过了,但它并没有比其他几个工具更能告诉我;它让我看到了直接的依赖关系,(没有一个是针对 4.0 的),但仅此而已。事实上,它似乎也没有告诉我特定程序集的目标是哪个框架。你指出的版本只是汇编版本,不一定和它需要的.NET框架有关。
  • 您是否尝试在 Tools\Options\Projects and Solutions\Build And Run 页面上将 set MSBuild Project Build Output Verbosity 设置为“Detailed”,然后重新构建解决方案?你可能会在 ResolveAssemblyReference 目标中看到一些东西
  • 是的,我现在正在解决这个问题,但这并没有给我很多线索,而且它是一个非常长的日志文件(650 万行!)
  • 应该有一些对 .net 4.0 dll 的引用。它可能非常不直接,但应该如此。尝试找到这个子字符串“System.Xml,Version=4.0.0.0”并按照路径
  • 日志中没有这样的字符串(除了报告错误),这就是问题的一半。我的任何代码都没有引用该文件,或者我的代码引用的任何引用都没有引用该文件!请参阅下面的答案以了解我的“解决方案”。
【解决方案3】:

我遇到了这个问题,并使用 CheckAsm 确定我自己的一个程序集出于某种奇怪的原因引用了 .NET 4.0 版本的第 3 方库,而应用程序本身是 .NET 2.0。我从我的硬盘驱动器中删除了该程序集的所有实例(周围有很多副本),重新构建了解决方案,一切都很好。

【讨论】:

    【解决方案4】:

    在我的情况下,程序集已卸载,并且所有引用(据我所知)都已删除。

    在 app.config 中找到它:

    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
                ...
            </dependentAssembly>
        </assemblyBinding>
    </runtime>     
    

    删除了dependentAssembly,让我的应用再次运行。

    【讨论】:

    • 对我来说一直是 app.config。我已经删除了对一个库的所有引用以及任何可能链接到一个库并且仍然构建的东西会抱怨它找不到这个库......我已经从我的系统中删除了这个库并且完全没有必要。我什至试图强制所有项目使用它的显式低版本,但仍然失败。项目文件很干净。没有踪迹……除了 app.config。不知道为什么,但 app.config 决定它需要使用这个库。如果诊断构建日志告诉我这就是原因,那就太好了。
    【解决方案5】:

    我也遇到了这个问题,event.er 引导我找到解决方案。我的 app.config 中有以下内容:

      <dependentAssembly>
        <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="4.0.0.0" />
      </dependentAssembly>
    

    我将 newVersion 更改为“2.0.0.0”并构建了解决方案。

    【讨论】:

      【解决方案6】:

      我的猜测是第 3 方 DLL 是一个没有将特定版本设置为 true 的依赖项并导致您的问题。

      【讨论】:

        【解决方案7】:

        我在一个针对 .NET 4.5 的项目中遇到了 System.Data.SQLite.dll 问题,结果是针对 GAC_32 安装了针对 4.5.1 的版本。

        如果我使用Copy Local = True 构建解决方案,一切都会好起来的。但是当我在最终构建中嵌入 SQLite 程序集时,这似乎是不必要的,我想对其进行整理。

        我尝试运行gacutil -u System.Data.SQLite.dll,但遇到了问题,所以最后我只是使用 Windows 的程序和功能来卸载它,然后一切都很好。

        【讨论】:

          【解决方案8】:

          如果使用 Visual Studio 2019 并尝试构建 .NET 3.5 项目,这将有所帮助。

          Visual Studio 服务包和较新的 Visual Studio 2019 将一个程序(通常是 WebDeploy)放在 Program Files 中,并将此文件夹放在您机器的程序集探测路径的高位(因此 net45 JSON.NET 程序集在任何其他程序之前被拾取)一)。

          要弄清楚您的问题是从哪里解决的,只需使用 SysInternals Process Monitor 并过滤引用的 DLL。然后开始你的构建。 Process Monitor 会告诉你它从哪里解析该程序集,它通常是 VS2019 安装的 WebDeploy 文件夹中的那个。如果您不使用 WebDeploy 工具,则可以清除该文件夹。

          具体来说,就我而言,我删除了 C:\Program Files\IIS\Microsoft Web Deploy V3\Newtonsoft.Json.dll 并且我的构建工作正常。

          【讨论】:

            猜你喜欢
            • 2023-04-01
            • 2020-05-10
            • 2011-03-28
            • 2011-03-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-03-29
            • 2010-12-06
            相关资源
            最近更新 更多