2011-03-29 15 views
23

Robocopy genera 1 cuando tiene éxito, a diferencia de la mayoría de los programas que salen con 0 en caso de éxito. Visual Studio (y MSBUILD) interpreta el código de salida de 1 como un error.Uso de robocopy con Visual Studio 2010 Eventos posteriores a la compilación y preconstrucción

¿Cómo se puede utilizar Robocopy en los eventos posteriores a la construcción de Visual Studio de modo que el entorno de compilación identifique correctamente su falla y éxito?

Nota: esto es más o menos un reenvío de this post.

Respuesta

4

MSBuild extensionpack contiene una tarea que Robocopy puedes usarlo en tu proceso de construcción.
¿Puede ser esta una solución para usted en lugar de los eventos VS pre/postbuild?

Si es así, puede extend the Visual Studio Build Process reemplazando los objetivos BeforeBuild, AfterBuild y llamar a la tarea Robocopy (se puede reemplazar otros objetivos, así si se adapte a sus necesidades mejor, vea la lista en la página vinculada MSDN)
Así en realidad debería descargar e instalar MSBuild extensionpack de abrir su archivo csproj/vbproj del proyecto y edite la siguiente manera:

Adición de entradas siguientes para importar la tarea de MSBuild Robocopy extensionpack

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

Anulación BeforeBuild, AfterBuild y ejecución de la tarea 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

¿Podría explicar en su respuesta cómo agregarlo en el momento? sirve el mismo propósito? –

+0

lo siento, el código fue truncado No estoy muy familiarizado con el editor .. Estoy tratando de resolver cómo agregar el código correctamente –

+0

Lo he editado. Por favor, verifica que esto es lo que querías decir. –

19

Con <src>, <TGT> ser el origen de la copia y el objetivo con respeto, y <opt> siendo opciones Robocopy:

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

Por ejemplo, si queremos copiar el objetivo del proyecto en c: \ temp, sin reintentos y con todos los subdirectorios vacíos (o no), que usaríamos:

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

también podría simplemente usar 'if errorlevel 1 exit 0 else exit% errorlevel%' – mafu

+1

@mafutrct: ¡Wunderbar! Si agregaste tu comentario como respuesta, lo votaría mejor. –

+5

@mafutrct ¡No! 'if errorlevel 1 ...' significa "si el error fue mayor o igual que 1". En otras palabras, esto capta todos los errores, pero no "no se necesitó copiar" (código de salida 0 de robocopy). Pero creo que necesita 'si% errorlevel% leq 1 exit 0 else exit% errorlevel%'. – skrebbel

17

La adición de esta respuesta por encargo. Basado en la solución de Asaf, y agregando el comentario de skrebbel.

puede simplificar el cheque a:

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

Como amablemente señalado en los comentarios, es posible que desee ajustar el '1': Depende de lo que su operación se debe tratar como un error. Eche un vistazo a the meaning of the bits that in combination make up the number returned by robocopy:

0 × 10 Error grave. Robocopy no copió ningún archivo. Esto es un error de uso de o un error debido a privilegios de acceso insuficientes en los directorios de origen o de destino .

0 × 08 Algunos archivos o directorios no se pudieron copiar (se produjeron errores de copia y se rebasó el límite de reintento). Compruebe estos errores más.

0 × 04 Se detectaron algunos archivos o directorios no coincidentes. Examine el registro de salida . La limpieza es probablemente necesaria.

0 × 02 Algunos archivos extra o directorios fueron detectados. Examine el registro de salida . Algo de limpieza puede ser necesario.

0 × 01 Uno o más archivos se han copiado correctamente (es decir, han llegado nuevos archivos ).

0 × 00 No se han producido errores y no se ha realizado ninguna copia. Los árboles de directorios de destino de fuente y están completamente sincronizados.

+0

En realidad solo los valores superiores a 7 (8 y superiores) indican un error, consulte mi respuesta a continuación –

+1

Gracias @OhadSchneider, he editado la respuesta para aclarar esto – mafu

7

Simplemente la comprobación de un código de salida de 1 es incorrecto, como any exit code below 8 is non-erroneous:

Cualquier valor mayor que 8 indica que hubo al menos un fallo durante la operación de copia.

(Solo para aclarar, el código de salida 8 es un error así: Several files did not copy)

El código apropiado, entonces, debería tener este aspecto:

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

Esto debería ser la respuesta aceptada! – nawfal

3

sintácticamente aquí es una versión de una línea-por-comando que funciona directamente en los pasos prefabricados:

(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 

Referencias:

Cuestiones relacionadas