MSBuild - 一个包参考会干扰加载单独的任务

Posted

技术标签:

【中文标题】MSBuild - 一个包参考会干扰加载单独的任务【英文标题】:MSBuild - one Package Reference interferes with loading a separate Task 【发布时间】:2021-04-09 17:31:42 【问题描述】:

使用 MSBuild,以下构建和工作正常:

<PackageReference Include="Publicise.MSBuild.Task" Version="1.3.0"/>

<Target Name="Publicise" BeforeTargets="BeforeBuild">
  <Publicise
    AssemblyPath="..."
    OutputPath="../"/>
</Target>

但是,当我添加另一个包引用(不更改其他内容)时,它会在构建时遇到错误:

<PackageReference Include="Publicise.MSBuild.Task" Version="1.3.0"/>
<PackageReference Include="ILRepack.MSBuild.Task" Version="2.0.13"/>

这会导致错误 MSB4062:

无法从程序集...\ILRepack.MSBuild.Task.dll 加载“公开”任务。确认声明正确,程序集及其所有依赖项都可用,并且任务包含实现 Microsoft.Build.Framework.ITask 的公共类。

为什么完全独立的东西会阻止正确找到任务,我该如何解决这个问题?

【问题讨论】:

【参考方案1】:

此问题是由这两个 msbuild 任务 nuget 包意外引起的。

并且,因为您最后安装了 ILRepack.MSBuild.Task nuget 包。 ILRepack.MSBuild.TaskPackageReference 节点在最后。所以$(TaskAssembly) 总是从ILRepack.MSBuild.Task nuget 包加载,publicise.msbuild.task 的值被覆盖。而The "Publicise" task could not be loaded from the assembly ILRepack.MSBuild.Task.dll 的问题是有道理的。

C:\Users\xxx\.nuget\packages\publicise.msbuild.task\1.3.0\build\Publicise.MSBuild.Task.props

C:\Users\xxx\.nuget\packages\ilrepack.msbuild.task\2.0.13\build\ILRepack.MSBuild.Task.props

另外,当你项目加载nuget包时,可以在C:\xxx\source\repos\xxx(project_name)\xxx(project_name)\obj\xxx.csproj.nuget.g.props下查看:

加载ILRepack.MSBuild.Task.props总是在最后,$(TaskAssembly)总是来自ilrepack.msbuild.task,因为被后来安装的包覆盖了。

可以理解来自ilrepack.msbuild.task的错误Publicise任务(应该来自publicise.msbuild.task)。

解决方案

所以你应该把publicise.msbuild.task放在最后。

解决方案 1)

打开C:\xxx\source\repos\xxx(project_name)\xxx(project_name)\obj\xxx.csproj.nuget.g.props文件,

修改如下:

<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
   
 <Import Project="$(NuGetPackageRoot)ilrepack.msbuild.task\2.0.13\build\ILRepack.MSBuild.Task.props" Condition="Exists('$(NuGetPackageRoot)ilrepack.msbuild.task\2.0.13\build\ILRepack.MSBuild.Task.props')" />

 <Import Project="$(NuGetPackageRoot)publicise.msbuild.task\1.3.0\build\Publicise.MSBuild.Task.props" Condition="Exists('$(NuGetPackageRoot)publicise.msbuild.task\1.3.0\build\Publicise.MSBuild.Task.props')" />
</ImportGroup>

在底部设置Publicise.MSBuild.Task.props

然后,保存更改,然后单击Build按钮而不是Rebuild按钮再次测试。

解决方案 2)

ILRepack.MSBuild.Task nuget 包降级到版本2.0.0

=================================

更新 1

感谢您分享您对解决方法的意见。由于这两个 nuget 包必须在您的项目中使用,因此这两个解决方案可能不是很有用。

错误,冲突是由 nuget 包的作者引起的,顺便说一下,您同时使用了这两个 nuget 包中相同的 TaskAssembly 属性。

TreatAsLocalProperty="TaskAssembly" 不会解决问题。 nuget 包中的&lt;packages_id&gt;.props 文件仍嵌入在项目的 CSPROj 文件中。字段是否与 TaskAssembly 相同或会冲突。

更好的解决方案是你应该将nuget包的TaskAssembly之一重命名为另一个,这样不会引起冲突。

1)打开C:\Users\xxx\.nuget\packages\ilrepack.msbuild.task\2.0.13\build\ILRepack.MSBuild.Task.props文件:

TaskAssembly 属性更改为另一个类似TaskAssembly_copy

【讨论】:

您好,这是一个不错的开始,但是这些解决方案都没有完全适合我。我不能只更改 .csproj.nuget.g.props 文件中的顺序,因为还有一个 ILRepack 任务。我不能将 ILREpack.MSBuild.Tasks 降级到 2.0.0,因为它与我必须使用的 net40 不兼容。需要明确的是,问题是由两个项目共享相同的TaskAssembly 属性引起的?为什么TreatAsLocalProperty="TaskAssembly" 不阻止这个问题?分叉其中一个并更改该属性名称是一个可行的解决方案吗? 我已经更新了我的答案,你可以查看update 1

以上是关于MSBuild - 一个包参考会干扰加载单独的任务的主要内容,如果未能解决你的问题,请参考以下文章

自定义 MsBuild 任务因程序集加载错误而失败

未能从程序集 C:Program Files (x86)MSBuild14.0inMicrosoft.Data.Entity.Build.Tasks.dll 加载任务“EntityClea(示例代码

MSBuild 社区任务的 Intellisense 不起作用

MSBuild 还原给出“请求被中止:无法创建 SSL/TLS 安全通道。”

CruiseControl.Net 在使用 msbuild 任务的项目后重新启动

使用 MSBuild 将输出项传递给单独的目标