【问题标题】:NET 5 DLL is present but does not loadNET 5 DLL 存在但未加载
【发布时间】:2022-02-23 04:26:37
【问题描述】:

这个问题是关于为什么程序集找不到位于同一文件夹中的库。据我所知,调用者的位数(x64)与无法找到的 NuGet 包(AnyCPU)一致。

即使我将所有内容重新编译到 AnyCPU,错误消息仍然存在:

Could not load file or assembly 'ChoETL.Core, Version=1.2.1.28, etc.' The system cannot find the file specified.

我发布的 NET 5 exe (x64) 文件调用了一个发布的 NET 5 库,该库在错误消息 (exe->lib->ChoETL.Core) 中调用 Nuget 包 ChoETL.Core

这是我用来构建程序 exe 和中间库 .csproj 文件的命令行。我不使用 Visual Studio,也不使用解决方案 .sln 文件。所有文件的构建都没有错误或警告。

msbuild -t:restore;publish /p:Platform=x64 /p:PlatformTarget=x64 /p:Configuration=Debug /p:TargetFramework=net5.0-windows7.0 /p:RuntimeIdentifier=win-x64  /p:PublishDir=c:\dev\holding\core.plt xxx.csproj

这是引用 ChoETL.Core 包的库的 .csproj 文件中的引用。请记住,msbuild 命令行属性会覆盖下面 csproj 文件中的 AnyCPU 值。

   <PropertyGroup>
      <UseWindowsForms>true</UseWindowsForms>
      <Platforms>AnyCPU</Platforms>
      <PlatformTarget>AnyCPU</PlatformTarget>
      <TargetFramework>net5.0-windows7.0</TargetFramework>
   </PropertyGroup>

   <ItemGroup>
      <PackageReference Include="ChoETL" Version="1.2.1.28" />
   </ItemGroup>

我认为 CorFlags 值可能是问题所在,所以我检查了它们。如下(32bitreq/prefs 为零):

Program.exe: PE32+, flags 0x9, ILONLY 1, Signed 1
Library.dll: PE32+, flags 0x9, ILONLY 1, Signed 1
ChoETL.Core: PE32, flags 0x1, ILONLY 1, Signed 0

PE32+ 表示 x64,PE32 表示 AnyCPU(如果程序集加载到 64 进程中,它将作为 64 位程序集运行)。所以,它们应该是兼容的(此外,我无法编译 NuGet 包)。

我查看了这个 SO 问题,但没有帮助。 Could not load file or assembly, system could not find the file specified

当所有三个程序集并排在同一个文件夹中时,有谁知道为什么库找不到ChoETL.Core.dll 库? 我在这个问题上花了好几天没有进展或成功。谢谢。

【问题讨论】:

  • 该程序集是否有任何其他无法找到的依赖项?
  • 感谢您的建议。这是一个有趣的问题。 ChoETL(NuGet 包)依赖于 10 或 20 个其他包,但据我所知,NET 5 SDK 项目负责所有这些包。此外,我刚刚构建了一个运行的小型测试项目,它只需要包含可执行文件的文件夹中的单个程序集。所以我不认为链式依赖是问题所在。在这一点上,这对我来说是个谜。

标签: c# msbuild .net-5


【解决方案1】:

又经过一天的调试,我的工作正常了,但我不知道具体原因。我从一个简单的控制台程序开始,然后是 exe + lib,然后是 exe + lib(称为 ChoETL),最后用我的真实系统的一部分制作了一个测试用例。当我开始对真实系统的一部分进行实验时,一切正常。但我想是脆弱的。

这里有一些可能对下一个人有帮助的理论。

一个关键问题(在失败的实际系统中)是 msbuild ... -t:clean;restore;publish 操作没有发布 ChoETL 包。我认为这是问题的主要部分。然而,当我使用相同的 msbuild 命令行构建测试实验时,ChoETL 总是在使用该包的可执行文件和库旁边正确发布。

当时,我意识到我的实验总是在开始新构建之前完全删除 bin 和 obj 文件夹,而我真正的系统构建文件并没有采取那么激烈的行动(认为 msbuild clean/restore 足以干净的构建)。但是,并非如此。 Msbuild 没那么聪明。我修改了我的真实系统构建文件,以在构建开始时完全删除 70 个项目构建序列中的所有 obj/bin 文件夹,并且 ChoETL 在使用它的程序集旁边正确发布。

最后,原来的问题解决了(但还没有真正理解)。系统可以找到 ChoETL 并加载它。我所知道的是,在开始时完全删除 obj 和 bin 文件夹可以成功构建。我不清楚 obj/bin 文件夹中的哪些文件或数据元素可能会阻止成功的发布操作。可能是 project.assets.json 文件,也可能是其他 json 文件之一。

我知道当 csproj 文件和 msbuild 命令行属性发生更改时,msbuild 不会轻易地重新生成 json 文件。由于这些问题,自从开始使用 NET 5 以来的几个月里,我养成了完全删除 obj/bin 文件夹的习惯。

我认为 msbuild 会像 make 那样进行依赖性和时间戳分析,如果 json 文件“过时”(无论在这种情况下可能意味着什么;我不知道),它们会重新生成它们。但事实并非如此。因此,我开始养成在构建之前完全删除 obj/bin 文件夹的习惯。显然,这种经历(数周的发展延迟)表明,我还有很长的路要走,才能将其发展成一种僵化的习惯。我希望这个答案可能对其他人有所帮助。

【讨论】:

  • 这些天我认为project.assets.json 文件是罪魁祸首。 VStudio 'clean;rebuild' 序列不会生成与 msbuild 相同的 JSON 文件(当 msbuild 缺少 json 文件时)。如果 json 文件存在(即使不正确),msbuild 也不会用正确的 json 文件覆盖它。在运行 msbuild 之前删除 obj/bin 文件夹会删除该文件,以便 msbuild 为 msbuild 重新生成正确的文件夹。我猜想在 csproj 文件中添加一个 win-x64 的 PlatformTarget 可能会使 VStudio 生成正确的文件,但我没有测试过这个想法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-21
相关资源
最近更新 更多