问题描述
tl;dr:我的 .NET Core 3.1 控制台应用程序因 FileNotFoundException
崩溃,因为版本 A 中存在(引用?)程序集,但版本 B 中需要。做什么?
我正在尝试运行一个控制台应用程序,该应用程序现在是为 .NET Core 3.1 构建的,但在转换之前它曾经是一个 .NET Framework 4.8 项目。
控制台应用程序因 System.IO.FileNotFoundException
崩溃,表示无法找到 3.1.0.0 版本中的程序集 Microsoft.Extensions.FileProviders.Physical。现在,我可以确认它不在那里 - 在我的控制台应用程序的 .exe
文件所在的目录中,有一个名为 Microsoft.Extensions.FileProviders.Physical.dll 的文件,但它的程序集版本为3.1.6.0。
控制台应用程序及其依赖项是上述文件夹中一个更大项目的一部分,共有 1,200 多个 DLL。
在 .NET Framework 中,我会使用绑定重定向来使用指示程序集的当前版本 3.1.6.0。不过,在 .NET Core 中,我明白这些绑定重定向不再是一回事。因此,我不确定如何继续,或者如何找出运行时认为它需要加载 Microsoft.Extensions.FileProviders.Physical.dll 的原因。
我可能已经找到了加载版本不匹配程序集的部分解决方案(请参阅下面的观察 (6)),但是,我仍然收到 FileNotFoundException
,这次是 Microsoft.AspNetCore.Mvc.Abstractions
.
一些观察和尝试解决这个问题:
-
(2) 超过 400 个
.deps.json
文件提到了“Microsoft.Extensions.FileProviders.Physical.dll”,所有这些文件都是指版本 3.1.0.0。 -
(3) 所有相应的 DLL 都加载到 ASP.NET Core 应用程序中,其中版本不匹配似乎不会导致任何问题。
-
(4) 我的控制台应用程序本身的
.deps.json
文件没有提到“Microsoft.Extensions.FileProviders.Physical.dll”。 -
(5) 将正确版本的文件 (3.1.0.0) 放入
.exe
文件所在的目录以及.exe
文件的执行目录不会改变任何内容.FileNotFoundException
仍然出现,仍然抱怨缺少“Microsoft.Extensions.FileProviders.Physical.dll”,版本 3.1.0.0。 -
(6) 根据 a CodeProject article 中提供的有关 .NET Core 中程序集解析的信息,我试图自己从同一目录中强制加载程序集(初步代码,依赖于工作目录):
AssemblyLoadContext.Default.Resolving += (context,name) => { var dllPath = System.IO.Path.Combine(Environment.CurrentDirectory,name.Name + ".dll"); if (File.Exists(dllPath)) { return AssemblyLoadContext.Default.LoadFromAssemblyPath(dllPath); } return null; };
这似乎在某种程度上有所帮助!现在,可以加载“Microsoft.Extensions.FileProviders.Physical.dll”程序集以及大量(超过 250 个)程序集。但是,一旦需要加载“Microsoft.AspNetCore.Mvc.Abstractions”3.1.0.0(实际上不在
.exe
文件周围的任何位置),此操作就会失败。显然,它必须从其他地方加载(?) -
(7) 虽然以上似乎提供了有关版本不匹配的部分解决方案,但我们的整个源代码不包含其他出现的“AssemblyLoadContext”。因此,ASP.NET Core 应用程序显然使用其他机制避免了版本不匹配问题。
-
(8) 在构建输出设置为 Diagnostic1 的情况下构建我的控制台应用程序确认了“Microsoft.Extensions.FileProviders.Physical.dll”的可疑行为" 文件(输出的缩短摘录):
Dependency "Microsoft.Extensions.FileProviders.Physical,Version=3.1.0.0,Culture=neutral,PublicKeyToken=adb9793829ddae60". Could not resolve this reference. Could not locate the assembly "Microsoft.Extensions.FileProviders.Physical,PublicKeyToken=adb9793829ddae60". Check to make sure the assembly exists on disk. If this reference is required by your code,you may get compilation errors. For SearchPath "C:\(...)". Considered "C:\(...)\Microsoft.Extensions.FileProviders.Physical.winmd",but it didn't exist. Considered "C:\(...)\Microsoft.Extensions.FileProviders.Physical.dll",but its name "Microsoft.Extensions.FileProviders.Physical,Version=3.1.6.0,PublicKeyToken=adb9793829ddae60" didn't match the expected name "Microsoft.Extensions.FileProviders.Physical,PublicKeyToken=adb9793829ddae60". Considered "C:\(...)\Microsoft.Extensions.FileProviders.Physical.exe",but it didn't exist. required by "(A)". required by "(B)". required by "(C)".
在那里,(A)、(B) 和 (C) 是我们自己项目的程序集。但据我所知,他们的
.csproj
文件都没有提到文本“Physical”,所以我不明白为什么他们需要 DLL。 -
(9) 对于“Microsoft.AspNetCore.Mvc.Abstractions”程序集,诊断输出表示:
Dependency "Microsoft.AspNetCore.Mvc.Abstractions,PublicKeyToken=adb9793829ddae60". Could not resolve this reference. Could not locate the assembly "Microsoft.AspNetCore.Mvc.Abstractions,you may get compilation errors. For SearchPath "C:\(...)". Considered "C:\(...)\Microsoft.AspNetCore.Mvc.Abstractions.winmd",but it didn't exist. Considered "C:\(...)\Microsoft.AspNetCore.Mvc.Abstractions.dll",but it didn't exist. Considered "C:\(...)\Microsoft.AspNetCore.Mvc.Abstractions.exe",but it didn't exist. Considered "C:\(...)\Microsoft.AspNetCore.Mvc.Abstractions.winmd",but it didn't exist. required by "(B)".
再一次,(B) 是我们自己的程序集(与 (8) 中的 (B) 相同),但查看
.csproj
文件并没有发现一个“Mvc.Abstractions”出现.
我发现了几个似乎可以提供解决方案的问题,但没有一个对我有用:
-
Assembly binding redirect in .NET Core - 只是指向另一个问题(如下所列)。
-
Adding a bindingRedirect to a .Net Standard library - 答案指出 .NET Core 中不存在绑定重定向,但
.deps.json
文件可用于解析程序集。然后继续描述 .NET Framework 绑定重定向,没有提及如何处理 .NET Core 中的.deps.json
。 -
Common practice to load the dependency(different version of dll) in program - 问题是关于 .NET Core,但答案适用于 .NET Framework。对于 .NET Core,它链接到此处列出的其他问题之一。
-
How can I add an assembly binding redirect to a .net core unit test project? - 这个问题的答案似乎建议在
的解决方案app.config
文件中使用绑定重定向,尽管根据对该问题的另一条评论,这些在 .NET Core 中显然不再受支持.无论如何,建议添加<PropertyGroup> <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType> </PropertyGroup>
到
.csproj
文件(呃,哪个?我试过我的控制台应用程序之一;那是正确的吗?)对我的.deps.json
文件或我不断收到的异常没有影响,据我所知。 -
Error System.IO.FileLoadException: 'Could not load file or assembly 'log4net,Version=2.0.8.0 in .NET Core - 在这种情况下,正确的 DLL 在正确的版本中可用,只是没有复制到适当的输出文件夹。
-
.NET Core 3.1 - Could not load file or assembly System.Runtime,Version=4.2.2.0 - 这种情况下的解决方案似乎是使用另一个适合程序集引用的库/库版本。我不认为这对我来说是一种可行的方法,因为替换 Microsoft.Extensions.FileProviders.Physical 程序集可能只会在我们的 400 个以上的程序集中导致任何类型的冲突或问题,显然根据
.deps.json
提及,以某种方式使用该文件。 -
Why is my .NET framework app looking for the wrong version of the .NET core/standard platform extension assembly,and how do I fix it? - 这个问题的 OP 似乎只是偶然地进入了 .NET Core 主题,而他们实际上是在 .NET Framework 上下文中工作的。
-
FileNotFoundException when referencing DLL in .NET Core Application - 此问题集中在早期 .NET Core 版本中的缺陷,这些缺陷不再适用于 .NET Core 3.1。
-
FileNotFoundException with indirectly (.net to .net standard to NuGet) referenced DLL - 这似乎是正确 DLL 文件可用的另一种情况,只是位置不正确。
Can I control .NET Core assembly redirects programmatically? - 这个问题中的评论再次指出绑定重定向不是 .NET Core 中的解决方案。此外,答案似乎适用于编译时间。由于我们的
.csproj
文件都没有提到我观察到版本不匹配的文件,我怀疑它是从我们正在使用的第 3 方库之一中引用的,因此编译时解决方案可能不适用。
如何使指定程序集的运行时加载版本为 3.1.6.0 而不是请求的版本 3.1.0.0?或者,我如何了解运行时在运行 ASP.NET Core 应用程序时是如何执行的?
1:在 VS2019 中:工具 -> 选项 -> 项目和解决方案 -> 构建和运行 -> MSBuild 项目构建输出详细信息 -> 诊断
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)