MSBuild Filtering ItemГруппа файлов с условием

Кажется, что это так просто, но я не могу заставить его работать.

Все, что я пытаюсь добиться, это отфильтрованный список встроенных ресурсов. Я пробовал разные подходы, но я не могу понять это правильно.

Вот то, что я думал, было правильным решением:

<ItemGroup>
  <AllEmbeddedResources Include="@(EmbeddedResource)" Condition="$(FullPath.Contains('Change')"/>
</ItemGroup>

Правка... Уточняю, результаты без условия, список все вложенные ресурсы, с условием группа пустая.

Я пробовал это внутри и вне цели, и я пытался получить полный список в одной группе, а затем отфильтровать в отдельной группе. Я знаю, что просто неправильно понимаю какую-то фундаментальную часть синтаксиса msbuild, я просто не могу понять это. С нетерпением жду, когда мне покажут мою глупую ошибку!


person Adam    schedule 01.09.2017    source источник
comment
$ для ссылки на свойства. Вы хотите сослаться на метаданные, что делается с помощью %, поэтому для начала вам следует %(FullPath.... Но я на 100% уверен, что об этом уже спрашивали, так что просто поищите.   -  person stijn    schedule 01.09.2017
comment
@stijn, поэтому я думал так же, но если я использую этот синтаксис [Condition=%(FullPath).Contains('Change')] я получаю сообщение об ошибке [ошибка MSB4092: неожиданный токен. был найден в позиции символа 12 в условии %(FullPath).Contains('Change').] Подобные вопросы задавались, но что бы я ни делал, чтобы следовать их примерам, это никогда не казалось достаточно близким. Я отредактирую, чтобы включить ссылки на то, что я пробовал...   -  person Adam    schedule 01.09.2017
comment
@ Адам, вам нужно сделать это во время статической оценки (проект-глобальный) или внутри цели? Это трудно сделать во время статической оценки.   -  person Martin Ullrich    schedule 01.09.2017
comment
@MartinUllrich Намерение состоит в том, чтобы передать список файлов задаче, чтобы затем проверить некоторые другие вещи (ps встроенная задача, если это имеет значение). Я пробовал это вне цели, содержащей задачу, и внутри цели перед задачей. Ни то, ни другое не работает.   -  person Adam    schedule 02.09.2017


Ответы (2)


Внутри цели это можно сделать, используя синтаксис пакетной обработки для элементов и используя метод System.String.Copy, чтобы иметь возможность вызывать функции экземпляра в строке:

<Target Name="ListAllEmbeddedResources">
  <ItemGroup>
    <AllEmbeddedResources Include="@(EmbeddedResource)" Condition="$([System.String]::Copy(%(FullPath)).Contains('Change'))" />
  </ItemGroup>
  <Message Importance="high" Text="AllEmbeddedResources: %(AllEmbeddedResources.Identity)" />
</Target>

Обратите внимание, что этот синтаксис работает только внутри цели, а не во время статической оценки (группа элементов непосредственно под узлом <Project>).

person Martin Ullrich    schedule 02.09.2017
comment
Работает отлично! Спасибо! Рад, что я не просто был глуп... разочарован тем, что это так чертовски неясно! - person Adam; 04.09.2017

Атрибут условия должен возвращать логическое значение, и он работает с каждым элементом группы элементов. Вы можете получить доступ к каждому элементу, используя %(Identity). Допустим, у вас есть нефильтрованная группа элементов с именем UnfilteredItems, и вы хотите отфильтровать их в группу с именем MyFilteredItems, используя некоторый шаблон регулярного выражения.

<ItemGroup>
  <MyFilteredItems Include="@(UnfilteredItems)" Condition="$([System.Text.RegularExpressions.Regex]::Match(%(Identity),'.*\\bin\\.*').Success)"/>
</ItemGroup> 
person Cogent    schedule 03.07.2020