我的项目中的各个目录中有一堆文件 x.txt 。作为构建步骤的一部分,我想收集它们并将它们放在一个文件夹中(无需声明每个文件夹)。我可以使用以下方法检测它们:
<ItemGroup>
<MyFiles Include="$(SRCROOT)\**\x.txt"/>
</ItemGroup>
但是,如果我将这些复制到一个文件夹 - 它们都会相互覆盖。我尝试使用转换,其中我将GUID附加到每个文件名,但GUID只创建一次,然后重新用于每个转换(因此它们覆盖每个转换)。有没有一种方法在复制具有相同命名文件的ItemGroup时在MSBuild中生成唯一名称?只要所有文件都以该文件夹结束,最终命名方案就不重要了。
答案 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>