MSBuild的动态生成的文件复制作为项目依赖的一部分 [英] MSBuild to copy dynamically generated files as part of project dependency

查看:59
本文介绍了MSBuild的动态生成的文件复制作为项目依赖的一部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个是产生了一些文件输出到项目A的输出目录($(TARGETDIR))的自定义MSBuild任务。当前code是这样的:

I have a custom msbuild task that is generating some output files to the output directory ($(TargetDir)) of a ProjectA. Current code is something like this:

<MyCustomTask ...>
   <Output TaskParameter="OutputFiles" ItemName="FileWrites"/>
</MyCustomTask>

一个项目B所引用的项目A 的,但问题是,建设项目B时,产生由MyCustomTask文件不会被复制到项目B的输出目录。

A ProjectB is referencing ProjectA but the problem is that when building ProjectB, generated files by MyCustomTask are not copied to the output directory of the ProjectB.

我们怎样才能动态生成的额外的文件复制与MSBuild项目依赖的一部分?

How can we get dynamically generated additional files to be copied as part of project dependency with MSBuild?

推荐答案

我终于成功地从的项目B 的自动进行复制,而无需修改。 IIya不是从溶液中,到目前为止,但事实是,我不能静态生成的文件列表,从的项目A 的生成MyCustomTask是动态的。挖多进 Microsoft.Common.targets 之后,我发现项目B从的项目A 的获取输出列表中通过调用目标 GetCop​​yToOutputDirectoryItems 。这个目标是依赖从 AssignTargetPaths 这本身就是依赖于目标列表属性 AssignTargetPathsDependsOn

I have finally managed to perform automatically the copy from Project B without having to modify it. IIya was not so far from the solution, but the fact is that I cannot generate statically as the list of files to generate from Project A with MyCustomTask is dynamic. After digging more into Microsoft.Common.targets, I have found that ProjectB will get the list of output from Project A by calling the target GetCopyToOutputDirectoryItems. This target is dependent from AssignTargetPaths which itself is dependent on the target list property AssignTargetPathsDependsOn.

因此​​,为了生成动态内容,并获得此内容正在通过标准的项目依赖关系自动复制,我们需要挂钩的项目A 的在两个不同的地方:

So in order to generate dynamically content and to get this content being copied automatically through standard project dependency, we need to hook Project A at two different places:


  • AssignTargetPathsDependsOn ,因为它是间接的项目B 的通过GetCop​​yToOutputDirectoryItems呼吁的项目A 的。而且它是间接的项目A 的当 prepareResource 被称为调用。在这里,我们只是允许输出将生成文件的列表(由项目A 的)或消耗的项目B 的。 AssignTargetPathsDependsOn将调用自定义任务 MyCustomTaskList 这是只负责输出文件的列表(而不是生成它们),此文件列表将建立动态的内容与 CopyOutputDirectory

  • BuildDependsOn ,以实际产生的项目A 的内容。这将调用 MyCustomTask ,将产生的内容。

  • In AssignTargetPathsDependsOn as it is called indirectly by Project B on Project A through GetCopyToOutputDirectoryItems. And also it is indirectly called by Project A when PrepareResource is called. Here, we are just outputing the list of files that will be generated (by Project A) or consumed by Project B. AssignTargetPathsDependsOn will call a custom task MyCustomTaskList which is only responsible to output the list of files (but not to generate them), this list of files will create dynamic "Content" with CopyOutputDirectory.
  • In BuildDependsOn in order to actually generate the content in Project A. This will call MyCustomTask that will generate the content.

这一切是项目A的设置是这样的:

All of this was setup like this in ProjectA:

<!-- In Project A -->

<!-- Task to generate the files -->
<UsingTask TaskName="MyCustomTask" AssemblyFile="$(PathToMyCustomTaskAssembly)"/>

<!-- Task to output the list of generated of files - It doesn't generate the file -->
<UsingTask TaskName="MyCustomTaskList" AssemblyFile="$(PathToMyCustomTaskAssembly)"/>

<!-- 1st PART : When Project A is built, It will generate effectively the files -->
<PropertyGroup>
  <BuildDependsOn>
    MyCustomTaskTarget;
    $(BuildDependsOn);
  </BuildDependsOn>
</PropertyGroup>

<Target Name="MyCustomTaskTarget">
  <!-- Call MyCustomTask generate the files files that will be generated by MyCustomTask -->
  <MyCustomTask
      ProjectDirectory="$(ProjectDir)"
      IntermediateDirectory="$(IntermediateOutputPath)"
      Files="@(MyCustomFiles)"
      RootNamespace="$(RootNamespace)"
      >
  </MyCustomTask>
</Target>

<!-- 2nd PART : When Project B is built, It will call GetCopyToOutputDirectoryItems on ProjectA so we need to generate this list when it is called  -->
<!-- For this we need to override AssignTargetPathsDependsOn in order to generate the list of files -->
<!-- as GetCopyToOutputDirectoryItems  ultimately depends on AssignTargetPathsDependsOn -->
<!-- Content need to be generated before AssignTargets, because AssignTargets will prepare all files to be copied later by GetCopyToOutputDirectoryItems -->
<!-- This part is also called from ProjectA when target 'PrepareResources' is called -->
<PropertyGroup>
  <AssignTargetPathsDependsOn>
    $(AssignTargetPathsDependsOn);
    MyCustomTaskListTarget;
  </AssignTargetPathsDependsOn>
</PropertyGroup>

<Target Name="MyCustomTaskListTarget">

  <!-- Call MyCustomTaskList generating the list of files that will be generated by MyCustomTask -->
  <MyCustomTaskList
      ProjectDirectory="$(ProjectDir)"
      IntermediateDirectory="$(IntermediateOutputPath)"
      Files="@(MyCustomFiles)"
      RootNamespace="$(RootNamespace)"
      >
      <Output TaskParameter="ContentFiles" ItemName="MyCustomContent"/>
  </MyCustomTaskList>

  <ItemGroup>
    <!--Generate the lsit of content generated by MyCustomTask -->
    <Content Include="@(MyCustomContent)" KeepMetadata="Link;CopyToOutputDirectory"/>
  </ItemGroup>
</Target>

这方法正在与anykind正在使用Common.Targets C#项目(因此它正在与纯桌面的WinRT XAML应用程序或Windows Phone 8个项目)。

This method is working with anykind of C# projects that is using Common.Targets (so It is working with pure Desktop, WinRT XAML App or Windows Phone 8 projects).

这篇关于MSBuild的动态生成的文件复制作为项目依赖的一部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆