msbuild создать группу элементов из группы свойств

Я хочу передать разделенный точкой с запятой список строк.
Каждая строка представляет имя файла.

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

Теперь я хочу создать группу элементов, которая должна дать мне все файлы в определенной папке, исключая список имен файлов, что-то вроде:

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

Как перебрать файлы текущей папки и сопоставить каждое из них с именем, если оно содержит одно имя файла в переменной Filenames.

2 ответа

Решение

Я уверен, что это дубликат, но я не могу найти его в данный момент, так что вот оно:

  • превращение разделенного точкой с запятой свойства в элемент просто вопрос использования Include=$(Property)
  • Exclude работает, только если у вас есть список точных совпадений, но вам нужно больше произвольной фильтрации, поэтому вам понадобится Condition
  • соедините две ItemGroups вместе, как перекрестный продукт, создав метаданные FileNames элемента ReleaseFiles. Затем вы можете перебирать каждый элемент в 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>

Используйте стандартный способ исключения файлов файлов из группы элементов с помощью атрибута Exclude и ссылки на другую группу элементов. Это будет намного легче понять.

Пример:

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

<ItemGroup>
    <FilesToExclude Include="$(PathToOutput)\**\Newtonsoft.Json" />
    <FilesToExclude Include="$(PathToOutput)\**\Reactive" />
    <ReleaseFiles Include="$(PathToOutput)\**\*.*" Exclude="@(FilesToExclude)"/>
</ItemGroup>
Другие вопросы по тегам