Использование функций Item для значений метаданных - PullRequest
17 голосов
/ 01 марта 2012

Справочная информация: Я управляю довольно крупным решением. Время от времени люди добавляют ссылку DLL на проект в решение, где они должны были добавить ссылку на проект. Я хочу сделать предупреждение в таком случае. Я хочу сделать это, найдя все ссылки с помощью «bin \ debug» в их HintPath *. Я знаю, что ссылки - это элементы в ItemGroup с метаданными "HintPath".

Я ожидал, что что-то подобное сработает:

<Warning Text="Reference %(Reference.Identity) should be a project reference. HintPath: %(Reference.HintPath)"
         Condition="%(Reference.HintPath).IndexOf('bin\debug') != -1"/>

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

  • Редактировать: я знаю, что эта проверка не является полной проверкой, но я просто хочу уменьшить число честных ошибок.

Ответы [ 3 ]

21 голосов
/ 03 марта 2012

Используя MSBuild 4.0 Функции свойств возможно сравнение строк:

<Target Name="AfterBuild">

  <Message Text="Checking reference... '%(Reference.HintPath)'" Importance="high" />

  <Warning Text="Reference %(Reference.Identity) should be a project reference. HintPath: %(Reference.HintPath)"
            Condition="$([System.String]::new('%(Reference.HintPath)').Contains('\bin\$(Configuration)'))" />

</Target>
2 голосов
/ 02 марта 2012

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

   %(Reference.HintPath.IndexOf(...))       # Note: not supported by MSBuild

Однако функции свойств в MSBuild недопустимы для метаданных элемента, так что это вам тоже не поможет.

Что можно обойти, вызвав отдельную цель, которая в основном вызывается для каждого элемента.

  <Target Name="CheckProjectReferences">
    <MSBuild 
      Projects="$(MSBuildProjectFullPath)"
      Properties="Identity=%(Reference.Identity);HintPath=%(Reference.HintPath)"
      Targets="_Warn"/>
  </Target>

  <Target Name="_Warn">
    <Warning Text="Reference $(Identity) should be a project reference. HintPath: $(HintPath)"
             Condition="$(HintPath.IndexOf('bin\debug')) != -1"/>
  </Target>

Честно говоря, я не уверен, достаточно ли этого, чтобы поймать все "нарушения". Например, вышеописанное будет работать только для bin\debug, но не для bin\Debug или других вариаций в смешанном корпусе, которые функционально эквивалентны. Чтобы их искать, вам нужно вызвать перегрузку IndexOf(string, StringComparison), но просто выполните:

   $(HintPath.IndexOf('bin\debug', System.StringComparison.OrdinalIgnoreCase))

Не будет работать, потому что разрешение перегрузки MSBuild выберет IndexOf(char, Int32) и выдаст вам эту ошибку:

MSB4184: выражение "bin \ debug" .IndexOf (bin \ debug, System.StringComparison.OrdinalIgnoreCase) "не может быть оценено. Строка должна быть длиной всего один символ.

Итак, вам нужно убедить это, используя перегрузку IndexOf(String, Int32, Int32, StringComparison) напрямую:

   $(HintPath.IndexOf('bin\debug', 0, 9, System.StringComparison.OrdinalIgnoreCase))

Возможно, вам также потребуется проверить bin\Release или другие варианты. Я не уверен, что это лучший способ выяснить, что ссылка должна быть ссылкой на проект, но если вы знаете (и в определенной степени) свою среду, это может быть осуществимо.

0 голосов
/ 23 февраля 2018

@Christian.K прав в своем анализе. Другое решение - принудительная перегрузка строки типа, используя &quot; для кавычек:

<Warning 
  Text="..." 
  Condition="$(HintPath.IndexOf(&quot;bin\debug&quot;, System.StringComparison.OrdinalIgnoreCase)) != -1" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...