Busqué en Google "Win8 Cómo obtener el indicador CMD para mostrar el estado de salida" como podemos hacer en Linux. Esta fue la mejor selección, y es precisa.
SDsolar
1
Puede ver rápidamente qué aplicación regresa:app.exe & echo %errorlevel%
marbel82
Respuestas:
976
Una pseudo variable de entorno llamada errorlevelalmacena el código de salida:
echo Exit Code is %errorlevel%
Además, el ifcomando tiene una sintaxis especial:
if errorlevel
Ver if /?para más 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. Use ( set errorlevel=) para borrar la variable de entorno, permitiendo el acceso al valor verdadero de a errorleveltravés de la %errorlevel%variable de entorno
Si está ejecutando directamente desde una línea de comandos de Windows y siempre ve 0 devuelto, vea la respuesta de Gary: stackoverflow.com/a/11476681/31629
Ken
99
Además, si está en PowerShell, puede usarloecho Exit Code is $LastExitCode
Brandon Pugh el
11
Nota: "errorlevel 1" es verdadero si errorlevel> = 1. Entonces "errorlevel 0" coincidirá con todo. Ve si /?". En su lugar, puede usar "if% ERRORLEVEL% EQU 0 (..)".
Curtis Yallop
1
Se encontraron casos donde %ERRORLEVEL%es 0 a pesar de que ocurrió un error. Sucedió al registrar %ERRORLEVEL%un archivo cmd. Intentar start /waitno funcionó. Lo único que funcionó esif errorlevel 1 (...)
AlikElzin-kilaka
1
Consejo amigable:% ErrorLevel% es una variable de shell, no una variable de entorno, y también devuelve un stringno int, lo que significa que no puede usar EQ/ NEQefectivamente.
kayleeFrye_onDeck
277
Las pruebas ErrorLevelfuncionan para aplicaciones de consola , pero como lo indica dmihailescu , esto no funcionará si está intentando ejecutar una aplicación con ventana (por ejemplo, basada en Win32) desde un símbolo del sistema. Una aplicación con ventana se ejecutará en segundo plano, y el control volverá inmediatamente al símbolo del sistema (muy probablemente con un ErrorLevelcero para indicar que el proceso se creó con éxito). Cuando una aplicación con ventana finalmente sale, su estado de salida se pierde.
Sin embargo, en lugar de usar 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 comando del símbolo del sistema START /WAIT. Esto iniciará la aplicación en ventana, esperará a que salga y luego devolverá el control al símbolo del sistema con el estado de salida del proceso establecido ErrorLevel.
Muchas gracias por la idea "START / wait". Eso funcionó para mí :)
Timotei
3
buena atrapada. No sabía sobre ese comando. Yo sólo he visto trabajar para> start / wait notepad.exe
dmihailescu
1
Otra razón por la que podría no funcionar (siempre cero) es cuando está dentro de un ifo for. Considere usar en su !errorlevel!lugar, como se describe en esta respuesta .
No. vars, comandos (incluyendo "if") y "equ" funcionan sin importar el caso.
Curtis Yallop
14
Es posible que no funcione correctamente cuando se utiliza un programa que no está conectado a la consola, porque esa aplicación aún puede estar ejecutándose mientras cree que tiene 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 FALSE0,// 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());returnGetLastError();}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;}
Hay una diferencia clave entre la forma en que los archivos por lotes .CMD y .BAT establecen niveles de error:
Un antiguo script por lotes .BAT que ejecuta los comandos internos 'nuevos': APPEND, ASSOC, PATH, PROMPT, FTYPE y SET solo establecerá ERRORLEVEL si se produce un error. Entonces, si tiene dos comandos en el script por lotes y el primero falla, el ERRORLEVEL permanecerá establecido incluso después de que el segundo comando tenga éxito.
Esto puede dificultar la depuración de un script BAT problemático, un script por lotes CMD es más consistente y establecerá ERRORLEVEL después de cada comando que ejecute [fuente].
Esto me estaba causando un sinfín de penas ya que estaba ejecutando comandos sucesivos, pero el ERRORLEVEL permanecería sin cambios incluso en caso de falla.
En un momento, necesitaba insertar con precisión los 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, detalles, prioridades, mensajes, etc. Así que creé un pequeño script 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
}
Ejecutando el script por lotes y llamando a __create_event:
app.exe & echo %errorlevel%
Respuestas:
Una pseudo variable de entorno llamada
errorlevel
almacena el código de salida:Además, el
if
comando tiene una sintaxis especial:Ver
if /?
para más detalles.Ejemplo
Advertencia: si establece un nombre de variable de entorno
errorlevel
,%errorlevel%
devolverá ese valor y no el código de salida. Use (set errorlevel=
) para borrar la variable de entorno, permitiendo el acceso al valor verdadero de aerrorlevel
través de la%errorlevel%
variable de entornofuente
echo Exit Code is $LastExitCode
%ERRORLEVEL%
es 0 a pesar de que ocurrió un error. Sucedió al registrar%ERRORLEVEL%
un archivo cmd. Intentarstart /wait
no funcionó. Lo único que funcionó esif errorlevel 1 (...)
string
noint
, lo que significa que no puede usarEQ
/NEQ
efectivamente.Las pruebas
ErrorLevel
funcionan para aplicaciones de consola , pero como lo indica dmihailescu , esto no funcionará si está intentando ejecutar una aplicación con ventana (por ejemplo, basada en Win32) desde un símbolo del sistema. Una aplicación con ventana se ejecutará en segundo plano, y el control volverá inmediatamente al símbolo del sistema (muy probablemente con unErrorLevel
cero para indicar que el proceso se creó con éxito). Cuando una aplicación con ventana finalmente sale, su estado de salida se pierde.Sin embargo, en lugar de usar 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 comando del símbolo del sistema
START /WAIT
. Esto iniciará la aplicación en ventana, esperará a que salga y luego devolverá el control al símbolo del sistema con el estado de salida del proceso establecidoErrorLevel
.fuente
if
ofor
. Considere usar en su!errorlevel!
lugar, como se describe en esta respuesta .Use la variable ERRORLEVEL incorporada:
Pero tenga cuidado si una aplicación ha definido una variable de entorno llamada ERRORLEVEL !
fuente
$LastExitCode
en PowerShell.Si desea coincidir exactamente con el código de error (por ejemplo, igual a 0), use esto:
if errorlevel 0
coincidenciaserrorlevel
> = 0. Verif /?
.fuente
Es posible que no funcione correctamente cuando se utiliza un programa que no está conectado a la consola, porque esa aplicación aún puede estar ejecutándose mientras cree que tiene el código de salida. Una solución para hacerlo en C ++ se ve a continuación:
fuente
Vale la pena señalar que los archivos .BAT y .CMD funcionan de manera diferente.
Al leer https://ss64.com/nt/errorlevel.html , observa lo siguiente:
Esto me estaba causando un sinfín de penas ya que estaba ejecutando comandos sucesivos, pero el ERRORLEVEL permanecería sin cambios incluso en caso de falla.
fuente
En un momento, necesitaba insertar con precisión los 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, detalles, prioridades, mensajes, etc. Así que creé un pequeño script Bash para encargarme de esto. Aquí está en GitHub, logit.sh .
Algunos extractos:
Aquí está la parte del contenido del archivo temporal:
Aquí hay una función para crear eventos en WEVL:
Ejecutando el script por lotes y llamando a __create_event:
fuente