Подтвердить что ты не робот

MSBuild - Цели проекта для решения не работают

У меня есть решение, в котором есть несколько проектов, включая веб-приложение. Я хочу, чтобы MSBuild выполнял цель "WebPublish" против проекта веб-приложения и "цель по умолчанию" для всех других проектов в решении.

В этой статье MSDN говорится, что я могу это сделать, указав командную строку

msbuild SlnFolders.sln /t:NotInSlnfolder:Rebuild;NewFolder\InSolutionFolder:Clean

Но я никогда не мог заставить его работать - MSBuild возвращает ошибку, что-то вроде цели "NotInSlnFolder: Rebuild" не существует. Не имеет значения, какую цель указать, построить, перестроить или очистить - это ни в коем случае не работает.

Как я могу достичь своей цели определения целевых значений для проекта для решения?

Документация MSDN не работает. Или я что-то пропустил?

4b9b3361

Ответ 1

ПРИМЕЧАНИЕ. Это обходное решение официально не поддерживается Microsoft, поэтому нет никакой гарантии, что он будет работать вечно.


Короткий ответ

В папке с файлом SLN создайте файл before.{YourSolution}.sln.targets со следующим содержимым: (Замените в фигурных скобках все, что вам нужно.)

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="{MyCompany_MyProduct_WebApp:WebPublish}">
    <MSBuild
        Condition="'%(ProjectReference.Identity)' == '{$(SolutionDir)MyCompany.MyProduct.WebApp\MyCompany.MyProduct.WebApp.csproj}'"
        Projects="@(ProjectReference)"
        Targets="{WebPublish}"
        BuildInParallel="True"
        ToolsVersion="4.0"
        Properties="BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)"
        SkipNonexistentProjects="%(ProjectReference.SkipNonexistentProjects)" />
  </Target>
</Project>

После этого вы можете выполнить командную строку:

msbuild {YourSolution}.sln /t:{MyCompany_MyProduct_WebApp:WebPublish}

Длинный ответ

Если вы добавите переменную среды MSBUILDEMITSOLUTION, установив ее значение в 1, MSBuild не удалит временные файлы, сгенерированные для решения и проектов.

Это позволит вам находить файлы {YourSolution}.sln.metaproj и {YourSolution}.sln.metaproj.tmp, сгенерированные в папке решения, которые являются стандартными файлами проекта MSBuild.

Для MSBuild 3.5 сгенерированный файл {YourSolution}.sln.cache и сохраняется независимо от переменных среды. Анализируя эти файлы, вы поймете информацию о нижнем уровне процесса и посмотрите доступные возможности настройки.

После выполнения MSBuild с определенной целевой программой в файле .Metaproj вы обнаружите, что список целевых объектов, ориентированных на проект, жестко запрограммирован и поддерживаются только стандартные цели (Сборка, перестроение, очистка, компиляция, публикация; примечание: публикация и веб-публикация не совпадают). MSBuild 3.5 создает только чистые, перестраиваемые и опубликованные цели, а также цель с именем проекта, которое означает "Build".

Вы также можете видеть, что NotInSlnfolder:Rebuild - это просто имя автогенерируемой цели. На самом деле MSBuild не анализирует его и не интересует имена и расположение проектов. Также обратите внимание, что автогенерированные имена целей определяют имя проекта с иерархией папок решения, если оно в одном, например. SolFolder\SolSubfolder\ProjectName:Publish.

Еще одна критически важная вещь, которую вы найдете: Имя цели MSBuild не поддерживает точки. Все точки в названиях проектов заменяются символами подчеркивания. Например, для проекта с именем MyCompany.MyProduct.Components вам нужно указать в командной строке:

/t:MyCompany_MyProduct_Components:Rebuild

Вот почему даже стандартная целевая цель Build не работала - мое имя проекта содержало точки.

Анализируя файл {YourSolution}.sln.metaproj.tmp, вы обнаружите, что во время выполнения он пытается импортировать цели из файла с именем before.{YourSolution}.sln.targets и after.{YourSolution}.sln.targets, если эти файлы существуют. Это ключ к обходному пути для этого ограничения/ошибки MSBuild.

Ответ 2

Вы можете открыть файл решения в текстовом редакторе и проверить, существует ли следующая строка или нет, если нет, то вы можете добавить

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> внутри тега <Project>.

Надеюсь, что это поможет вам.