[ACCEPTED]-Using robocopy with Visual Studio 2010 Post-build and Pre-build events-robocopy

Accepted answer
Score: 29

Adding this answer per request. Based on 22 Asaf's solution, and adding skrebbel's comment.

You 21 can simplify the check to:

robocopy <opt> <src> <tgt>
if %errorlevel% leq 1 exit 0 else exit %errorlevel%

As kindly remarked 20 in the comments, you may want to adjust 19 the '1': It depends on what your operation 18 should treat as an error. Have a look at 17 the meaning of the bits that in combination make up the number returned by robocopy:

0×10 Serious error. Robocopy did not copy 16 any files. This is either a usage error 15 or an error due to insufficient access privileges 14 on the source or destination directories.

0×08 13 Some files or directories could not be copied 12 (copy errors occurred and the retry limit 11 was exceeded). Check these errors further.

0×04 10 Some Mismatched files or directories were 9 detected. Examine the output log. Housekeeping 8 is probably necessary.

0×02 Some Extra files 7 or directories were detected. Examine the 6 output log. Some housekeeping may be needed.

0×01 5 One or more files were copied successfully 4 (that is, new files have arrived).

0×00 3 No errors occurred, and no copying was done. The 2 source and destination directory trees 1 are completely synchronized.

Score: 19

With <src>, <tgt> being the 5 copy source and target respectfully, and 4 <opt> being robocopy options:

robocopy <opt> <src> <tgt>
set rce=%errorlevel%
if not %rce%==1 exit %rce% else exit 0

For instance, if 3 we want to copy the project target to c:\temp, without 2 retries and with all sub-directories (empty 1 or not), we'd use:

robocopy /R:0 /E $(TargetDir) c:\temp
set rce=%errorlevel%
if not %rce%==1 exit %rce% else exit 0
Score: 11

Simply checking for an exit code of 1 is 5 incorrect, as any exit code below 8 is non-erroneous:

Any value greater than 8 4 indicates that there was at least one failure during 3 the copy operation.

(Just to clarify, an 2 exit code of 8 is an error as well: Several files did not copy)

The 1 proper code, then, should look like this:

IF %ERRORLEVEL% GEQ 8 exit 1
exit 0
Score: 5

Syntactically here is a one-line-per-command 2 version that works directly within the PreBuild 1 steps:

(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

References:

Score: 4

MSBuild extensionpack contains a Robocopy task that you can use 10 in your build process.
Can this be a solution 9 for you instead of VS pre/postbuild events?

If 8 so, you can extend the Visual Studio Build Process by overriding the BeforeBuild, AfterBuild 7 targets and calling the Robocopy task (you 6 can override other targets as well if they 5 would suit your needs better, see the list 4 in the linked MSDN page)
So actually you 3 should download and install MSBuild extensionpack 2 than open your project's csproj/vbproj file 1 and edit the following way:

Adding following entries for importing MSBuild extensionpack's Robocopy task

<PropertyGroup>
    <TPath>$(MSBuildExtensionsPath32)\ExtensionPack\4.0\MSBuild.ExtensionPack.tasks</TPath>        
</PropertyGroup>
<Import Project="$(TPath)"/>

Overriding BeforeBuild, AfterBuild and executing the Robocopy task

<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>
Score: 4

The accepted answer is overkill IMO. Robocopy 28 already has its exit codes defined, so we can usually assume 27 any value of 8 or less indicates things went 26 well.

"Any value greater than 8 indicates that there was at least one failure during the copy operation."

So let's say your command is, ROBOCOPY $(Source) $(Dest) *.*, which 25 I'll just refer to as $(RobocopyBinCommand).

In Visual Studio 24 for your Pre-Build or Post-Build Event, click 23 the dropdown and select <Edit...>

Create a new line 22 below your command, and place IF %ERRORLEVEL% LEQ 8 EXIT 0 then apply 21 and close the Properties window, eg:

example

Advanced Exit Code Requirements

Let's 20 say you only want the build to pass if ROBOCOPY 19 returns 1 or 3. The if-check above won't allow 18 you to even use the OR-like behavior supported 17 by CMD.exe to fix the issue. You can work 16 around this limitation multiple ways but 15 I think this is one of the most concise 14 ways to do it.

if %errorlevel% LEQ 3 echo %errorlevel%|findstr "1 3"

One-Liner Explanation

Basically, we're piping the 13 result of echoing the errorlevel to findstr which 12 is looking for either a 1 or a 3. We don't 11 have to worry about values that have a 3 10 or a 1 in them like 23 or 16 because the first 9 evaluation makes sure the value is 3 or 8 less. Once that evaluation passes if it 7 does indeed pass it then pipes the errorlevel 6 to findstr which then compares errorlevel to 1 or 5 3. If either is detected by findstr, findstr 4 will exit 0, otherwise it will not. If the 3 errorlevel was not 3 or less, errorlevel 2 will remain unchanged and the build task 1 will exit 1 as-usual from using ROBOCOPY.

Score: 0

I found that it's much easier to start robocopy 11 rather than trying to call it in-line with 10 Visual Studio. This way Visual Studio doesn't 9 care about the return code from robocopy.

start robocopy . ..\latestbuild

The 8 only difference I could see is that you 7 will see a command prompt appear and disappear 6 to execute the robocopy command.

Using call instead 5 of start actually doesn't open the command prompt 4 and, even better, redirects the output from 3 the robocopy to Visual Studio output window.

call robocopy . ..\latestbuild

For 2 some reason this approach only works when 1 used in Pre-build events command line.

More Related questions