Pregunta ¿Cómo obtengo el código de salida de la aplicación desde una línea de comando de Windows?


Estoy ejecutando un programa y quiero ver cuál es su código de retorno (ya que devuelve códigos diferentes basados ​​en diferentes errores).

Sé en Bash que puedo hacer esto corriendo

echo $?

¿Qué hago cuando uso cmd.exe en Windows?


634
2017-12-02 18:04


origen


Respuestas:


Una variable de pseudo entorno llamada errorlevel almacena el código de salida:

echo Exit Code is %errorlevel%

También el if comando tiene una sintaxis especial:

if errorlevel

Ver if /? para detalles.

Ejemplo

@echo off
my_nify_exe.exe
if errorlevel 1 (
   echo Failure Reason Given is %errorlevel%
   exit /b %errorlevel%
)

Advertencia: si establece un nombre de variable de entorno errorlevel, %errorlevel% devolverá ese valor y no el código de salida. Usar (establecer errorlevel=) para borrar la variable de entorno, lo que permite el acceso al verdadero valor de errorlevel mediante el %errorlevel% Variable ambiental.


777
2017-12-02 18:07



Pruebas ErrorLevel trabaja para consola aplicaciones, pero como se insinuó por dmihailescu, esto no funcionará si estás intentando ejecutar un ventana aplicación (por ejemplo, basada en Win32) desde un símbolo del sistema. Se ejecutará una aplicación en ventana en segundo plano, y el control volverá inmediatamente al símbolo del sistema (lo más probable con un ErrorLevel de cero para indicar que el proceso fue creado exitosamente). Cuando finalmente sale una aplicación con ventana, se pierde su estado de salida.

Sin embargo, en lugar de utilizar el iniciador de C ++ basado en consola mencionado en otra parte, una alternativa más simple es iniciar una aplicación en ventana usando el símbolo del sistema. START /WAIT mando. Esto iniciará la aplicación con ventana, esperará a que salga y luego devolverá el control al símbolo del sistema con el estado de salida del proceso establecido en ErrorLevel.

start /wait something.exe
echo %errorlevel%

198
2017-07-13 18:57



Use la variable ERRORLEVEL incorporada:

echo %ERRORLEVEL%

Pero tenga cuidado si una aplicación ha definido una variable de entorno llamada ERRORLEVEL!


85
2017-12-02 18:09



Es posible que no funcione correctamente cuando se utiliza un programa que no está conectado a la consola, porque esa aplicación aún podría estar ejecutándose mientras crees que tienes el código de salida. Una solución para hacerlo en C ++ se ve a continuación:

#include "stdafx.h"
#include "windows.h"
#include "stdio.h"
#include "tchar.h"
#include "stdio.h"
#include "shellapi.h"

int _tmain( int argc, TCHAR *argv[] )
{

    CString cmdline(GetCommandLineW());
    cmdline.TrimLeft('\"');
    CString self(argv[0]);
    self.Trim('\"');
    CString args = cmdline.Mid(self.GetLength()+1);
    args.TrimLeft(_T("\" "));
    printf("Arguments passed: '%ws'\n",args);
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);
    ZeroMemory( &pi, sizeof(pi) );

    if( argc < 2 )
    {
        printf("Usage: %s arg1,arg2....\n", argv[0]);
        return -1;
    }

    CString strCmd(args);
    // Start the child process. 
    if( !CreateProcess( NULL,   // No module name (use command line)
        (LPTSTR)(strCmd.GetString()),        // Command line
        NULL,           // Process handle not inheritable
        NULL,           // Thread handle not inheritable
        FALSE,          // Set handle inheritance to FALSE
        0,              // No creation flags
        NULL,           // Use parent's environment block
        NULL,           // Use parent's starting directory 
        &si,            // Pointer to STARTUPINFO structure
        &pi )           // Pointer to PROCESS_INFORMATION structure
    ) 
    {
        printf( "CreateProcess failed (%d)\n", GetLastError() );
        return GetLastError();
    }
    else
        printf( "Waiting for \"%ws\" to exit.....\n", strCmd );

    // Wait until child process exits.
    WaitForSingleObject( pi.hProcess, INFINITE );
    int result = -1;
    if(!GetExitCodeProcess(pi.hProcess,(LPDWORD)&result))
    { 
        printf("GetExitCodeProcess() failed (%d)\n", GetLastError() );
    }
    else
        printf("The exit code for '%ws' is %d\n",(LPTSTR)(strCmd.GetString()), result );
    // Close process and thread handles. 
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );
    return result;
}

11
2018-06-25 17:05



Si desea hacer coincidir el código de error exactamente (por ejemplo, igual a 0), use esto:

@echo off
my_nify_exe.exe
if %ERRORLEVEL% EQU 0 (
   echo Success
) else (
   echo Failure Reason Given is %errorlevel%
   exit /b %errorlevel%
)

if errorlevel 0 partidos errorlevel > = 0. Ver if /?.


9
2017-07-29 16:08



Hubo un momento en que necesité insertar con precisión eventos de registro de Cygwin en el registro de eventos de Windows. Quería que los mensajes en WEVL fueran personalizados, que tuvieran el código de salida correcto, los detalles, las prioridades, el mensaje, etc. Así que creé un pequeño script de Bash para encargarme de esto. Aquí está en GitHub, logit.sh.

Algunos extractos:

usage: logit.sh [-h] [-p] [-i=n] [-s] <description>
example: logit.sh -p error -i 501 -s myscript.sh "failed to run the mount command"

Aquí está la parte del contenido del archivo temporal:

LGT_TEMP_FILE="$(mktemp --suffix .cmd)"
cat<<EOF>$LGT_TEMP_FILE
    @echo off
    set LGT_EXITCODE="$LGT_ID"
    exit /b %LGT_ID%
EOF
unix2dos "$LGT_TEMP_FILE"

Aquí hay una función para crear eventos en WEVL:

__create_event () {
    local cmd="eventcreate /ID $LGT_ID /L Application /SO $LGT_SOURCE /T $LGT_PRIORITY /D "
    if [[ "$1" == *';'* ]]; then
        local IFS=';'
        for i in "$1"; do
            $cmd "$i" &>/dev/null
        done
    else
        $cmd "$LGT_DESC" &>/dev/null
    fi
}

Ejecutar el script por lotes y llamar a __create_event:

cmd /c "$(cygpath -wa "$LGT_TEMP_FILE")"
__create_event

0
2018-02-28 19:33