.NET 5自定义MSBuild Task运行出现程序集加载错误如何解决?
核心原因
这个报错的本质是自定义MSBuild Task的编译目标框架,和运行构建的MSBuild所在的运行时环境不兼容:
你用.NET 5开发的Task,编译时依赖的是.NET 5版本的基础类库(比如System.Diagnostics.Process 5.0.0.0、System.Runtime 5.0.0.0),而如果调用构建的是.NET Framework 版本的MSBuild(比如Visual Studio内置的生成工具、直接调用msbuild.exe),其运行时自带的基础类库都是.NET Framework版本,和.NET 5的版本不匹配,就会抛出程序集加载失败的异常。
你移除对应代码后不再报错,是因为移除相关逻辑后,运行时无需再加载对应依赖的高版本程序集,属于临时绕开了问题,不是根本解决。
排查步骤
- 先确认触发构建的命令:如果是直接调用
msbuild.exe或者在Visual Studio中点击生成,用的就是.NET Framework版本的MSBuild;如果是调用dotnet build,用的是.NET 运行时版本的MSBuild - 检查自定义MSBuild Task项目的目标框架配置:确认项目文件里的
<TargetFramework>或者<TargetFrameworks>配置是否匹配你要使用的构建工具的运行时 - 检查Task的发布产物:确认部署到构建流程的Task目录下,包含了所有依赖的程序集,不是只有单独的Task主dll
解决方法
方案1:统一使用dotnet命令构建
直接用dotnet build命令构建你的Application项目,.NET版MSBuild可以正常加载.NET 5开发的自定义Task,不需要修改Task代码。
方案2:兼容.NET Framework版MSBuild
如果需要支持Visual Studio内置生成等依赖.NET Framework版MSBuild的场景,将自定义Task项目的目标框架改为netstandard2.0,确认所有使用的API都属于netstandard2.0支持范围后重新编译Task即可,netstandard2.0可以同时被.NET Framework和.NET 5+运行时兼容。
方案3:多版本兼容配置
如果需要同时支持两种运行时的MSBuild,可以给Task项目配置多目标框架,同时编译出netstandard2.0和net5.0版本的Task,再在引入Task的.targets文件中根据MSBuild运行时变量,自动选择加载对应版本的Task程序集。
内容的提问来源于stack exchange,提问作者Babak Fakhriloo

