Ответ 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.