Robocopy在成功时输出1,与大多数在成功时以0退出的程序不同。 Visual Studio(和MSBUILD)将退出代码1解释为错误。在Visual Studio 2010中使用robocopy后生成和预生成事件
Robocopy如何在Visual Studio后期和预先构建事件中使用,以使构建环境正确识别失败和成功?
注意:这或多或少是this post的转贴。
Robocopy在成功时输出1,与大多数在成功时以0退出的程序不同。 Visual Studio(和MSBUILD)将退出代码1解释为错误。在Visual Studio 2010中使用robocopy后生成和预生成事件
Robocopy如何在Visual Studio后期和预先构建事件中使用,以使构建环境正确识别失败和成功?
注意:这或多或少是this post的转贴。
MSBuild extensionpack包含的Robocopy任务你可以在你的构建过程中使用。
这可以成为你的解决方案,而不是VS前/后生成事件?
如果是这样,你可以extend the Visual Studio Build Process通过覆盖BeforeBuild,AfterBuild目标和调用的Robocopy任务(可以覆盖其他的目标,以及他们是否会满足您的需求更好的,请参阅链接的MSDN页面列表)
所以其实你应该下载并安装的MSBuild extensionpack比打开你的项目的csproj/vbproj文件并编辑以下方式:
添加以下条目进口的MSBuild extensionpack的任务的Robocopy
<PropertyGroup>
<TPath>$(MSBuildExtensionsPath32)\ExtensionPack\4.0\MSBuild.ExtensionPack.tasks</TPath>
</PropertyGroup>
<Import Project="$(TPath)"/>
重写BeforeBuild,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>
随着<SRC>,<TGT>为复制源和目标恭恭敬敬,并<选择>是ROBOCOPY选项:
robocopy <opt> <src> <tgt>
set rce=%errorlevel%
if not %rce%==1 exit %rce% else exit 0
举例来说,如果我们希望该项目的目标复制到C:\温度,不重试,并与所有子目录(空或没有),我们会使用:
robocopy /R:0 /E $(TargetDir) c:\temp
set rce=%errorlevel%
if not %rce%==1 exit %rce% else exit 0
你也可以简单地使用'如果errorlevel 1 exit 0 else exit%errorlevel%' – mafu 2011-10-12 09:43:48
@mafutrct:Wunderbar!如果你添加了你的评论作为答案,我会upvote它。 – 2012-03-01 00:21:47
@mafutrct不! '如果errorlevel 1 ...'表示“如果错误大于或等于1”。换句话说,这会捕获所有错误,但不会“不需要复制”(robocopy的0退出代码)。但是,我认为你需要'如果%errorlevel%leq 1 exit 0 else exit%errorlevel%'。 – skrebbel 2012-10-31 10:27:34
添加每个请求的这个答案。基于Asaf的解决方案,并添加skrebbel的评论。
可以简化检查:
robocopy <opt> <src> <tgt>
if %errorlevel% leq 1 exit 0 else exit %errorlevel%
正如评论指出好心,你可能需要调整“1”:这取决于你的操作应该当作一个错误。看看the meaning of the bits that in combination make up the number returned by robocopy:
0×10严重错误。 Robocopy没有复制任何文件。这是 使用错误或由于源或目标目录上的访问权限不足导致的错误。
0×08某些文件或目录无法复制(出现复制错误 并超出重试限制)。进一步检查这些错误 。
0×04检测到一些不匹配的文件或目录。检查 输出日志。家务管理可能是必要的。
0×02检测到一些额外的文件或目录。检查输出 日志。一些家务管理可能是需要的。
0×01成功复制一个或多个文件(即新文件 已到达)。
0×00没有发生错误,也没有进行复制。目标目录树和目标目录树完全同步。
其实只有大于7(8以上)的值才表示失败,请参见我的回答 – 2016-06-20 15:42:08
谢谢@OhadSchneider,我已经编辑了答案以澄清此问题 – mafu 2016-06-20 22:34:20
检查的1退出代码是不正确,因为any exit code below 8 is non-erroneous:
任何大于8的值表明有在复制操作过程中的至少一个发生故障 。
(只是为了澄清,8退出代码是一个错误,以及:Several files did not copy
)
正确的代码,那么,应该是这样的:
IF %ERRORLEVEL% GEQ 8 exit 1
exit 0
这应该被接受的答案! – nawfal 2016-06-20 13:57:00
语法上这里是一个一行一行的版本,可直接在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
参考文献:
您可以请解释如何添加它s.t.它有相同的目的吗? – 2011-03-29 10:29:17
抱歉,代码被截断了我对编辑器不是很熟悉..我正在尝试理清如何正确添加代码 – 2011-03-29 11:13:56
我编辑了它。请确认这是你的意思。 – 2011-03-29 11:21:52