.Net 选择错误引用的程序集版本

Posted

技术标签:

【中文标题】.Net 选择错误引用的程序集版本【英文标题】:.Net picking wrong referenced assembly version 【发布时间】:2011-05-10 10:18:54 【问题描述】:

我刚刚将一个现有项目复制到一台全新的机器上以开始在其上进行开发,但我的一个引用程序集的版本遇到了问题(碰巧是一个 Telerik DLL)。

该项目最初引用了旧版本的程序集(我们称之为 v1.0.0.0)。我的新机器安装了最新版本的程序集,所以我想我已经更新了它(我们称之为新版本 v2.0.0.0)。

现在问题来了:如果我将旧的 v1.0.0.0 dll 复制到项目文件夹并将其添加为参考,则网站启动时不会出现问题。如果我删除该引用(并从我的系统中删除旧 DLL)并添加新版本 (v2.0.0.0),则页面显示以下异常:

无法加载文件或程序集 'XXXXXX, 版本=1.0.0.0, 文化=中性, PublicKeyToken=121fae78165ba3d4' 或 它的依赖项之一。位于 程序集的清单定义确实 与程序集引用不匹配。 (HRESULT 异常:0x80131040)

很明显,代码正在寻找过时的版本,但找不到。但为什么呢?

我在解决方案文件夹中查找了该版本号,但找不到单个参考。我仔细检查了 .csproj 文件的文本,发现版本正确显示了最新版本,并且 HintPath 正确显示了新 DLL 的路径。此外,因为我没有在系统上安装旧的 DLL,所以它没有显示在我的 GAC 中(尽管 v2.0.0.0 确实如此,正如预期的那样)。

然后我启用了融合日志查看器,试图找出它为什么要寻找那个旧版本,但没有运气:

Assembly Load Trace: The following information can be helpful to determine why the assembly 'XXXXXX, Version=1.0.0.0, Culture=neutral, PublicKeyToken=121fae78165ba3d4' could not be loaded.


=== Pre-bind state information ===
LOG: User = MyComp\me
LOG: DisplayName = XXXXXX, Version=1.0.0.0, Culture=neutral, PublicKeyToken=121fae78165ba3d4
 (Fully-specified)
LOG: Appbase = file:///d:/My Documents/Visual Studio 2010/Projects/CoolProj/WebApp/
LOG: Initial PrivatePath = d:\My Documents\Visual Studio 2010\Projects\CoolProj\WebApp\bin
Calling assembly : WebApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: d:\My Documents\Visual Studio 2010\Projects\CoolProj\WebApp\web.config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Post-policy reference: XXXXXX, Version=1.0.0.0, Culture=neutral, PublicKeyToken=121fae78165ba3d4
LOG: Attempting download of new URL file:///C:/WINDOWS/Microsoft.NET/Framework/v4.0.30319/Temporary ASP.NET Files/root/90233b18/10d54998/XXXXXX.DLL.
LOG: Attempting download of new URL file:///C:/WINDOWS/Microsoft.NET/Framework/v4.0.30319/Temporary ASP.NET Files/root/90233b18/10d54998/XXXXXX/XXXXXX.DLL.
LOG: Attempting download of new URL file:///d:/My Documents/Visual Studio 2010/Projects/CoolProj/WebApp/bin/XXXXXX.DLL.
WRN: Comparing the assembly name resulted in the mismatch: Major Version
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.

它只是说它从寻找那个旧的程序集开始。我试图在网上找到解决方案,并看到了类似的SO question,但这似乎与我的问题完全相反。那个提问者的程序找到了错误的 DLL 而不是引用的那个。而我的问题是程序神秘地寻找错误的 DLL,而当可以在本地 bin 文件夹和 GAC 中找到正确的 DLL 时却无法找到它。

为什么我要寻找旧版本?我还能在哪里搜索以找到这个糟糕的参考?

【问题讨论】:

【参考方案1】:

我的猜测是您正在使用的另一个程序集正在引用旧的 dll。您是否熟悉正在使用的所有其他项目引用,并且其中任何一个都引用了 Telerik dll?

你能像这样在你的 web.config 文件中加入绑定重定向吗?

<dependentAssembly>
 <assemblyIdentity name="Telerik" publicKeyToken="121fae78165ba3d4"/>
 <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0"/>
</dependentAssembly>

【讨论】:

在加载/不加载不同版本时,我遇到过各种类似的问题。您可以尝试的另一个技巧是手动删除 C:/WINDOWS/Microsoft.NET/Framework/v4.0.30319/Temporary ASP.NET Files/root/90233b18/10d54998 文件夹中的所有文件。有时在重新编译网站时,ASP.Net 不会因为某些文件锁定而清除该文件夹,并且这些 dll 可能会挂在旧引用上。值得一试,我知道它过去对我有用。 您为我解决了一个相关问题 - 谢谢!我的 C# 应用程序中的继承表单无法在设计器中打开,因为它正在寻找旧版本的引用。原来在引用旧版本的问题参考时,最初构建了另一个参考。 如果你还在纠结语法:msdn.microsoft.com/en-us/library/0ash1ksb.aspx 谢谢克里斯!你在这里解决了我的问题:***.com/q/11490177/7850 您还可以查看您的 App.config 或 web.config 并查看现有的 &lt;dependentAssembly&gt; 条目是否导致问题。【参考方案2】:

我尝试了大多数答案,但仍然无法正常工作。这对我有用:

右键单击参考 -> 属性 -> 将“特定版本”更改为 false。

希望对您有所帮助。

【讨论】:

这就是投票 +1 的意思。 但有时简单的点赞并不能充分说明答案让你感到多么高兴和如释重负——在花了好几个小时试图解决一个甚至不应该成为问题的愚蠢问题之后,然后您尝试以不同的方式搜索它,遇到与以前尝试不同的答案,然后轰隆隆!现在可以了!毕竟,有时仅仅按下赞成按钮并不能完全消除那种压倒性的感觉,伙计,你真的让我摆脱了这个。【参考方案3】:

我和 Chris Conway 一起讨论这个问题(支持他)。问题是您在项目中引用了一个 Telerik 程序集,该程序集引用了另一个不存在的程序集。

第一件事:我不会将任何供应商(即:telerik)程序集安装到 GAC 中。 Telerik 的东西无论如何都被编译成两个程序集(telerik.web.design 和telerik.web.ui)。只需将它们与应用程序一起部署即可。

其次,在您的每个 .proj 文件(如 .csproj)中,都会有一个 &lt;reference include..&gt; 指向 Telerik.Web.UI 文件。这通常包含一个版本号。确保您放入 bin 文件夹中的程序集与该版本匹配。

第三,确保您的所有项目都使用最新的程序集。还要确保他们从本地路径而不是 GAC 获取程序集。 (我真的很不喜欢 GAC。它对我参与的一些项目造成了无穷无尽的问题)。我们通常有一个“Assemblies”文件夹,所有项目都将其用于外部程序集引用。

第四,每次加载网站项目时,Visual Studio 都会自动搜索您的 gac,如果在 gac 中找到某些内容,它会重新定位程序集位置。我不记得它是否曾经为 Web 应用程序项目这样做过,但我已经很长时间没有遇到这些问题了。这可能会在部署期间导致类似的问题。

第五,您可以在 web.config 中重新绑定程序集的版本号。在runtime/assemblybinding 部分中,您可以使用类似以下内容的内容,它将 2008 年部署的每个 Telik 程序集向前推进,并将其指向一个非常特定的版本:

  <dependentAssembly>
    <assemblyIdentity name="Telerik.Web.UI" publicKeyToken="121fae78165ba3d4" />
    <bindingRedirect oldVersion="2008.0.0.0-2020.0.0.0" newVersion="2010.02.0713.35" />
  </dependentAssembly>

【讨论】:

我的意思是“感觉”,这已经困扰我好几个月了:)【参考方案4】:

试试:

清理临时项目文件 清理构建和 obj 文件 清理安装在 C:\Users\USERNAME\.nuget\packages\

这对我有用。

【讨论】:

清理 C:\Users\USERNAME\.nuget\packages\ 目录是我所缺少的。非常感谢! 对于干净的旧 nuget 版本,在基于 Windows 的计算机中,ckuck 开始并搜索“运行”> 复制并粘贴“%userprofile%\.nuget\packages” - 这将打开 nuget 版本文件夹【参考方案5】:
    转到 C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG 查找 machine.config 文件 在记事本中打开 查找冲突 dll 删除并保存。

编译程序集

addassembly=dllName,Version=1.0.0000.0000 Culture=neutral,PublicKeyToken="QWEWQERWETERY"

程序集编译

为我工作。

【讨论】:

我也发现了这个噩梦——即使你从 GAC 中删除程序集,它也会在“C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\machine.config”中留下错误的版本引用 【参考方案6】:

这不是一个明确的答案,但我们遇到了这个问题,这是我们的情况以及解决它的方法:

开发 1:

解决方案包含引用 NuGet 包的项目 A 和引用项目 A 的 MVC 项目。启用 NuGet 包还原,然后更新 NuGet 包。出现运行时错误,抱怨找不到 NuGet 库 - 但错误是它正在寻找较旧的、未更新的版本。解决方案(这很荒谬):在调用项目 A 的 MVC 项目的第一行代码上设置断点。按 F11 进入。解决了 - 再也没有问题了。

开发 2:

相同的解决方案和项目,但魔法设置断点和解决方案中的步骤不起作用。到处寻找版本重定向或其他对该 Nuget 包的错误引用,删除包并重新安装它,擦除 bin、obj、Asp.Net Temp,没有解决它。最后,重命名项目 A,运行 MVC 项目 - 已修复。将其重命名为原来的名称,它保持不变。

我没有解释为什么会这样,但它确实让我们摆脱了严重的困境。

【讨论】:

【参考方案7】:

您在该解决方案中还有其他项目吗?(可能是另一个项目引用了旧版本)通常在 VS 中,dll 依赖项跨越解决方案中的所有项目。

【讨论】:

解决方案中没有其他项目,也没有其他引用 Telerik 的 DLL。我只引用 MS DLL ala System.*【参考方案8】:

我的问题是旧程序集位于 Web 应用程序下的 _bin_deployableAssemblies 文件夹中。 这意味着旧程序集在构建项目时会覆盖 GAC 程序集。

【讨论】:

【参考方案9】:

如果可以为其他人节省 3 小时...我的情况有点不同。我的代码使用了 DevExpress v11.1 v11.1.4.0。我在我的代码中正确引用了它。但是.net memory profiler 在 GAC 中安装了 DevExpress v11.1 v11.1.12.0。事实上,失败的不是我引用的组件,而是他们内部引用的组件。尽我所能,总是先检查 GAC。它编译并运行良好,但我无法查看 win 表单设计器,堆栈跟踪也没有任何帮助。最后卸载了.net memory profiler,一切都恢复了。

【讨论】:

【参考方案10】:

我遇到了类似的问题,我不得不从 bin 和 obj 文件夹中删除所有内容并重建以解决我的问题。希望这会有所帮助。

【讨论】:

【参考方案11】:

我得到了:

无法加载文件或程序集“XXX-new-3.3.0.0”或其依赖项之一。找到的程序集的清单定义与程序集引用不匹配。 (HRESULT 异常:0x80131040)

这是因为我将程序集的名称从 XXX.dll 更改为 XXX-new-3.3.0.0.dll。将名称恢复为原始名称修复了错误。

【讨论】:

是的 - 在我们的通用程序集库的名称中包含一个版本,以避免源代码管理中的命名问题。改回名称并手动更新引用/提示路径,一切正常。【参考方案12】:

如果您在从 Visual Studio 环境(ASP.NET 开发服务器)测试和/或调试应用程序时遇到此问题,则需要删除开发网站文件夹中的所有临时文件。要知道该文件夹的位置,请在 Windows 托盘图标上查找 ASP.NET Development Server 图标(它的标题应如下所示:ASP.NET Development Server - Port ####),右键单击该图标并选择 Show细节;然后,物理路径字段会告诉您临时文件夹是什么,应该删除其中的所有项目以解决问题。再次构建并运行网站,问题应该得到解决(再次,为开发环境解决)。

【讨论】:

【参考方案13】:

我在引用不同版本的 Newtonsoft.json 的不同程序集时遇到了同样的问题。对我有用的解决方案是从 Nuget 包管理器控制台运行 update-package。

【讨论】:

【参考方案14】:

这个错误有点误导 - 我正在加载一些需要指定 x64 架构的 DLL。在.csproj 文件中:

<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-ABC|AnyCPU'">
    <OutputPath>bin\Release-ABC</OutputPath>
    <PlatformTarget>x64</PlatformTarget>
</PropertyGroup>

缺少PlatformTarget 导致此错误。

【讨论】:

【参考方案15】:

这几乎就像您必须清除计算机才能摆脱旧的 dll。我已经尝试了上述所有操作,然后我进行了额外的步骤,即删除我计算机上的 .DLL 文件的每个实例并从应用程序中删除所有引用。但是,它仍然可以正常编译,并且在运行时引用 dll 函数也很好。我开始怀疑它是否从某个网络驱动器引用它。

【讨论】:

【参考方案16】:

在引用同一 DLL 的不同版本的应用程序的两个版本之间切换时,我收到了相同的消息。虽然我在不同的文件夹中进行测试,但我不小心将新版本复制到旧版本之上。

所以首先要检查的是应用程序文件夹中引用的 DLL 的版本。以防万一。

【讨论】:

【参考方案17】:

也许这有帮助,也许没有。我清理了调试和发布版本,然后重命名了 OBJ 文件夹。这终于让我彻底明白了。之前的步骤基本上是项目删除引用,然后将它们重新添加到项目属性中。

【讨论】:

【参考方案18】:

在我的 Visual Studio 2015 中,我确保有问题的 Visual Studio 项目的参考路径列表为空:

【讨论】:

您对 2 个不同的问题发布了完全相同的答案?【参考方案19】:

这对我有用:

我在一个类库项目中使用了Microsoft.IdentityModel.Clients.ActiveDirectory 3.19 版,但在实际的 ASP.NET Web 应用程序项目中只安装了 2.22 版。在网络应用项目中升级到 3.19 让我克服了这个错误。

【讨论】:

【参考方案20】:

在我的情况下,我有 3 个项目,1 个主项目和 2 个主项目引用的子项目。所以我更新了主项目,省略了子项目。这就是冲突的地方。在我更新了所有项目后,一切正常。

【讨论】:

【参考方案21】:

在 VS2017 中,已经尝试了上述所有解决方案,但没有任何效果。我们正在使用 Azure devops 进行版本控制。

    来自团队资源管理器 > 源代码管理资源管理器

    选择让你抓狂很久的项目

    右击分支或解决方案>高级>获取特定版本

    然后确保您已根据屏幕截图勾选了覆盖文件的复选框

【讨论】:

【参考方案22】:

就我而言,我不小心从 nuget 中选择了错误版本的 Telerik 包,然后 nuget 将我引用的每个包替换为不正确的版本。然后它插入了一个绑定重定向到不正确的版本,这样即使我用正确的版本替换了所有内容,它仍然在寻找不正确的版本。

【讨论】:

以上是关于.Net 选择错误引用的程序集版本的主要内容,如果未能解决你的问题,请参考以下文章

程序集使用版本 X,其版本高于引用的程序集错误

.Net MVC 提示未能加载文件或程序集

无法包含报表查看器 Web 部件。错误是,程序集的版本高于引用的程序集

如何快速获得.net程序引用的程序集

c# 未能载入文件或程序集

c#引用其它程序的程序集时报错