Использование robocopy с событиями Visual Studio 2010 Post-build и Pre-build
Robocopy выводит 1 после успеха, в отличие от большинства программ, которые с успехом завершают 0. Visual Studio (и MSBUILD) интерпретирует код выхода 1 как ошибку.
Как можно использовать Robocopy в событиях post-and-pre-build Visual Studio, чтобы их сбой и успех были правильно идентифицированы средой сборки?
Примечание: это более или менее репортаж этот пост.
Ответы
Ответ 1
MSBuild extensionpack содержит задачу Robocopy, которую вы можете использовать в процессе сборки.
Может ли это быть решением для вас вместо VS pre/postbuild событий?
Если это так, вы можете расширить процесс создания Visual Studio, переопределив цели BeforeBuild, AfterBuild и вызов задачу Robocopy (вы можете переопределить другие цели, если они лучше подходят вашим потребностям, см. список на связанной странице MSDN)
Поэтому на самом деле вы должны скачать и установить MSBuild extensionpack, чем открыть файл проекта csproj/vbproj и отредактировать следующий способ:
Добавление следующих записей для импорта задачи Robocopy для MSBuild
<PropertyGroup>
<TPath>$(MSBuildExtensionsPath32)\ExtensionPack\4.0\MSBuild.ExtensionPack.tasks</TPath>
</PropertyGroup>
<Import Project="$(TPath)"/>
Переопределение PreBuild, AfterBuild и выполнение задачи Robocopy
<Target Name="BeforeBuild">
<Message Text="Beforebuild" />
<MSBuild.ExtensionPack.FileSystem.RoboCopy Source="C:\temp\robo_src1" Destination="C:\temp\robo_dest1" Files="*.*" Options="/MIR">
<Output TaskParameter="ExitCode" PropertyName="Exit" />
<Output TaskParameter="ReturnCode" PropertyName="Return" />
</MSBuild.ExtensionPack.FileSystem.RoboCopy>
<Message Text="ExitCode = $(Exit)"/>
<Message Text="ReturnCode = $(Return)"/>
</Target>
<Target Name="AfterBuild">
<MSBuild.ExtensionPack.FileSystem.RoboCopy Source="C:\temp\robo_src2" Destination="C:\temp\robo_dest2" Files="*.*" Options="/MIR">
<Output TaskParameter="ExitCode" PropertyName="Exit" />
<Output TaskParameter="ReturnCode" PropertyName="Return" />
</MSBuild.ExtensionPack.FileSystem.RoboCopy>
<Message Text="ExitCode = $(Exit)"/>
<Message Text="ReturnCode = $(Return)"/>
</Target>
Ответ 2
С <src> , <tgt> являющийся источником копии и целевой стороной, и <opt> варианты robocopy:
robocopy <opt> <src> <tgt>
set rce=%errorlevel%
if not %rce%==1 exit %rce% else exit 0
Например, если мы хотим скопировать цель проекта в c:\temp, без повторений и со всеми подкаталогами (пустым или нет), мы будем использовать:
robocopy /R:0 /E $(TargetDir) c:\temp
set rce=%errorlevel%
if not %rce%==1 exit %rce% else exit 0
Ответ 3
Добавление ответа на запрос. На основе решения Asaf и добавления комментария skrebbel.
Вы можете упростить проверку:
robocopy <opt> <src> <tgt>
if %errorlevel% leq 1 exit 0 else exit %errorlevel%
Как было отмечено в комментариях, вы можете настроить "1": это зависит от того, какую операцию следует рассматривать как ошибку. Посмотрите значение битов, которые в совокупности составляют число, возвращаемое robocopy:
0 × 10 Серьезная ошибка. Robocopy не копировал файлы. Это либо ошибки использования или ошибки из-за недостаточных прав доступа на исходных или целевых каталогов.
0 × 08 Некоторые файлы или каталоги не могут быть скопированы (ошибки копирования и превышен лимит повтора). Проверьте эти ошибки в дальнейшем.
0 × 04 Определены несогласованные файлы или каталоги. Изучите выходной журнал. Возможно, необходимо провести уборку дома.
0 × 02 Некоторые дополнительные файлы или каталоги были обнаружены. Изучить выход журнал. Может потребоваться некоторая уборка.
0 × 01 Один или несколько файлов были скопированы успешно (то есть новые файлы прибыл).
0 × 00 Ошибок не было, и копирование не производилось. Источник и деревья каталога назначения полностью синхронизированы.
Ответ 4
Просто проверка кода выхода 1 неверна, поскольку любой код выхода ниже 8 не является ошибочным:
Любое значение, большее 8, указывает на то, что был хотя бы один сбой во время операции копирования.
(Чтобы уточнить, код выхода из 8 также является ошибкой: Several files did not copy
)
Соответствующий код должен выглядеть так:
IF %ERRORLEVEL% GEQ 8 exit 1
exit 0
Ответ 5
Синтаксически здесь представлена версия с одной строкой для каждой команды, которая работает непосредственно в шагах PreBuild:
(robocopy "$(ProjectDir)..\Dir1" "$(ProjectDir)Dir1" "Match.*" /a+:R) ^& IF %ERRORLEVEL% GEQ 8 exit 1
(robocopy "$(ProjectDir)..\Dir2" "$(ProjectDir)Dir2" "Match.*" /a+:R) ^& IF %ERRORLEVEL% GEQ 8 exit 1
exit 0
Ссылки: