Я создал пользовательскую общую цель "RealClean", которые удаляют каждый файлы в выводе и "промежуточном выводе" каталог. Я поместил его в Microsoft. Файл Common.targets. Когда я выполняю MsBuild на своем csproj, все прекрасно. Но когда я выполняю MsBuild на своем sln (который просто ссылается на список csproj), у меня есть следующая ошибка
error MSB4057: The target "RealClean" does not exist in the project.
Вот командная строка, которую я ввожу для выполнения MsBuild
C:\Windows\Microsoft .NET\Framework\v3.5\MsBuild.exe /p:Configuration="Release";OutputPath="..\..\MSBuild.Referentiel.net35";nowarn="1591,1573" /t:RealClean mySolution.sln
Какая-либо подсказка?
Для работы с файлом решения MSBuild создает временный файл проекта MSBuild, содержащий только некоторые цели, например Build и Чистый . Таким образом, вы не можете вызвать свою настраиваемую цель в файле решения.
Madgnome, вероятно, прав. Но я хотел добавить, что вы не должны редактировать файлы Microsoft.common.targets. Если вы это сделаете, вы рискуете получить на этой машине процесс сборки, отличный от того, что есть у всех остальных. В вашем случае вы могли бы создать новый файл MSBuild только с целью RealClean и поместить его по адресу C:\Program Files (x86)\MSBuild\v4.0\Custom.After.Microsoft.Common.targets или для 32 бит C:\Program Files\MSBuild\v4.0\Custom.After.Microsoft.Common.targets и по сути это будет то же самое, что поместить этот файл внутрь Microsoft.Common.targets, за исключением того, что вам не нужно изменять этот файл.
У меня была такая же проблема, но я не хотел изменять что-либо за пределами дерева исходных текстов, чтобы заставить это работать. Добавление файлов в C: \ Program Files ... означает, что вам нужно делать это вручную на каждой машине разработчика, чтобы добиться одинакового поведения.
Я сделал три вещи:
1) Создал файл настраиваемых целей, который я импортирую в каждый проект C # и / или VB / F # в моем решении, добавив следующее в каждый файл проекта:
<!-- Rest of project file -->
<PropertyGroup Condition="'$(SolutionDir)' == '' or '$(SolutionDir)' == '*undefined*'">
<!-- Relative path to containing solution folder -->
<SolutionDir>..\</SolutionDir>
</PropertyGroup>
<Import Project="$(SolutionDir)CommonSettings.targets" />
2) Добавил цель clean, которая вызывается после настоящей очистки (с использованием атрибута AfterTargets из MSBuild 4.0):
<Target Name="CleanCs" AfterTargets="Clean">
<Message Text="Deep cleaning C# project..." />
<CreateItem Include="$(OutDir)**\*.*; $(ProjectDir)\obj\**\*.*; $(IntermediateOutputPath)**\*.*"
Exclude="**\bin\**\*.vshost.exe; $(IntermediateOutputPath)**\*.log">
<Output TaskParameter="Include" ItemName="AfterClean_FilesToDelete"/>
</CreateItem>
<Delete Files="@(AfterClean_FilesToDelete)" />
<CreateItem Include="$(ProjectDir)\obj\" >
<Output TaskParameter="Include" ItemName="AfterClean_DirectoriesToDelete" />
</CreateItem>
<CreateItem Include ="$(ProjectDir)\bin\" Condition="'$(TargetExt)' != '.exe'" >
<Output TaskParameter="Include" ItemName="AfterClean_DirectoriesToDelete"/>
</CreateItem>
<RemoveDir ContinueOnError="true" Directories="@(AfterClean_DirectoriesToDelete)" />
</Target>
3) В моем проекте непрерывной интеграции MSBuild я проверяю и убеждаюсь, что все файлы proj имеют # 1:
<ItemGroup>
<!-- Exclude viewer acceptance tests as they must compile as x86 -->
<CheckProjects_CsProjects Include="**\*.csproj" />
</ItemGroup>
<Target Name="CheckProjects">
<!--
Look for C# projects that don't import CommonSettingsCs.targets
-->
<XmlRead XPath="//n:Project[count(n:Import[@Project[contains(string(), 'CommonSettingsCs.targets')]]) = 0]/n:PropertyGroup/n:AssemblyName/text() "
XmlFileName="%(CheckProjects_CsProjects.Identity)"
Namespace="http://schemas.microsoft.com/developer/msbuild/2003"
Prefix="n" >
<Output TaskParameter="Value" ItemName="CheckProjects_CsMissingImports"/>
</XmlRead>
<Error Text="Project missing CommonSettingsCs.targets: %(CheckProjects_CsMissingImports.Identity)"
Condition="'%(CheckProjects_CsMissingImports.Identity)' != ''" />
</Target>
Это не позволяет разработчикам забывая добавить # 1. Вы можете создать свой собственный шаблон проекта, чтобы гарантировать, что он есть во всех новых проектах по умолчанию.
Преимущество этого подхода в том, что установка нового списка исходных текстов не требует ничего, кроме получения текущего дерева исходных текстов. Обратной стороной является то, что вам нужно отредактировать файлы проекта один раз при их создании.