在作为Windows服务运行的自包含 .Net Core Web应用程序中引用嵌套DLL的问题

3

错误信息

首先,让我们看一下错误信息:

System.BadImageFormatException:“无法加载文件或程序集'System.Management, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'。 引用程序集不应在执行过程中加载。 它们只能在反射加载器上下文中加载。(0x80131058)”

根据我的经验,这种类型的错误通常是由于缺少DLL文件或者文件格式/版本不符合预期导致的。然而,我无法确定如何解决此错误。

设置

主要项目是一个ASP.Net Core 3.1应用程序。

它配置为能够作为Windows服务运行并支持Web API和MVC框架。因此,我的Program.cs看起来像这样:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        var builder = Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });

        builder.UseWindowsService();

        return builder;
    }
}

那部分都很好,我可以将应用程序作为Windows服务运行并提供剃刀视图和Web API端点等。

然而,在此解决方案中还有更多的项目。我有几个.NET 4.6类库项目被服务应用程序引用。因此,我的解决方案看起来像这样:

  • 服务应用程序(NET CORE 3.1)
  • Lib 1(NET 4.6)
  • Lib 2(NET 4.6)

Service App引用Lib 1,并且Lib 1引用Lib 2。

任何这两个库中的代码都可以正常工作,并且可以被服务应用程序使用。

问题在于Lib 2引用了System.Management DLL,这就是导致错误的原因。每当我使用一个使用该DLL的函数时,我就会收到上面的错误。

迄今为止的尝试

我迄今为止的尝试包括:

  • 将DLL设置为“复制到输出”
  • 直接将DLL引用添加到Web服务应用程序中
  • 手动将DLL复制到输出文件夹。调试和发布文件夹(注意:发布设置为“自包含”应用程序)

问题

基本上,我如何解决这个问题?或者至少,我如何进一步调试问题以潜在地找到解决方案。


1
System.Management是.NET Framework的一部分,但在.NET Core中,它显然会从Program Files复制引用程序集。这样是行不通的。如果您在服务应用程序中安装System.Management包,会发生什么呢? - undefined
@CodeCaster... 哇... 它起作用了 :D 这很奇怪,因为我记得几周前最后一次研究这个问题时,我认为同样的版本实际上是不可用的... 但是我也一直在尝试使用Microsoft.Management,所以可能是我把自己搞混了。无论如何,感谢你的帮助。请发布一个答案,你将获得积分! - undefined
1个回答

3

目前我无法重现这个问题,但我怀疑使用 dotnet publish 进行自包含发布时解析传递依赖的方式存在错误。

问题在于,你的 .NET Core 3.1 应用程序 无法在 .NET Framework 上运行,而你引用的库(称之为“Lib 2”)可以。

你的 Lib 2 引用了 NuGet 包 System.Management,在针对 .NET Framework 的项目上安装它时……除了让你的项目引用 C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1 中找到的 .NET Framework 引用程序集的 System.Management 外,什么都不会发生。运行时,.NET Framework 将从 GAC 加载适当的程序集,但 .NET Core 运行时不会这样做。

现在,在发布您的.NET Core应用程序时,MSBuild会遍历要复制的依赖项,并(我猜)查看参考程序集并执行“我想要那个!”然后将其复制到输出目录中。但是,您无法运行参考程序集,只能引用它们,因此在运行时,您的应用程序会崩溃,并显示以下异常:引用程序集不应加载以执行。一种解决方法是从您的.NET Core应用程序中引用相同的System.Management包,该包实际上会提取一个包含可运行代码的DLL,并将其复制到输出目录中。但这可能会导致其他问题,例如在构建过程中使用引用文件覆盖DLL。我建议查看GitHub,了解是否已知此问题,或者这是由项目设置引起的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接