如何基于当前项';从另一个项列表生成MsBuild itemList;谁的目录名?

如何基于当前项';从另一个项列表生成MsBuild itemList;谁的目录名?,msbuild,Msbuild,我正在获取文件列表*.config,并将它们复制到目录列表中。目录相对于路径C:\branchs\有一个名称,然后是name.UnitTest 因此,在不进行重构/批处理的情况下,副本看起来是这样的: <Target Name="CopyClientConfigs"> <ItemGroup> <ClientConfigDestinations Include="$(LocalSourcePath)\Module1\Module1.UnitTest\;

我正在获取文件列表
*.config
,并将它们复制到目录列表中。目录相对于路径
C:\branchs\
有一个名称,然后是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)"
        />
或者更好

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

如何重构或正确批处理此操作?

如果我没有看错您的问题,我认为您正在尝试进行跨产品复制:将一个项目组中的所有项目复制到另一个组中的所有文件夹

实际上,我有一个整洁的目标,我用它来实现这一点,因为我讨厌TeamBuild将所有二进制文件放在一个文件夹中的方式——我希望项目能够指定它们的输出是一个“bundle”,并且输出也将被复制到一个或多个位置

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

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

然后,我的目标包含以下两个任务:

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

%(BundleOutDir.完整路径)
这将创建一个uber项目组,其中包含按文件夹划分的文件的叉积

因此,副本非常简单:

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

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


我的目标实际上更聪明一点,我可以声明bundle将进入子文件夹,并且/或者我可以在复制过程中通过元数据重命名文件,但如果我没有看错你的问题,情况就不同了,我认为您正在尝试进行跨产品复制:将一个ItemGroup中的所有项目复制到另一个group中的所有文件夹

<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>
实际上,我有一个整洁的目标,我用它来实现这一点,因为我讨厌TeamBuild将所有二进制文件放在一个文件夹中的方式——我希望项目能够指定它们的输出是一个“bundle”,并且输出也将被复制到一个或多个位置

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

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

然后,我的目标包含以下两个任务:

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

%(BundleOutDir.完整路径)
这将创建一个uber项目组,其中包含按文件夹划分的文件的叉积

因此,副本非常简单:

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

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

我的目标实际上更聪明一些,因为我可以声明捆绑包将进入子文件夹,并且/或者我可以在复制过程中通过元数据重命名文件,但这是另一回事


<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>
目标批处理似乎已经做到了



目标批处理似乎已经做到了

+1这看起来很接近,但我需要我的目标文件夹是一个子文件夹
FirstFolder\FirstFolder.UnitTestFolder
而且我不认为
%(BundleOutDir)\*.UnitTestFolder\%(文件名)%(扩展名)
会起作用是的,当我尝试这种方法时,路径中会出现非法字符。将一组文件复制到一组位置的有趣方法。我喜欢。嗯,在副本中应该很简单。您不需要“*”,因为您只处理单个项目(当您看到%(项目)时,想象“foreach”循环对项目执行单个操作)DestinationFiles=“@(FileByDirScrossProduct->'%(BundleOutDir)\%(BundleOutDir).UnitTestFolder\%(Filename)%(Extension)”@Peter,如果您说的单个项目是指配置项目,不,我正在复制3个配置文件。如果你是指目标,我很难理解你的评论。看到我的答案后它仍然适用吗?+1这看起来很接近,但我需要我的目标文件夹成为一个子文件夹
FirstFolder\FirstFolder.UnitTestFolder
而且我不认为
%(BundleOutDir)\*.UnitTestFolder\%(文件名)%(扩展名)
会起作用是的,当我尝试这种方法时,路径中会出现非法字符。将一组文件复制到一组位置的有趣方法。我喜欢。嗯,在副本中应该很简单。您不需要“*”,因为您只处理单个项目(当您看到%(项目)时,想象“foreach”循环对项目执行单个操作)DestinationFiles=“@(FileByDirScrossProduct->'%(BundleOutDir)\%(BundleOutDir).UnitTestFolder\%(Filename)%(Extension)”@Peter,如果您说的单个项目是指配置项目,不,我正在复制3个配置文件。如果你是指目标,我很难理解你的评论。看到我的答案后,它仍然适用吗?类似于此,你应该看到。@Sayed谢谢,有趣的链接。我认为这不适用于我的情况,因为我的团队似乎不接受/不允许对项目文件进行任何自定义,所以这里的.proj代码位于一个实际上不进行任何构建的项目中,只是从主控端刷新我的环境。与此类似,您应该看到。@Sayed谢谢,有趣的链接。我认为这不适用于我的情况,因为我的团队似乎不接受/不允许对项目文件进行任何自定义,因此这里的.proj代码位于一个实际上不进行任何构建的项目中,只是从主环境刷新我的环境。