2009-05-18 7 views
7

Tengo un archivo de proceso por lotes que usa el comando exit para devolver un código de salida.Honrar códigos de salida de archivos por lotes invocados por msbuild

Este archivo por lotes puede, en algunos casos, invocarse interactivamente desde una línea de comandos, o en otros casos, puede ejecutarse como parte de un proyecto MSBuild, utilizando la tarea Exec.

  • Si uso exit %errorlevel% dentro de mi archivo por lotes que esto funciona bien y MSBuild ve el código de error, sin embargo un usuario interactivo que está ejecutando el archivo por lotes desde una ventana de comandos obtendrá una salida grosera de cmd.exe en este caso.
  • Si uso exit /b %errorlevel% el escenario interactivo no obtiene una salida grosera, pero esto también significa que el cmd iniciado por la tarea Exec tampoco se cierra y, por lo tanto, MSBuild no ve el valor devuelto.

Como solución a ambos problemas, estoy tratando de utilizar exit /b pero ejecutar el archivo por lotes de mi escritura de la estructura como esta:

<Exec Command="Batch.cmd params &amp; exit %errorlevel%" /> 

La idea es que explícitamente tomar el 'no terminal 'return from exit /b y llame manualmente al exit para propocionar este valor fuera de cmd.exe donde la tarea de compilación Exec puede verlo.

Parece la solución perfecta, pero no funciona. Exec aún no obtiene el valor de error correcto.

Respuesta

13

Una forma de manejar esto podría ser que MSBuild pase un parámetro al archivo por lotes para que sepa que MSBuild lo está llamando en lugar de un símbolo del sistema. Por ejemplo yo he creado al test.bat archivo de ejemplo se muestra a continuación

ECHO OFF 

IF (%1)==() goto Start 
SET fromMSBuild=1 

:Start 

ECHO fromMSBuild:%fromMSBuild% 


REM ***** Perform your actions here ***** 

set theExitCode=101 
GOTO End 



:End 
IF %fromMSBuild%==1 exit %theExitCode% 


REM **** Not from MSBuild **** 

ECHO Exiting with exit code %theExitCode% 
exit /b %theExitCode% 

Y hemos creado el archivo de MSBuild wrapper.proj que es:

<Project DefaultTargets="Demo" ToolsVersion="3.5" 
     xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 

    <PropertyGroup> 
    <BatchFile>test.bat</BatchFile> 
    <FromMSBuild>FromMSBuild</FromMSBuild> 
    </PropertyGroup> 

    <Target Name="Demo"> 

    <Message Text="Executing batch file $(BatchFile)" Importance="high"/> 

    <PropertyGroup> 
     <_Command>$(BatchFile) $(FromMSBuild)</_Command> 
    </PropertyGroup> 

    <Exec Command="$(_Command)"> 
     <Output PropertyName="CommandExitCode" TaskParameter="ExitCode"/> 
    </Exec> 

    <Message Text="CommandExitCode: $(CommandExitCode)"/> 

    </Target> 
</Project> 

Si se ejecuta el archivo test.bat desde el símbolo del sistema es el resultado

C:\Data\Development\My Code\Community\MSBuild\BatchFile>test.bat 

C:\Data\Development\My Code\Community\MSBuild\BatchFile>ECHO OFF 
fromMSBuild:0 
Exiting with exit code 101 

Y a partir de MSBuild el resultado es:

C:\Data\Development\My Code\Community\MSBuild\BatchFile>msbuild Wrapper.proj /t:Demo /fl /nologo 
Build started 5/18/2009 10:54:52 PM. 
Project "C:\Data\Development\My Code\Community\MSBuild\BatchFile\Wrapper.proj" on node 0 (Demo target(s)). 
    Executing batch file test.bat 
    fromMSBuild:1 
C:\Data\Development\My Code\Community\MSBuild\BatchFile\Wrapper.proj(17,5): error MSB3073: The command "test.bat FromMSBuild" exi 
ted with code 101. 
Done Building Project "C:\Data\Development\My Code\Community\MSBuild\BatchFile\Wrapper.proj" (Demo target(s)) -- FAILED. 


Build FAILED. 

"C:\Data\Development\My Code\Community\MSBuild\BatchFile\Wrapper.proj" (Demo target) (1) -> 
(Demo target) -> 
    C:\Data\Development\My Code\Community\MSBuild\BatchFile\Wrapper.proj(17,5): error MSB3073: The command "test.bat FromMSBuild" e 
xited with code 101. 

    0 Warning(s) 
    1 Error(s) 

Time Elapsed 00:00:00.06 

Sayed Ibrahim Hashimi

Mi libro: Inside the Microsoft Build Engine : Using MSBuild and Team Foundation Build

0

No he probado esto, pero lo que si que acaba de establecer una variable de entorno llamada ERRORLEVEL? Oculto después del contenido de su comando Exec, MSBuild tiene "exit% ERRORLEVEL%". % ERRORLEVEL% si se establece anula cualquier nivel de error real.

2

Esta pregunta es un poco mayor, pero la respuesta aún pueden ser de interés, así que aquí va:

modificar ligeramente su tarea MSBuild a

<Exec Command='cmd.exe /C "call Batch.cmd params &amp;&amp; exit %errorlevel%"' /> 

Y mantener el

exit /b %errorlevel% 

en su Batch.cmd.

Cuestiones relacionadas