2011-03-29 69 views

回答

4

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> 
+0

您可以请解释如何添加它s.t.它有相同的目的吗? – 2011-03-29 10:29:17

+0

抱歉,代码被截断了我对编辑器不是很熟悉..我正在尝试理清如何正确添加代码 – 2011-03-29 11:13:56

+0

我编辑了它。请确认这是你的意思。 – 2011-03-29 11:21:52

19

随着<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 
+9

你也可以简单地使用'如果errorlevel 1 exit 0 else exit%errorlevel%' – mafu 2011-10-12 09:43:48

+1

@mafutrct:Wunderbar!如果你添加了你的评论作为答案,我会upvote它。 – 2012-03-01 00:21:47

+5

@mafutrct不! '如果errorlevel 1 ...'表示“如果错误大于或等于1”。换句话说,这会捕获所有错误,但不会“不需要复制”(robocopy的0退出代码)。但是,我认为你需要'如果%errorlevel%leq 1 exit 0 else exit%errorlevel%'。 – skrebbel 2012-10-31 10:27:34

17

添加每个请求的这个答案。基于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没有发生错误,也没有进行复制。目标目录树和目标目录树完全同步。

+0

其实只有大于7(8以上)的值才表示失败,请参见我的回答 – 2016-06-20 15:42:08

+1

谢谢@OhadSchneider,我已经编辑了答案以澄清此问题 – mafu 2016-06-20 22:34:20

7
只需

检查的1退出代码是不正确,因为any exit code below 8 is non-erroneous

任何大于8的值表明有在复制操作过程中的至少一个发生故障 。

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

正确的代码,那么,应该是这样的:

IF %ERRORLEVEL% GEQ 8 exit 1 
exit 0 
+1

这应该被接受的答案! – nawfal 2016-06-20 13:57:00

3

语法上这里是一个一行一行的版本,可直接在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 

参考文献:

相关问题