Как удалить несколько файлов с помощью проекта msbuild/web deployment?
У меня есть странная проблема с тем, как msbuild ведет себя с проектом развертывания веб-сайтов VS2008 и хотел бы знать, почему это кажется случайным образом неправильным.
Мне нужно удалить несколько файлов из папки развертывания, которая должна существовать только в моей среде разработки. Файлы были созданы веб-приложением во время 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 (вероятно, там, где она должна быть), но она дает мне тот же непредсказуемый результат.
Кто-нибудь испытал это? Я делаю что-то неправильно? Почему это происходит?
Ответы
Ответ 1
<ItemGroup>
оценивается при загрузке script и до <Target>
.
Кажется, что есть несколько способов сделать это правильно -
-
Включите <ItemGroup>
внутри <Target>
, и он должен быть оценен в нужное время. Это будет работать с MS-Build v3.5 +
-
Используйте <CreateItem>
для создания списка элементов
Пример построения script для этого -
<!-- 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>
Чтобы объяснить, почему процесс удаления генерировал "непредсказуемые" результаты -
- Начните с пути вывода чистой сборки
- Build # 1 - создайте проект развертывания веб-сайтов.
@(DeleteAfterBuild)
будет оценивать без файлов, поскольку файлы не существуют в папке $(OutputPath)
и не будут удалять какие-либо файлы как часть AfterBuild
target
- Build # 2 - создайте проект развертывания веб-сайтов.
@(DeleteAfterBuild)
будет оценивать все ожидаемые файлы в папке $(OutputPath)
и удалит файлы как часть AfterBuild
target
- В принципе, мы вернемся к стадии 2. Повторите. Полученные результаты предсказуемы - больше не царапайте голову.
Справочный материал:
Как создать группы элементов на лету,
Отложенная оценка элементов в файле MSBUILD
Ответ 2
Проверьте запись в блоге, которую я только что разместил MSBuild: оценка предметов и свойств, я думаю, это может вам помочь. Дайте мне знать, если нет.
Сказал Ибрагим Хашими
Ответ 3
Я понимаю, что это уже ответили, но я думал, что добавлю свои 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>