Это очень странно. Мы пытались понять это на некоторое время, но это действительно не имеет никакого смысла.
Наш веб-проект импортирует файл целей, у которого есть цель, подобная этой:
<Target Name="CSSCheckInternal">
<ItemGroup>
<CSSFiles Include="$(MSBuildProjectDirectory)\**\*.css" />
</ItemGroup>
<CSSChecker Files="@(CSSFiles)" />
</Target>
В настоящий момент одна ветка строится идеально, выполняя задачу по желанию; но другая ветка не работает на указанной цели.
Сбой происходит из-за того, что элемент @(CSSFiles)
, полученный при выполнении задачи, не расширяется в массив ITaskItem
.
Задача записывается следующим образом (вплоть до того момента, когда я получаю метаданные FullPath):
public class CSSChecker : Task
{
[Required]
public ITaskItem[] Files
{
get;
set;
}
public override bool Execute()
{
string fullFilePath = null;
if (Files != null)
{
foreach (var item in Files)
{
fullFilePath = item.GetMetadata("FullPath");
if(!File.Exists(fullFilePath))
throw new InvalidOperationException(
string.Format("{0} does not exist", fullFilePath));
//rest of the code elided
Строка, которая не работает, бросает InvalidOperationException
на последнюю строку, например:
Файл не существует: C:\Code\Project\**\*. css
Таким образом, кажется, что MSBuild вместо расширения шаблона в атрибуте Include
просто передает строку поверх, создавая при этом только одну ITaskItem
.
На диске существует целевая папка , и единственное различие между сломанным файлом проекта и рабочим - это один файл, который гораздо раньше в файле проекта.
Update
I спросил Сайид Хашими на твиттере (написал книгу MSBuild), и благодаря этому попытался вынуть подстановочный файл **
и теперь он начал работать. Это не очень подходит, поскольку задача предназначена для повторного использования между проектами. Но, похоже, это как-то связано с этим.
Окончательное обновление
Пожалуйста, если кто-нибудь знает, в какой ситуации MSBuild не будет правильно расширять подстановочный знак, это будет большой помощью!