Подтвердить что ты не робот

Использование robocopy с событиями Visual Studio 2010 Post-build и Pre-build

Robocopy выводит 1 после успеха, в отличие от большинства программ, которые с успехом завершают 0. Visual Studio (и MSBUILD) интерпретирует код выхода 1 как ошибку.

Как можно использовать Robocopy в событиях post-and-pre-build Visual Studio, чтобы их сбой и успех были правильно идентифицированы средой сборки?

Примечание: это более или менее репортаж этот пост.

4b9b3361

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

Ссылки: