[ACCEPTED]-Using robocopy with Visual Studio 2010 Post-build and Pre-build events-robocopy
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.
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
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
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:
- @OhadSchneider answer for GEQ 8
- This answer on why exit 0 needs to be at the end.
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>
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:
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.
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
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.