Во-первых, не то, чтобы ваш синтаксис был неправильным для вызова функций, это должно быть:
%(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
или другие варианты. Я не уверен, что это лучший способ выяснить, что ссылка должна быть ссылкой на проект, но если вы знаете (и в определенной степени) свою среду, это может быть осуществимо.