msbuild从属性组创建项目组

时间:2016-06-16 13:22:28

标签: msbuild teamcity msbuild-itemgroup

我想传递一个以分号分隔的字符串列表 每个字符串代表一个文件名。

    <PropertyGroup>
          <FileNames>Newtonsoft.Json;Reactive</FileNames>
          <PathToOutput>C:/</PathToOutput>
    </PropertyGroup>

现在我要创建一个项目组,它应该给我特定文件夹中的所有文件,不包括文件名列表,如:

<ItemGroup>
    <ReleaseFiles Include="$(PathToOutput)\**\*.*" Exclude="%(identity)-> identity.contains(%FileNames)"/>
</ItemGroup>

如果在Filenames变量中包含任何一个文件名,我如何遍历当前文件夹的文件并匹配每个文件名。

2 个答案:

答案 0 :(得分:1)

非常确定这是重复的,但目前我找不到它,所以在这里:

  • 将分号分隔的属性转换为项目只需使用Include=$(Property)
  • Exclude仅在您拥有完全匹配列表时才有效,但您需要在此处进行更多任意过滤,因此您需要Condition
  • 通过制作ReleaseFiles项的FileNames元数据,像交叉产品一样将两个ItemGroup连接在一起。然后,您可以迭代ReleaseFiles中的每个项目并同时访问FileNames
  • Contains是一个属性函数(嗯,或者System :: String方法),因此不会在元数据上工作,因此我们首先将元数据转换为字符串

在代码中:

<PropertyGroup>
  <FileNames>Newtonsoft.Json;Reactive</FileNames>
  <PathToOutput>C:/</PathToOutput>
</PropertyGroup>

<Target Name="FilterBasedCommaSeperatedProperty">
  <ItemGroup>
    <!-- property -> item -->
    <Excl Include="$(FileNames)"/>
    <!-- list all and add metadata list -->
    <AllReleaseFiles Include="$(PathToOutput)\**\*.*">
      <Excl>%(Excl.Identity)</Excl>
    </AllReleaseFiles >
    <!-- filter to get list of files we don't want -->
    <FilesToExclude Include="@(AllReleaseFiles)"
                    Condition="$([System.String]::Copy('%(FileName)').Contains('%(Excl)'))"/>
    <!-- all but the ones to exclude --> 
    <ReleaseFiles Include="@(AllReleaseFiles)" Exclude="@(FilesToExclude)"/>
  </ItemGroup>
  <Message Text="%(ReleaseFiles.Identity)" />
</Target>

答案 1 :(得分:0)

使用标准方法,使用“排除”属性并引用其他项目组,从项目组中排除文件文件。理解它会容易得多。

示例:

<PropertyGroup>
  <PathToOutput>C:/</PathToOutput>
</PropertyGroup>

<ItemGroup>
    <FilesToExclude Include="$(PathToOutput)\**\Newtonsoft.Json" />
    <FilesToExclude Include="$(PathToOutput)\**\Reactive" />
    <ReleaseFiles Include="$(PathToOutput)\**\*.*" Exclude="@(FilesToExclude)"/>
</ItemGroup>