我正在尝试在C#Windows窗体应用程序(Visual Studio 2005)中运行一些单元测试,但出现以下错误:
System.IO.FileLoadException:未能加载文件或程序集“Utility,Version=1.2.0.200,Culture=neutral,PublicKeyToken=764d581291d764f7”或其依赖项之一。找到的程序集的清单定义与程序集引用不匹配。(HRESULT的异常:0x80131040)**位于x.Foo.FooGO()位于Foo.cs:line 123中的x.Foo.Foo2(String groupName_)位于FooTests.cs:line 98中的x.Foo.UnitTests.FooTests.TestFoo()**System.IO.FileLoadException:未能加载文件或程序集“Utility,Version=1.2.0.203,Culture=neutral,PublicKeyToken=764d581291d764f7”或其依赖项之一。找到的程序集的清单定义与程序集引用不匹配。(HRESULT的异常:0x80131040)
我查阅了我的参考资料,我只参考了实用程序版本1.2.0.203(另一个是旧版本)。
关于我如何找出试图引用此DLL文件的旧版本的内容,有什么建议吗?
此外,我想我的硬盘上甚至没有这个旧组件。是否有任何工具可以搜索此旧版本的程序集?
我自己遇到了这个问题,我发现这个问题与其他人遇到的问题不同。
我的主项目引用了两个dll:CompanyClasses.dll和CompanyControls.dll
无法加载文件或程序集'CompanyClasses,版本=1.4.1.0,培养=中性,PublicKeyToken=045746ba8544160c'或它的一个依赖项。位于程序集的清单定义与程序集引用不匹配
问题是,我的系统中没有版本号为1.4.1的CompanyClasses.dll文件。GAC中没有,应用程序文件夹中没有。。。任何地方都没有。我搜索了整个硬盘。我所有的CompanyClasses.dll文件都是1.4.2。
我发现,真正的问题是CompanyControls.dll引用了CompanyClasses.dll的1.4.1版本。我刚刚重新编译了CompanyControl.dll(在引用CompanyClasss.dll 1.4.2之后),这个错误就消失了。
以下命令将任何程序集版本重定向到3.1.0.0版本。我们有一个脚本,它将始终更新App.config中的此引用,因此我们再也不用处理此问题了。
通过反射,您可以获取程序集publicKeyToken,并从.dll文件本身生成此块。
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Castle.Core" publicKeyToken="407dd0808d44fbdc" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-65535.65535.65535.65535" newVersion="3.1.0.0" />
</dependentAssembly>
</assemblyBinding>
注意,如果没有XML命名空间属性(xmlns),这将无法工作。
我添加了一个NuGet包,结果发现我的应用程序的黑盒部分引用了旧版本的库。
我删除了包并引用了旧版本的静态DLL文件,但web.config文件从未从以下位置更新:
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" />
<bindingRedirect oldVersion="0.0.0.0-4.5.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
恢复到卸载包时应该恢复的状态:
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.5.0.0" />
</dependentAssembly>
就我而言,问题出在椅子和键盘之间:-)
Could not load file or assembly 'DotNetOpenAuth.Core, Version=4.0.0.0,
Culture=neutral, PublicKeyToken=2780ccd10d57b246' or one of its dependencies.
The located assembly's manifest definition does not match the assembly reference.
(Exception from HRESULT: 0x80131040)
两个或多个不同的程序集希望使用不同版本的DotNetOpenAuth库,这不是问题。此外,在我的本地计算机上,NuGet自动更新了web.config:
<dependentAssembly>
<assemblyIdentity name="DotNetOpenAuth.AspNet" publicKeyToken="2780ccd10d57b246" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.3.0.0" newVersion="4.3.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="DotNetOpenAuth.Core" publicKeyToken="2780ccd10d57b246" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.3.0.0" newVersion="4.3.0.0" />
</dependentAssembly>
然后我意识到我忘记了将新的web.config复制/部署到生产服务器。因此,如果您有手动部署web.config的方法,请检查它是否已更新。如果生产服务器的web.config完全不同,则必须在使用NuGet后同步合并这些dependentAssembly部分。
这是我解决这个问题的方法。
从异常消息中,获取“问题”库的名称和“预期”版本号。
在解决方案中查找该.dll的所有副本,右键单击它们,然后检查它是哪个版本的.dll。
好的,在这个例子中,我的.dll肯定是2.0.5022.0(所以异常版本号是错误的)。
在解决方案中的所有.csproj文件中搜索异常消息中显示的版本号。用dll中的实际版本号替换此版本号。
所以,在这个例子中,我将替换这个。。。
<Reference Include="DocumentFormat.OpenXml, Version=2.5.5631.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
…用这个。。。
<Reference Include="DocumentFormat.OpenXml, Version=2.0.5022.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
工作完成!
没有适合我的解决方案。我尝试了清理项目解决方案、删除bin、更新包、降级包等……两个小时后,我用程序集从项目加载了默认App.config,并在那里更改了错误的引用版本:
<dependentAssembly>
<assemblyIdentity name="Microsoft.IdentityModel.Logging" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.5.0.0" newVersion="5.5.0.0" />
</dependentAssembly>
to:
<dependentAssembly>
<assemblyIdentity name="Microsoft.IdentityModel.Logging" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.14.0.0" newVersion="5.5.0.0" />
</dependentAssembly>
在这之后,我清理了这个项目,再次构建它,它成功了。没有警告没有问题。
我也有类似的问题,但没有一个答案对我有效。
对我有效的解决方案是手动从项目文件(YourProject.csproj)中删除publicKeyToken部分。
以前是:
<Reference Include="Utility, Version=0.0.0.0, Culture=neutral, PublicKeyToken=e71b9933bfee3534, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>dlls\Utility.dll</HintPath>
</Reference>
更改后为:
<Reference Include="Utility, Version=1.0.1.100, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>dlls\Utility.dll</HintPath>
</Reference>
确保SpecificVersion为False。
这类问题的一般答案是像其他答案一样使用绑定重定向。然而,这只是问题的一部分——您需要知道所使用的程序集文件的正确版本。Windows财产并不总是准确的,nuget也不总是准确的。
获取正确版本信息的唯一方法是分析文件本身。一个有用的工具是dotPeek。根据我的经验,dotPeek中列出的程序集名称总是准确的。
例如,此文件的正确绑定如下:
<dependentAssembly>
<assemblyIdentity name="System.ComponentModel.Annotations" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.2.1.0" newVersion="4.2.1.0"/>
</dependentAssembly>
Windows资源管理器称该文件为4.6.26515.06,nuget称其为5.0.0.0文件。dotPeek说它是4.2.1.0,这是在我们的软件中正确工作的版本。还要注意,公钥和文化很重要,dotPeek也会显示这些信息。
这个问题由来已久,我最近在Azure DevOps Yaml管道和Dotnet Core 3.1中收到了同样的错误消息。这个问题与其他答案试图解决的问题有些不同,因此我将分享我的解决方案。
我有一个解决方案,为我自己的nuget包提供了许多项目。我无意中在*.csproj文件中添加了版本标记,如下所示:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Version>1.0.0</Version>
</PropertyGroup>
我用一个DotnetCoreCLI@2任务:
- task: DotNetCoreCLI@2
displayName: 'pack'
inputs:
command: pack
nobuild: true
configurationToPack: 'Release'
includesource: true
includesymbols: true
packagesToPack: 'MyNugetProject1.csproj;**/MyNugetProject2.csproj'
versioningScheme: 'byEnvVar'
versionEnvVar: 'GitVersion.SemVer'
问题是*.csproj文件中的版本与环境变量GitVersion.SemVer(由输入“versionEnvVar”指定)中的版本不匹配。
删除*.csproj文件中的所有<Version>1.0.0</Version>-标记后,dll的程序集/fileversion由环境变量自动分配,nuget和dll(程序集/file版本)将具有相同的版本,问题得到解决。
您可能在assemblyBinding中有错误的掘金版本,请尝试:
删除web.config/app.config中的所有程序集绑定内容:
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.Logging.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.3.0" newVersion="3.1.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.DependencyInjection" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.3.0" newVersion="3.1.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ComponentModel.Annotations" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.1.0" newVersion="4.2.1.0" />
</dependentAssembly>
</assemblyBinding>
在包管理器控制台中键入:添加BindingRedirect生成所有必要的绑定重定向运行应用程序,看看它是否正常工作。如果没有,请添加包控制台缺少的任何缺少的绑定重定向。
运行迁移器以从使用packages.config升级到PackageReference,为我轻松修复了此错误。如果您运行的是Visual Studio 2017 15.7版或更高版本,您可以按照以下步骤进行升级。
https://learn.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference#migration-步骤
以下是步骤(从上述链接复制):
使用packages.config打开包含项目的解决方案。在解决方案资源管理器中,右键单击“引用”节点或packages.config文件,然后选择将packages.cnfig迁移到程序包参考。。。。迁移器分析项目的NuGet包引用和尝试将它们分类为顶级依赖项(NuGet直接安装的软件包)和Transitive依赖项(作为顶级包的依赖项安装的包)。注意:PackageReference支持可传递的包还原和解析依赖关系是动态的,这意味着传递依赖关系需要不能显式安装。(可选)您可以选择将NuGet包分类为通过选择程序包的顶层选项。此选项自动设置为包含不流动的资产的包(build、buildCrossTargeting、contentFiles或分析器文件夹)和标记为开发依赖项(developmentDependency=“真”)。检查所有程序包兼容性问题。选择“确定”开始迁移。在迁移结束时,Visual Studio提供了一个带有备份路径、已安装软件包的列表(顶级依赖项),引用为可传递的包列表依赖关系,以及在开始迁移。报告将保存到备份文件夹中。验证解决方案是否构建并运行。如果您遇到问题,在GitHub上提交问题。
与“文件资源管理器”>“属性”>“详细信息”选项卡中的版本相比,.DLL在代码中使用反射的“版本”属性报告不同的版本并不罕见。
多年来,我发现使用这种powershell可以更好地找到应该将绑定重定向设置到哪个版本。
[Reflection.AssemblyName]::GetAssemblyName('C:\Source\Project\Web\bin\System.Memory.dll').Version
Major Minor Build Revision
----- ----- ----- --------
4 0 1 2
通过以上步骤,我可以在app.config文件中插入(或替换)绑定重定向:
<dependentAssembly>
<assemblyIdentity name="System.Memory" culture="neutral" publicKeyToken="cc7b13ffcd2ddd51"/>
<bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2"/>
</dependentAssembly>
在该特定示例中,System.Memory.dll的“详细信息”选项卡报告的文件版本为4.6.31308.01。