在Visual Studio 2010后期构建和预构建事件中使用robocopy

Asa*_*f R 31 msbuild batch-file robocopy visual-studio-2010

Robocopy在成功时输出1,与大多数成功退出0的程序不同.Visual Studio(和MSBUILD)将退出代码1解释为错误.

如何在Visual Studio后期和预构建事件中使用Robocopy,以便构建环境正确识别其失败和成功?

注意:这或多或少是这篇文章的转贴.

maf*_*afu 23

根据请求添加此答案.基于Asaf的解决方案,并添加skrebbel的评论.

您可以将检查简化为:

robocopy <opt> <src> <tgt>
if %errorlevel% leq 1 exit 0 else exit %errorlevel%
Run Code Online (Sandbox Code Playgroud)

正如评论中所说的那样,您可能需要调整"1":这取决于您的操作应该视为错误.看一下组合构成robocopy返回的数字的位的含义:

0×10严重错误.Robocopy没有复制任何文件.由于源或目标目录上的访问权限不足,这可能是使用错误或错误.

0×08无法复制某些文件或目录(发生了复制错误并超出了重试限制).进一步检查这些错误.

0×04检测到一些不匹配的文件或目录.检查输出日志.家政可能是必要的.

0×02检测到一些额外的文件或目录.检查输出日志.可能需要一些家政服务.

0×01成功复制了一个或多个文件(即新文件已到达).

0×00未发生错误,未进行复制.源目标树和目标目录树完全同步.


Asa*_*f R 19

使用<src>,<tgt>作为复制源和目标,<opt>是robocopy选项:

robocopy <opt> <src> <tgt>
set rce=%errorlevel%
if not %rce%==1 exit %rce% else exit 0
Run Code Online (Sandbox Code Playgroud)

例如,如果我们想要将项目目标复制到c:\ temp,而不重试和所有子目录(空或不),我们将使用:

robocopy /R:0 /E $(TargetDir) c:\temp
set rce=%errorlevel%
if not %rce%==1 exit %rce% else exit 0
Run Code Online (Sandbox Code Playgroud)

  • 你也可以简单地使用`if errorlevel 1 exit 0 else exit%errorlevel%` (9认同)
  • @mafutrct不!`if errorlevel 1 ...`表示"如果错误大于或等于1".换句话说,这会捕获所有错误,但不会"不需要复制"(robocopy的0退出代码).但是我认为你需要`if%errorlevel%leq 1退出0否则退出%errorlevel%`. (5认同)

Oha*_*der 9

只需检查退出代码为1是不正确的,因为8以下的任何退出代码都是非错误的:

任何大于8的值表示复制操作期间至少有一个失败.

(只是为了澄清,8退出代码是错误的,以及:Several files did not copy)

那么,正确的代码应如下所示:

IF %ERRORLEVEL% GEQ 8 exit 1
exit 0
Run Code Online (Sandbox Code Playgroud)


cro*_*sek 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
Run Code Online (Sandbox Code Playgroud)

参考文献:


Ján*_*agy 4

MSBuild 扩展包包含可在构建过程中使用的 Robocopy 任务。
这可以成为您的解决方案,而不是 VS 构建前/构建后事件吗?

如果是这样,您可以通过覆盖 BeforeBuild、AfterBuild 目标并调用 Robocopy 任务来扩展 Visual Studio 构建过程(如果其他目标更适合您的需求,您也可以覆盖其他目标,请参阅链接的 MSDN 页面中的列表)
所以实际上您应该下载并安装 MSBuild 扩展包,而不是打开项目的 csproj/vbproj 文件并按以下方式编辑:

添加以下条目以导入 MSBuild 扩展包的 Robocopy 任务

<PropertyGroup>
    <TPath>$(MSBuildExtensionsPath32)\ExtensionPack\4.0\MSBuild.ExtensionPack.tasks</TPath>        
</PropertyGroup>
<Import Project="$(TPath)"/>
Run Code Online (Sandbox Code Playgroud)

覆盖 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>
Run Code Online (Sandbox Code Playgroud)