【问题标题】:DLL load fails at runtimeDLL 加载在运行时失败
【发布时间】:2017-08-16 22:58:49
【问题描述】:

我有一个可以在本地正常运行的 c# 应用程序。它依赖于许多其他 c# 项目。当我右键单击并发布并获取 setup.exe 时,一旦运行,我就会收到一条错误提示

System.IO.FileLoadException:无法加载文件或程序集“Newtonsoft.Json,版本=4.5.0.0,Culture=neutral,PublicKeyToken=30ad4fe6b2a6aeed”或其依赖项之一。找到的程序集的清单定义与程序集引用不匹配。 (HRESULT 异常:0x80131040)
文件名:'Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'

这特别来自我的 Twitter 项目。 twitter 项目不引用 4.5.0.0 它引用 6.0.0.0

我似乎在任何地方都找不到对 4.5.0.0 的任何引用。我使用的是 tweetsharp-unofficial 2.3.1.2 (https://github.com/timothy-makarov/tweetsharp),它本身具有 json.net 依赖项,但我没有明确引用。

关于这是如何发生的任何线索?

提前致谢!

【问题讨论】:

  • 当不同的项目引用同一个 nuget 包的不同版本时,这种情况经常发生。您的 Twitter 项目引用的项目之一必须使用 4.5.0.0
  • 如果所有项目都在同一个解决方案中,您可以打开 nuget 包管理器并转到 Consolidate 选项卡,它会显示不匹配的版本。
  • @GBreen12 我不同意你的说法。 “当不同的项目引用同一个 nuget 包的不同版本时,这种情况经常发生”。这是运行时错误,无论是否使用 nuget,它都可能独立发生。可能你指的是一个案例,当一个项目引用 dll 的 v1 并且还引用第二个项目时,这反过来又引用了同一个 dll 的 v2。在这种情况下,错误会说明 2 个不同的版本。如果项目未连接,最后构建的项目将简单地覆盖 bin 中的 dll,并且在运行时会发生错误,就像这里一样。很大程度上取决于这里的情况。
  • @GBreen12 我的 twitter 项目没有引用任何其他项目,除了一个只是模型,而且该项目中甚至没有 newtonsoft。它确实安装了一个 nuget 包和一个我为该服务制作的类/接口文件。
  • 此外,我现在将每个版本都更新为 6.0.0.8 调用 4.5.0.0 的错误没有变化

标签: c# asp.net dll json.net


【解决方案1】:

除了上面 GBreen 所说的,根据您对引用的控制级别,您还可以查看 web.config 中的 bindingRedirects。类似如下:

<!-- Upgrade of NewtonsoftJson.dll to version 6.0.2. The Web API/MVC 4 has been built with version 4.5 of NewtonsoftJson.dll, so we need a redirect in the web.config for now.-->
<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <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>
  </assemblyBinding>
</runtime>

【讨论】:

    【解决方案2】:

    此错误的含义如下:

    您使用 Newtonsoft 程序集构建了一个 DLL,该程序集的版本比您 bin 中的版本更高。程序集版本被写入您的 DLL 清单。在加载过程中,如果 bin 中的程序集版本较低,则会引发该异常。此外,版本 (a.b.c.x) - abc 中只有 3 位数字很重要。例如,版本1.0.0.11.0.0.2 是可互换的。如果您针对 v6.0.0.0 构建 DLL 并放置在 bin v4.5.0.0 中,您将遇到问题。但是相反应该有效,只要您不调用某些更改签名的方法,或者您调用的方法不调用其他更改签名的方法。

    1。 最好的解决方案是统一版本控制 - 到处使用相同的版本。

    2。 如果您在 bin 中使用更高版本的 DLL,它甚至适用于使用相同 dll 的较低版本构建的应用程序

    3。 或者,您可以将版本重定向添加到您的 app.config。此特定配置将较高版本的构建重定向到使用较低版本。只要没有调用新函数,它就会工作

    <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1" appliesTo="v1.0.3705">  
        <dependentAssembly>   
          <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture=""/>  
          <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="4.5.0.0"/>  
        </dependentAssembly>  
      </assemblyBinding>  
    </runtime>
    

    顺便说一句,此时newtonsoft当前版本是9+

    【讨论】:

    • 嗯。我更新了所有项目以使用 6.0.0.8,但在运行时仍然会出现相同的错误,因为没有 4.5.0.0。我也尝试了#3,但是在我的 app.config 中,如果我放置该运行时,它不会为我生成 .config 文件。 (我知道适用于 web.config 的 app.config 位置不同吗?)
    • @JordanBrooklyn 现在您的所有项目都参考 v6.0... 在 config 中运行没有 assemblyBinding 的应用程序。如果这不起作用...如果您无法将其添加到 app.config(查看配置中是否已经有 &lt;runtime&gt;,然后仅添加内部内容),您始终可以将其直接添加到您的 myApp.exe.config。只有这一次您需要更改为&lt;bindingRedirect oldVersion="0.0.0.0-4.5.0.0" newVersion="6.0.0.8"/&gt;。您有可能引用 v4.5 并已设置为“特定版本”的第 3 方。照我说的做,让我知道。嘿,只需确保 bin 中的 dll 确实是 v6
    • 我确实再试了一次。当我发布时,我将该块添加到我的 app.config(在配置标签下,在我的控制台应用程序 app.config 中)的那一刻,我不再得到 CacheConsoleApp.exe.config.deploy 它甚至不在清单中。如果我注释掉那个运行时标签,我会再次获得配置。关于为什么会发生这种情况的任何想法?
    • @JordanBrooklyn 不知道。尝试在构建后添加部分。
    猜你喜欢
    • 2021-01-07
    • 2010-10-16
    • 1970-01-01
    • 2019-11-21
    • 2020-02-28
    • 2012-12-21
    • 2012-12-29
    • 2020-09-01
    相关资源
    最近更新 更多