2009-05-12 3 views
10

У меня есть странная проблема с тем, как msbuild ведет себя с проектом VS2008 Web Deployment Project и хотел бы знать, почему это кажется случайным образом неправильным.Как удалить несколько файлов с помощью проекта msbuild/web deployment?

Мне нужно удалить несколько файлов из папки развертывания, которая должна существовать только в моей среде разработки. Файлы были созданы веб-приложением во время dev/testing и не включены в проект/решение Visual Studio.

Конфигурация Я использую выглядит следующим образом:

<!-- Partial extract from Microsoft Visual Studio 2008 Web Deployment Project --> 
<ItemGroup> 
    <DeleteAfterBuild Include="$(OutputPath)data\errors\*.xml" /> <!-- Folder 1: 36 files --> 
    <DeleteAfterBuild Include="$(OutputPath)data\logos\*.*" /> <!-- Folder 2: 2 files --> 
    <DeleteAfterBuild Include="$(OutputPath)banners\*.*" />  <!-- Folder 3: 1 file --> 
</ItemGroup> 

<Target Name="AfterBuild"> 
    <Message Text="------ AfterBuild process starting ------" Importance="high" /> 
    <Delete Files="@(DeleteAfterBuild)"> 
     <Output TaskParameter="DeletedFiles" PropertyName="deleted" /> 
    </Delete> 
    <Message Text="DELETED FILES: $(deleted)" Importance="high" /> 
    <Message Text="------ AfterBuild process complete ------" Importance="high" /> 
</Target> 

У меня есть проблема в том, что, когда я делаю сборку/восстановление проекта веб-развертывания это «иногда» удаляет все файлы, но иногда это ничего не удалит! Или он удалит только одну или две из трех папок в группе элементов DeleteAfterBuild. Кажется, что нет последовательности в том, когда процесс сборки решает удалить файлы или нет.

Когда я редактировал конфигурацию для включения только папки 1 (например), она удаляет все файлы правильно. Затем добавляя папки 2 и 3, он начинает удалять все файлы по мере необходимости. Затем, казалось бы, в случайные моменты, я перестрою проект, и он не удалит файлы!

Я попытался переместить эти элементы в группу элементов ExcludeFromBuild (что, вероятно, там, где должно быть), но это дает мне такой же непредсказуемый результат.

Кто-нибудь испытал это? Я делаю что-то неправильно? Почему это происходит?

ответ

27

<ItemGroup> оценивается при загрузке сценария и до <Target> был обработан.

Там, кажется, больше, чем один из способов сделать это правильно -

  1. Включите <ItemGroup> внутри <Target> и она должна быть оценена в нужное время. Это будет работать с MS-Build v3.5 +

  2. Использование <CreateItem> для создания элемента списка,

Пример построения сценария для этого -

<!-- Using ItemGroup --> 
<Target Name="AfterBuild"> 
    <ItemGroup> 
    <DeleteAfterBuild Include="$(OutputPath)data\errors\*.xml" /> 
    </ItemGroup> 
    <Delete Files="@(DeleteAfterBuild)" /> 
</Target> 

<!-- Using CreateItem --> 
<Target Name="AfterBuild"> 
    <CreateItem Include="$(OutputPath)data\errors\*.xml"> 
    <Output TaskParameter="Include" ItemName="DeleteAfterBuild"/> 
    </CreateItem> 
    <Delete Files="@(DeleteAfterBuild)" /> 
</Target> 

Чтобы объяснить, почему процесс удаления был генерирующие «непредсказуемые» результаты -

  1. Начните с пути выхода чистой сборки
  2. Build # 1 - создайте проект развертывания веб-сайтов. @(DeleteAfterBuild) будет оценивать без файлов, поскольку файлы не существуют в папке $(OutputPath) и не будут удалять какие-либо файлы как часть цели AfterBuild
  3. Build # 2 - создайте проект веб-развертывания.@(DeleteAfterBuild) будет оценивать со всеми ожидаемыми файлами в папке $(OutputPath) и удалит файлы как часть цели AfterBuild
  4. В основном мы возвращаемся к этапу 2. Повторите. Результаты, конечно, предсказуемы - больше не царапайте голову.

Справочные материалы: How To: Create Item Groups on the Fly, Delayed evaluation of items in MSBUILD file

+0

+1 - У меня была такая же царапина на голове. Это был прекрасный ответ. Благодаря! – spot

4

Просмотрите запись в блоге Я только что разместил MSBuild: Item & Property Evaluation, я думаю, это может вам помочь. Дайте мне знать, если нет.

Сайед Ибрагим Хашими

0

Я понимаю, что это уже есть ответ, но я думал, что я хотел бы добавить свои 5 центов. Для проекта веб-развертывания нет необходимости использовать предоставленные цели, просто добавьте группу элементов, содержащую элементы ExcludeFromBuild. Я предоставил соответствующий раздел из нижней части моего файла проекта развертывания для справки.

<Import Project="$(MSBuildExtensionsPath)\Microsoft\WebDeployment\v9.0\Microsoft.WebDeployment.targets" /> 
    <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
     Other similar extension points exist, see Microsoft.WebDeployment.targets. 
    <Target Name="BeforeBuild"> 
    </Target> 
    <Target Name="BeforeMerge"> 
    </Target> 
    <Target Name="AfterMerge"> 
    </Target> 
    <Target Name="AfterBuild"> 
    </Target> 
    --> 
    <ItemGroup> 
    <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\obj\**\*.*" /> 
    <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\Properties\**\*.*" /> 
    <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\**\*.csproj*" /> 
    <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\**\*.resx" /> 
    <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\**\*.Publish.xml" /> 
    <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\LocalTestRun.testrunconfig" /> 
    <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\TestResults\**\*.*" /> 
    </ItemGroup>