【问题标题】:'Could not load file or assembly 'netstandard, Version=2.0.0.0, ...'. Reference assemblies should not be loaded for execution'无法加载文件或程序集'netstandard,Version = 2.0.0.0,...'。不应加载引用程序集以执行
【发布时间】:2017-12-14 18:33:49
【问题描述】:

目标: 从 .NET 4.7 控制台应用程序中,使用带有 Assembly.GetType() 的反射,我尝试从 Assembly X 中提取 netstandard 2.0 类的类型。然后我想使用 Activator.CreateInstance() 创建此类型的实例。

我想要做什么: 然而,这个程序集 X 依赖于 netstandard 2.0。为了能够获取类型,必须将 netstandard 依赖项加载到 AppDomain 中。这就是为什么当 AppDomain 通过 AssemblyResolve 事件请求 netstandard 程序集时,我只需像这样加载 dll:

var netStandardDllPath = @"C:\Users\xxx\.nuget\packages\NETStandard.Library.2.0.0-preview1-25301-01\build\netstandard2.0\ref\netstandard.dll";

return Assembly.LoadFrom(netStandardDllPath);

哪个抛出:

System.BadImageFormatException: '无法加载文件或程序集 'file:///C:\Users\vincent.lerouvillois.nuget\packages\NETStandard.Library.2.0.0-preview1-25301-01\build\netstandard2.0\ref\netstandard.dll' 或其依赖项之一。不应加载引用程序集 执行。它们只能在 Reflection-only loader 中加载 语境。 (来自 HRESULT 的异常:0x80131058)'

内部异常:BadImageFormatException:无法加载引用 执行程序集。

我所知道的: 我知道他们希望我们使用 Assembly.ReflectionOnlyLoadFrom 加载 DLL。但是这样做会阻止我使用 Activator.CreateInstance() 实例化类型。见Microsoft official post

另外,我尝试在我的控制台应用程序中引用 Nuget 包 NETStandard.Library 2.0.0-preview1-25301-01 和 NETStandard.Library.NETFramework 2.0.0-preview1-25305-02,这样它就有了 netstandard 2.0 库引用,但它没有改变任何东西。

问题: 有谁会知道是否有正确的方法来加载该 dll 而不会出错,或者这是否是一个错误,或者其他?或者为什么这种dll无法加载执行?

【问题讨论】:

  • 永远,永远不要加载参考程序集,它们只适合构建您的程序。这是错误的,因为您编写了 AssemblyResolve 事件处理程序,没有它应该可以正常工作。关键是让 CLR 找出包含该类型的真正运行时程序集,this workaround 也适用于 .NETCore。

标签: c# .net dll .net-assembly .net-standard


【解决方案1】:

NETStandard 2.0.0-preview1 与 net461 和 net47 不兼容。

但对于真正的 .NET Core SDK 2.0 程序集(以及 2.0.0-preview2)

 var netStandardDllPath = @"c:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\netstandard.dll";
 Console.WriteLine(Assembly.LoadFrom(netStandardDllPath).FullName);

一切正常。

但是如果你需要加载preview1库,也许你应该使用netstandard2.0而不是net471。

【讨论】:

  • 您要小心不要使用 netstandard.dll,因为它用于 .NET Core 应用程序,并且在尝试在 .NET Framework 上运行时可能会导致其他问题。请参阅我的答案,了解在哪里可以找到 .NET Framework 版本。
【解决方案2】:

您无法加载参考程序集。

.NET Standard 是一组 API,必须由 .NET Standard 兼容的实现提供。

参考程序集仅包含合同。这意味着它不包含任何实现。您尝试加载的程序集包含 .NET Standard 2.0 合同。

合同如下所示:https://github.com/dotnet/standard/blob/master/netstandard/ref/mscorlib.cs

编辑: .NET Framework 4.7 实现了 .NET Standard 2.0,因此您无需加载任何程序集即可使用 Activator.CreateInstance() 来实例化 .NET Standard 类型。

【讨论】:

    【解决方案3】:

    您尝试加载的 netstandard.dll 是一个参考程序集,正如其他人指出的那样,它无法在 .NET Framework 上运行时加载。但是,如果您需要解决该依赖关系,则需要映射到您尝试运行的框架的运行时版本。

    对于 .NET Standard 支持,我们将它们作为 VS 附带的 msbuild 扩展的一部分包含在内,因此您需要从那里获取 netstandard.dll 的版本。根据您安装的 VS2017 版本,它应该位于 C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\netstandard.dll 之类的位置,或者您可以从 .NET Core 2.0 SDK 中找到它 C:\Program Files\dotnet\sdk\2.0.0\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\netstandard.dll

    尝试在您的场景中使用其中一个版本。

    【讨论】:

    • 谢谢,我在这里找到了一个适合我的:C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461 \lib\netstandard.dll。我需要它用于 xUnit 控制台测试运行器。我在我的目标机器上运行 .Net Framework 4.5.2,这个 4.6.1 netstandard.dll 对我来说适用于 xUnit。
    • 我通过在 .csproj 末尾添加以下内容来解决此问题:C:\ Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\netstandard.dllTrue
    • 哇,谢谢。我花了一整天的时间来解决这个问题。将 netstandard.dll 文件上传到部署的 bin 文件夹为我解决了这个问题。
    【解决方案4】:

    在 netstandard.dll 属性中将 Copy Local 设置为 true。

    1. 打开解决方案资源管理器并右键单击 netstandard.dll。
    2. Copy Local 设置为true。

    【讨论】:

    • 这帮助我解决了我在部署 wpf 应用程序时遇到的问题。非常感谢!
    • 我以前从来不需要这样做。为什么它突然停止工作,为什么它之前工作?让我非常怀疑这是“正确”的解决方案......
    【解决方案5】:

    从 NuGet 安装 NetStandard.Library 2.0.0.0,它对我有用。当我将 .net 框架 4.6.1 降级到 4.6.0

    【讨论】:

      【解决方案6】:

      对我来说,解决了以下问题: 1 - 在服务器上安装了最新的 .Net Framework。 2 - 更新了 Windows 服务器和我的本地机器。 3 - 去管理 Nuget 包并更新更新选项卡上的所有引用。

      也许只有做第 3 步才能解决你的情况

      【讨论】:

        【解决方案7】:

        哇。我只是花了几个小时来跟踪这个“无法加载...... netstandard”错误的原因。

        对我来说,问题在于我的 .NET Framework 项目(引用 .NET Framework 和 .NET Standard 库)是使用 .NET Framework 4.7.2 构建的,而我部署和运行它的系统没有4.7.2 已安装。

        部署一个具有相同基本结构和引用的非常小的控制台项目并在命令窗口中执行,最终在弹出窗口中显示正确的错误,即缺少 .NET Framework 4.7.2。

        如果您遇到此特定错误,请确保您已安装必要的 .NET Framework。

        【讨论】:

        • 这种情况的一个线索(对我来说就是这样)是,如果您有一个环境工作属性,而另一个没有,即使应用程序文件相同。感谢您指出 MikeZ。
        • 对我来说,当我开始使用 C#7 和 C#8 功能时,也出现了同样的问题。我所有的项目都以 .NET 4.6.1 为目标,并且在我的机器上编译得很好(安装了 .NET 4.8)。但是,一旦部署在服务器上(没有 .NET 4.8),它就无法运行,给我带来了很多奇怪的错误,包括这个。我花了 1.5 天的时间才意识到我需要服务器上的 4.8 运行时,即使我的项目没有专门针对它。此外,使用 UnityContainer 的人的注意事项 - 您可能会得到“当前类型,是一个接口,无法构造。你错过了类型映射吗?错误,也与此有关。
        • 谢谢,这解决了我使用 AWS PowerShell 工具的问题!
        【解决方案8】:

        如果项目解决方案中使用了IBM Message Queue引用,则此异常表明用于引用MQ类的DLL与安装的主机(服务器).NET版本不兼容。

        在这种情况下,我们需要使用最新更新更新服务器并确保 .NET 最新版本可用,或者使用较低版本的 IBM 消息队列 DLL 作为参考。

        旧版本 DLL - amqmdnet.dll(IBM 不会引入新功能,因为不支持)

        最新版本的 DLL - amqmdnetstd.dll(要为 .NET Standard 运行 IBM MQ 类,您必须安装 Microsoft .NET Core)

        【讨论】:

          【解决方案9】:

          如果您在以前可以运行的项目中遇到此问题,请尝试删除 binobj 文件夹,因为缓存也会导致此问题。

          【讨论】:

            猜你喜欢
            • 2018-10-04
            • 2018-09-30
            • 2019-04-11
            • 2021-05-02
            • 2020-01-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多