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

当项目组文件都具有相同的名称时,如何使用MSBuild转换?,msbuild,Msbuild,在整个项目的各个目录中,我都有一堆文件x.txt。作为构建步骤的一部分,我希望收集这些文件并将它们放在一个文件夹中(无需声明每个文件)。我可以使用以下方法检测它们: <ItemGroup> <MyFiles Include="$(SRCROOT)\**\x.txt"/> </ItemGroup> 但是,如果我将它们复制到一个文件夹中,它们都会相互覆盖。我曾尝试使用一种转换,在这种转换中,我将GUID附加到每个文件名,但GUID只创建一次,然后在每次转

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

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


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

转换可以工作,但您必须“强制”它在每次迭代中生成新数据。我花了一段时间才弄明白这一点,现在这很有意义,但我找不到任何文档来解释这一点。但它只需引用其他现有元数据即可工作:msbuild看到必须在每次迭代中对其进行评估,因此它将乐于评估新元数据的任何部分。例如,只需使用%(文件名):


%(文件名)$([System.Guid]::NewGuid())%(文件名)
或者,您可以使用已经拥有的唯一元数据,即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>

x_$([System.String]::复制('%(RecursiveDir)').Replace('\','\')).txt

我试过了,这是一个很好的解决方案——只需要小心第二个解决方案中不断增加的文件名长度。
<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>