如何根据当前项目的目录名称从另一个项目列表生成MsBuild itemList?

时间:2010-09-15 16:30:44

标签: msbuild

我正在获取文件列表*.config并将它们复制到目录列表中。这些目录相对于路径C:\branches\具有名称,然后是name.UnitTest。

因此副本看起来像这样而不被重构/批处理:

<Target Name="CopyClientConfigs">

<ItemGroup>
    <ClientConfigDestinations Include="$(LocalSourcePath)\Module1\Module1.UnitTest\;
    $(LocalSourcePath)\Module2\Module2.UnitTest\;
    $(LocalSourcePath)\CommonControls\Module3\Module3.UnitTest\;
    $(LocalSourcePath)\Administration\Module4\Module4.UnitTest\;
    $(LocalSourcePath)\IndividualControls\Configuration\Module5\Module5.UnitTest\" />
    <ClientConfigs
    Include="$(ClientConfigPath)\*.config"
    Exclude="$(ClientConfigPath)\P*.config" >
    </ClientConfigs>
</ItemGroup>
<Copy
        SourceFiles="@(ClientConfigs)"
        DestinationFolder="%(ClientConfigDestinations.FullPath)"
        />

我想要的是能够使用这个ItemGroup

<ItemGroup>
<MyModules Include="$(LocalSourcePath)\Module1;
    $(LocalSourcePath)\Module2;
    $(LocalSourcePath)\CommonControls\Module3;
    $(LocalSourcePath)\Administration\Module4;
    $(LocalSourcePath)\IndividualControls\Configuration\Module5"
/>          

所以任务就像

Copy
        SourceFiles="@(ClientConfigs)"
        DestinationFolder="%(ClientConfigDestinations.FullPath)\*.UnitTest\"
        />

或更好

Copy
        SourceFiles="@(ClientConfigs)"
        DestinationFolder="%(ClientConfigDestinations.FullPath)\%(ClientConfigDestinations.NameOnly).UnitTest\"
        />

如何重构或正确批量操作?

2 个答案:

答案 0 :(得分:9)

如果我正确地阅读了您的问题,我认为您正在尝试进行跨产品复制:将一个ItemGroup中的所有项目复制到另一个组中的所有文件夹。

我实际上有一个整洁的目标,我用来做这个,因为我讨厌TeamBuild将所有二进制文件放入一个文件夹的方式 - 我希望项目能够指定他们的输出是一个“捆绑”,并且输出也将被复制到一个或多个位置。

为此,我有两个项目组:BundleFiles(我要复制的文件集)和BundleFolders,它们是我要复制到的文件夹集。

<ItemGroup>
    <BundleOutDir Include="FirstFolder;SecondFolder" />
    <BundleFiles Include="file1;file2" />
</ItemGroup>

我的目标包含两个这样的任务:

<ItemGroup>
    <FilesByDirsCrossProduct Include="@(BundleFiles)">
        <BundleOutDir>%(BundleOutDir.FullPath)</BundleOutDir>
    </FilesByDirsCrossProduct>
</ItemGroup>

这会创建一个超级项目组,其中包含文件夹的文件交叉产品。

副本非常简单:

<Copy SourceFiles="@(FilesByDirsCrossProduct)"
    DestinationFiles="@(FilesByDirsCrossProduct -> '%(BundleOutDir)\%(Filename)%(Extension)' ) "
    SkipUnchangedFiles="true" />

然后将文件复制到元数据中指定的文件夹。

我的目标实际上更聪明一点,因为我可以声明捆绑包将转到子文件夹和/或我可以在复制期间通过元数据重命名文件,但这是一个不同的故事

答案 1 :(得分:1)

<Target Name="CopyClientConfigsBatched" Outputs="%(MyModules.FullPath)">
    <Message Text="@(MyModules -> '%(FullPath)\%(FileName).UnitTest')"/>
  <ItemGroup>
    <ClientConfigs
    Include="$(ClientConfigPath)\*.config"
    Exclude="$(ClientConfigPath)\P*.config" >
    </ClientConfigs>
  </ItemGroup>
  <Copy SourceFiles="@(ClientConfigs)" DestinationFolder="@(MyModules -> '%(FullPath)\%(FileName).UnitTest')"
     SkipUnchangedFiles="true"/>
</Target>

目标批处理似乎已经完成了!