MSBuild错误MSB4018无法访问NET 5构建中的project.assets.json

2024-02-02

MSBuild错误MSB4018无法在.NET 5构建操作中访问project.assets.json MSBuild 错误 MSB4018

我正在并行组中构建 70 个 C# NET 5 项目,有时在构建中的随机项目上会出现以下错误

错误 MSB4018:“GenerateDepsFile”任务意外失败。 [c:\dev\highspeed\HsCore\hscore\HsCore.csproj] C:..\sdk\6.0.202\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.targets(172,5): 错误 MSB4018: System.IO.IOException: 该进程无法访问 文件 'c:\dev\highspeed\HsCore\hscore\bin\Debug\net5.0-windows7.0\win-x64\HsCore.deps.json' 因为它正在被另一个进程使用。 [c:\dev\highspeed\HsCore\hscore\HsCore.csproj]

Microsoft 文档说:当任务因未处理的异常而失败时,会发出此错误。这通常是任务中存在错误的迹象。在未准备好的环境中运行任务时可能会导致错误 MSB4018,例如,当任务具有 x86 依赖项但在 64 位 MSBuild 环境中运行时。这可能表现为 System.DllNotFoundException。

就我而言,我完全在 Windows x64 环境中构建和使用 AnyCPU 库(并发布到 win-x64,但这在构建运行之前并不重要)。 我使用以下参数调用 xxx.sln 文件上的构建:

退出代码 1:/t:Clean;Restore;Publish /p:Platform="Any CPU" /p:Configuration=调试 /p:TargetFramework=net5.0-windows7.0 /p:RuntimeIdentifier=win-x64 "c:\path\MySolution.sln"

代码通常可以正常构建并运行,除非发生此类错误。通常,当我第二次运行构建时,构建会成功。

我不明白为什么 MSBuild 进程(或其进程之一)无法访问项目.assets.json文件,因为 MSBuild 是该项目中唯一访问该文件的人。我的工具都没有引用该文件; Visual Studio 没有打开文件或项目;并行构建组中的其他项目都不会访问项目.assets.json无论如何都要归档;因此 MSBuild 是唯一一个可以处理整个项目树的软件。

我能想到的最好的办法是,也许恢复目标清理;恢复;发布链可能会锁定文件,并且释放速度不够快,无法进行发布(包括构建)操作。但 MSBuild 是否足够聪明来管理这类事情呢?

有人知道会发生什么吗?还有哪些其他进程可能正在查看(并锁定)该文件?谢谢


经过几天的调试和调查,我确信问题是由在构建解决方案 (.sln) 文件时使用 MSBuild 多核操作 (-m:) 引起的。

如果我删除 -m MSBuild 命令行参数,所有奇怪的“文件正在被另一个进程使用”错误立即消失。如果我启用 -m:2 参数(或更高,或无界 -m),错误会立即返回。

我失败的 .sln 文件通常包含三个 .csproj 项目 - 一个库 DLL 项目、一个 LibraryXxxTests 项目和一个到库的瘦控制台程序接口。测试和控制台项目通常使用对库项目的项目引用。

也许(但我无法想象为什么)指向库项目的项目引用为 MSBuild 并行性错误打开了大门。 (但是 MSBuild -m 应该足够聪明,可以在控制台和引用库 DLL 的测试项目之前首先查看项目引用并构建库项目,是吗?)

另一种有时会失败的项目只有两个项目(lib 和测试项目)。

我的解决方案文件和项目文件没有做任何特殊或棘手的事情 - 据我所知,它们是具有 20 - 50 个 C# 文件的典型 C# 项目。当某些进程尝试写入该 .DLL 文件但由于锁定而无法执行时,构建生成的主 DLL 文件 (Library.DLL) 上会出现错误。我不知道为什么。

但我确实知道,如果删除 MSBuild -m 命令行参数,错误就会消失。回到我的解决方案级别的串行构建......

更新:我想相信 MSBuild 可以找出解决方案文件中项目之间的构建顺序,因此我在网上进行了更多搜索。我在中找到了此信息有关如何计算构建的 MSBuild 文档 https://learn.microsoft.com/en-us/visualstudio/msbuild/build-process-overview?view=vs-2022.

图表选项

如果指定图形构建开关(-graphBuild 或 -graph), ProjectReference 成为 MSBuild 使用的一流概念。 MSBuild 将解析所有项目并构建构建顺序 graph,项目的实际依赖图,然后遍历 以确定构建顺序。与各个项目的目标一样, MSBuild 确保引用的项目是在项目之后构建的 他们依赖。

将 -graph 选项与 -m 选项一起使用似乎适用于解决方案级构建(将 .sln 文件传递​​到 MSBuild)。 graph 选项告诉它计算每个解决方案文件中项目之间的构建顺序图。 -m -graph 组合似乎让我可以使用多个核心在更短的时间内进行构建,而 MSBuild 不会在解决方案中的项目之间出现访问错误。

请记住,此方法要求您在项目 XML 文件中使用 ProjectReferences。如果您使用对存储在其他位置的project.DLL 的直接程序集引用,则-graph 选项无法计算解决方案中正确的构建顺序。

更新2:

上面有关使用 -graph 的信息似乎有帮助,但并没有解决所有问题。我很幸运地找到了以下内容GitHub 上的信息 https://github.com/dotnet/sdk/issues/9964:

我很想将其称为 #9585 的重复项,它本身并不是 第一次发现这个问题,但找不到原文。

每当您显式传递 --framework (CLI) 或 /p:TargetFramework=(直接 MSBuild)来构建解决方案。这 问题是全局属性(例如 TF 设置) 大多数情况下都会遗传,但不是全部。这里是 ClassLibrary1 项目 使用显式 TF 构建一次(从解决方案构建继承) 一次没有 TF(因为它只有一个,来自的 ProjectReference WebApplication1 不会向下传递其 TF)。

解决这个问题的最佳方法是仅将 --framework 传递给构建 个别项目,而不是解决方案。项目到项目的参考是 小心不要陷入这种情况。

到目前为止,在构建 .SLN 文件时从 msbuild 命令行中删除 /p:TargetFramework=win-x64 似乎对我有用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MSBuild错误MSB4018无法访问NET 5构建中的project.assets.json 的相关文章

随机推荐