当ItemGroup文件都具有相同的名称时,如何使用MSBuild转换?

时间:2016-09-22 15:30:14

标签: msbuild

我的项目中的各个目录中有一堆文件 x.txt 。作为构建步骤的一部分,我想收集它们并将它们放在一个文件夹中(无需声明每个文件夹)。我可以使用以下方法检测它们:

<ItemGroup>
  <MyFiles Include="$(SRCROOT)\**\x.txt"/>
</ItemGroup>

但是,如果我将这些复制到一个文件夹 - 它们都会相互覆盖。我尝试使用转换,其中我将GUID附加到每个文件名,但GUID只创建一次,然后重新用于每个转换(因此它们覆盖每个转换)。有没有一种方法在复制具有相同命名文件的ItemGroup时在MSBuild中生成唯一名称?只要所有文件都以该文件夹结束,最终命名方案就不重要了。

1 个答案:

答案 0 :(得分:1)

改造有效,但你必须“强迫”#39;它在每次迭代时生成新数据。我花了一段时间来弄明白这一点,现在有意义,但我找不到任何解释这个的文档。但它只是通过引用其他现有元数据来工作:msbuild看到必须在每次迭代时对其进行评估,以便它可以愉快地评估新元数据的任何部分。例如,只需使用%(FileName):

<Target Name="CreateUniqueNames">
  <ItemGroup>
    <MyFiles Include="$(SRCROOT)\**\x.txt"/>
    <MyFiles>
      <Dest>%(Filename)$([System.Guid]::NewGuid())%(FileName)</Dest>
    </MyFiles>
  </ItemGroup>
  <Message Text="%(MyFiles.Identity) -> %(MyFiles.Dest)"/>
</Target>

或者,您可以使用已有的唯一元数据,即RecursiveDir:

<Target Name="CreateUniqueNames">
  <ItemGroup>
    <MyFiles Include="$(SRCROOT)\**\x.txt"/>
    <MyFiles>
      <Dest>x_$([System.String]::Copy('%(RecursiveDir)').Replace('\', '_')).txt</Dest>
    </MyFiles>
  </ItemGroup>
  <Message Text="%(MyFiles.Identity) -> %(MyFiles.Dest)"/>
</Target>