使用MSBuild创建一个ItemGroup的文件夹列表

38

我正在尝试在一个MSBuild脚本中构建一个ItemGroup,其中包含给定“根”文件夹下面的一组直接子文件夹。所以 - 在这个例子中...

+ Root folder
---- Sub Folder 1
-------- Sub-Sub Folder 1
-------- Sub-Sub Folder 2
---- Sub Folder 2
---- Sub Folder 3

...我想让我的ItemGroup包含"Sub Folder 1"、"Sub Folder 2"和"Sub Folder 3"。

可能在层次结构中的任何时刻都有一些文件,但我只对文件夹感兴趣。

有人可以帮忙吗?

5个回答

61

3
谢谢!在我的情况下,我还添加了搜索模式: <Folders Include="$([System.IO.Directory]::GetDirectories("$(RootFolder)","*$(SearchPattern)*"))" />。 - Houman
9
与其使用让我读起来头痛的丑陋的"""实体,你可以简单地使用反引号(`)代替。 - MarioDS

31
<PropertyGroup>
    <RootFolder>tmp</RootFolder>
</PropertyGroup>
<ItemGroup>
   <AllFiles Include="$(RootFolder)\**\*"/>
   <OnlyDirs Include="@(AllFiles->'%(Directory)')"/>
</ItemGroup>

@(OnlyDirs)可能会包含重复项,因此您可以使用RemoveDuplicatesTask:

<Target Name="foo">
   <RemoveDuplicates Inputs="@(OnlyDirs)">
      <Output TaskParameter="Filtered" ItemName="UniqueDirs"/>
   </RemoveDuplicates>
</Target>

或者使用批处理的方式通过%(AllFiles.Identity)或者使用msbuild 3.5的CreateItem:

<Target Name="foo">
   <ItemGroup>
      <UniqueDirs Include="%(AllFiles.Directory)"/>
   </ItemGroup>
</Target>

1
这真的很慢。如果可能,请使用@Stason Stangroome提供的解决方案。 - LuckyLikey

7

MSBuild 4.0:

<PropertyGroup>
     <RootFolder>tmp</RootFolder>
</PropertyGroup>
<ItemGroup>
    <AllFiles Include="$(RootFolder)\**\*"/>
    <OnlyDirs Include="@(AllFiles->'%(RootDir)%(Directory)'->Distinct())"/>
</ItemGroup>

3
不选择空目录。 - Mrchief
如果子文件夹中有文件夹,则会选择子文件夹。因此可能有效,但不能保证仅选择第一级子文件夹。 - htuomola

6

MSBuild扩展包有一个名为FindUnder的任务,它可以返回某个路径下的文件或文件夹的itemgroup。以下任务将实现您想要的功能,返回一个包含Sub Folder 1、Sub Folder 2和Sub Folder 3的itemgroup,但不包括Sub-Sub Folder 1或Sub-Sub Folder 2:

<MSBuild.ExtensionPack.FileSystem.FindUnder
    TaskAction="FindDirectories"
    Path="$(RootFolder)"
    Recursive="False">
    <Output ItemName="FoundFolders" TaskParameter="FoundItems" />
</MSBuild.ExtensionPack.FileSystem.FindUnder>

3

这篇MSDN论坛帖子提供了一个处理空目录问题的自定义任务(因为它是一个非常有用的回答,被upvoted并接受了)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接