MSBuild将动态生成的文件复制为项目依赖项的一部分

我有一个自定义的msbuild任务,它生成一些输出文件到ProjectA的输出目录($(TargetDir))。 目前的代码是这样的:

   

ProjectB正在引用ProjectA,但问题是在构建ProjectB时,MyCustomTask生成的文件不会复制到ProjectB的输出目录中。

我们如何使用MSBuild将动态生成的附加文件作为项目依赖项的一部分进行复制?

我终于设法自动执行项目B的副本而无需修改它。 IIya离解决方案不远,但事实是我无法静态生成, 因为使用MyCustomTask从项目A生成的文件列表是动态的。 在深入了解Microsoft.Common.targets ,我发现ProjectB将通过调用目标GetCopyToOutputDirectoryItems来获取项目A的输出列表。 此目标依赖于AssignTargetPaths ,它本身依赖于目标列表属性AssignTargetPathsDependsOn

因此,为了生成动态内容并通过标准项目依赖项自动复制此内容,我们需要在两个不同的位置挂钩项目A.

  • AssignTargetPathsDependsOn因为它在项目A上通过GetCopyToOutputDirectoryItems由项目B间接调用。 而且,当PrepareResource时, 项目A会间接调用它。 在这里,我们只输出将由项目A生成或由项目B使用的文件列表。 AssignTargetPathsDependsOn将调用自定义任务MyCustomTaskList ,它只负责输出文件列表(但不生成它们),这个文件列表将使用CopyOutputDirectory创建动态“内容”。
  • BuildDependsOn中,以便在Project A中实际生成内容。 这将调用将生成内容的MyCustomTask

所有这些都是在ProjectA中设置的:

         MyCustomTaskTarget; $(BuildDependsOn);               $(AssignTargetPathsDependsOn); MyCustomTaskListTarget;             

此方法适用于使用Common.Targets的任何C#项目(因此它与纯桌面,WinRT XAML应用程序或Windows Phone 8项目一起使用)。

这样的东西似乎工作,要么手动将其包含在ProjectA的.csproj中(请记住VS有一个坏习惯,即偶尔将通配符解析为绝对路径并覆盖.csproj)或由自定义任务本身动态注入。 此外,VS在打开时缓存项目组,因此它可能不会复制文件或如果它们在那里但是已删除而使构建失败。 在这种情况下,需要重新加载项目或重新启动VS以重新评估项目组。 MSBuild,TFS等应始终有效。

   %(Filename)%(Extension) PreserveNewest   

如果您已经使用MSBuild自行构建,可以添加一个复制任务来推送自己的文件吗?

据我所知,你想通过在ProjectB.msbuild中只写这一行来增加额外的步骤:

  

要实现它,您可以编写类似ProjectA中的内容:

  $(BuildDependsOn);MyCustomTask  

这会将您的任务添加到Build任务的依赖项列表中。

有关详细信息,请参阅此问题: StyleCop MS Build magic? 谁在调用StyleCop目标?