Passing Items to MSBuild Task

2020-02-12 17:35发布

问题:

I would like to use the "MSBuild" task in my target in order to build another project, while passing some items (with their metadata) from the current project to the project to be built.
While it's possible to pass properties using the Properties attribute or the AdditionalProperties Metadata, I couldn't find a way to pass Items.
A possible solution could be to write the items to a file and pass the filename as a property, but this would pass only the items, without their metadata.

Any idea?

Thanks.

回答1:

It is fairly straightforward to write a custom task to dump items and their metadata to a file, to be picked up by another process. Instead of just dumping the items in raw text form though, generate a valid MSBuild project file containing the item group (with item meta data) and have that generated file imported by the project being executed by the MSBuild task. You can even use an MSBuild 4.0 inline task to dump the file.

(response to comment)

<UsingTask
  TaskName="WriteItemsWithMetadata"
  TaskFactory="CodeTaskFactory"
  AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
  <ParameterGroup>
    <OutputFile ParameterType="System.String" Required="true" />
    <Items ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
  </ParameterGroup>
  <Task>
    <Using Namespace="System.IO" />
    <Code Type="Fragment" Language="cs">
  <![CDATA[
  // This code simplified with specific knowledge
  // of the item metadata names.  See ITaskItem
  // documentation to enable writing out arbitrary
  // meta data values
  //
  using (StreamWriter writer = new StreamWriter(OutputFile))
  {
    writer.Write("<?");
    writer.WriteLine(" version=\"1.0\" encoding=\"utf-8\"?>");
    writer.WriteLine("<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\"");
    writer.WriteLine("  ToolsVersion=\"4.0\">");
    writer.WriteLine("  <ItemGroup>");

    foreach (var item in Items)
    {
      string meta1 = item.GetMetadata("Meta1");
      string meta2 = item.GetMetadata("Meta2");
      writer.WriteLine("    <CopyItem Include=\"{0}\">", item.ItemSpec);
      writer.WriteLine("      <Meta1>{0}</Meta1>", meta1);
      writer.WriteLine("      <Meta2>{0}</Meta2>", meta2);
      writer.WriteLine("    </CopyItem>");
    }
    writer.WriteLine("  </ItemGroup>");    
    writer.WriteLine("</Project>");    
  }
  ]]>
    </Code>
  </Task>
</UsingTask>

<ItemGroup>
  <OriginalItem Include="A">
    <Meta1>A1</Meta1>
    <Meta2>A2</Meta2>
  </OriginalItem>
  <OriginalItem Include="B">
    <Meta1>B1</Meta1>
    <Meta2>B2</Meta2>
  </OriginalItem>
</ItemGroup>
<Target Name="WriteItemsWithMetadata">
  <WriteItemsWithMetadata
    OutputFile="Out.props"
    Items="@(OriginalItem)"
    />
  <Exec Command="type Out.props" />
</Target>


标签: msbuild