Googled na „Win8 Jak uzyskać CMD, aby pokazać status wyjścia”, tak jak możemy to zrobić w Linuksie. To był najlepszy wybór i jest dokładny.
SDsolar
1
Możesz szybko zobaczyć, która aplikacja zwraca:app.exe & echo %errorlevel%
marbel82
Odpowiedzi:
976
Pseudo zmienna środowiskowa o nazwie errorlevelprzechowuje kod wyjścia:
echo Exit Code is %errorlevel%
Ponadto ifpolecenie ma specjalną składnię:
if errorlevel
Zobacz if /?szczegóły.
Przykład
@echo off
my_nify_exe.exe
if errorlevel 1 (
echo Failure Reason Given is %errorlevel%
exit /b %errorlevel%
)
Ostrzeżenie: jeśli ustawisz nazwę zmiennej środowiskowej errorlevel, %errorlevel%zwróci tę wartość, a nie kod wyjścia. Użyj ( set errorlevel=), aby wyczyścić zmienną środowiskową, umożliwiając dostęp do prawdziwej wartości za errorlevelpośrednictwem %errorlevel%zmiennej środowiskowej.
Jeśli korzystasz bezpośrednio z wiersza poleceń systemu Windows i zawsze widzisz 0, zobacz odpowiedź Gary'ego: stackoverflow.com/a/11476681/31629
Ken
9
Również jeśli jesteś w PowerShell, możesz użyćecho Exit Code is $LastExitCode
Brandon Pugh
11
Uwaga: „poziom błędu 1” jest prawdziwy, jeśli poziom błędu> = 1. Zatem „poziom błędu 0” będzie pasował do wszystkiego. Zobacz „if /?”. Zamiast tego możesz użyć „jeśli% ERRORLEVEL% EQU 0 (..)”.
Curtis Yallop,
1
Znaleziono przypadki, w których %ERRORLEVEL%wynosi 0, mimo że wystąpił błąd. Zdarzyło się podczas %ERRORLEVEL%wpisywania pliku cmd. Próbowanie start /waitnie zadziałało. Jedyne, co zadziałało, toif errorlevel 1 (...)
AlikElzin-kilaka
1
Przyjazna rada:% ErrorLevel% jest zmienną powłoki, a nie zmienną środowiskową, a także zwraca wartość stringan int, co oznacza, że nie można używać EQ/ NEQskutecznie.
kayleeFrye_onDeck
277
Testowanie ErrorLeveldziała dla aplikacji konsolowych , ale jak sugeruje dmihailescu , nie zadziała to, jeśli próbujesz uruchomić aplikację okienkową (np. Opartą na Win32) z wiersza poleceń. Aplikacja działająca w oknie uruchomi się w tle, a kontrola natychmiast powróci do wiersza poleceń (najprawdopodobniej z ErrorLevelzerą wskazującą, że proces został pomyślnie utworzony ). Gdy aplikacja okienkowa ostatecznie kończy działanie, jej status wyjścia zostaje utracony.
Zamiast korzystać z konsolowego programu uruchamiającego C ++ wspomnianego w innym miejscu, prostszą alternatywą jest uruchomienie aplikacji okienkowej za pomocą polecenia wiersza START /WAITpolecenia. Spowoduje to uruchomienie aplikacji okienkowej, poczekanie na jej zakończenie, a następnie przywrócenie sterowania do wiersza polecenia ze statusem zakończenia procesu ustawionym w ErrorLevel.
Wielkie dzięki za pomysł „START / czekaj”. To działało dla mnie :)
Timotei
3
dobry chwyt. Nie wiedziałem o tym poleceniu. Właśnie widziałem, że działa dla> start / wait notepad.exe
dmihailescu,
1
Innym powodem, dla którego może nie działać (zawsze zero) jest to, że znajduje się w iflub for. Rozważ użycie !errorlevel!zamiast tego, jak opisano w tej odpowiedzi .
Nie. Zmienne, polecenia (w tym „if”) i „equ” działają bez względu na przypadek.
Curtis Yallop,
14
Może nie działać poprawnie, gdy używasz programu, który nie jest podłączony do konsoli, ponieważ ta aplikacja może nadal działać, gdy uważasz, że masz kod wyjścia. Rozwiązanie w C ++ wygląda następująco:
#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;}
Istnieje zasadnicza różnica między sposobem ustawiania poziomów błędów w plikach wsadowych .CMD i .BAT:
Stary skrypt wsadowy .BAT uruchamiający „nowe” komendy wewnętrzne: APPEND, ASSOC, PATH, PROMPT, FTYPE i SET ustawią ERRORLEVEL tylko w przypadku wystąpienia błędu. Więc jeśli masz dwa polecenia w skrypcie wsadowym, a pierwsze nie powiedzie się, ERRORLEVEL pozostanie ustawiony nawet po udanym drugim poleceniu.
Może to utrudnić debugowanie skryptu BAT, skrypt wsadowy CMD jest bardziej spójny i ustawi ERRORLEVEL po każdej komendzie, którą uruchomisz [źródło].
Nie powodowało to końca smutku, gdy wykonywałem kolejne polecenia, ale ERRORLEVEL pozostałby niezmieniony nawet w przypadku awarii.
W pewnym momencie musiałem dokładnie przesłać zdarzenia dziennika z Cygwin do dziennika zdarzeń Windows. Chciałem, aby komunikaty w WEVL były niestandardowe, miały poprawny kod wyjścia, szczegóły, priorytety, komunikat itp. Więc stworzyłem mały skrypt Bash, aby się tym zająć. Tutaj jest na GitHub, logit.sh .
Niektóre fragmenty:
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"
Oto część zawartości pliku tymczasowego:
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"
Oto funkcja tworzenia zdarzeń w 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
}
Wykonanie skryptu wsadowego i wywołanie __create_event:
app.exe & echo %errorlevel%
Odpowiedzi:
Pseudo zmienna środowiskowa o nazwie
errorlevel
przechowuje kod wyjścia:Ponadto
if
polecenie ma specjalną składnię:Zobacz
if /?
szczegóły.Przykład
Ostrzeżenie: jeśli ustawisz nazwę zmiennej środowiskowej
errorlevel
,%errorlevel%
zwróci tę wartość, a nie kod wyjścia. Użyj (set errorlevel=
), aby wyczyścić zmienną środowiskową, umożliwiając dostęp do prawdziwej wartości zaerrorlevel
pośrednictwem%errorlevel%
zmiennej środowiskowej.źródło
echo Exit Code is $LastExitCode
%ERRORLEVEL%
wynosi 0, mimo że wystąpił błąd. Zdarzyło się podczas%ERRORLEVEL%
wpisywania pliku cmd. Próbowaniestart /wait
nie zadziałało. Jedyne, co zadziałało, toif errorlevel 1 (...)
string
anint
, co oznacza, że nie można używaćEQ
/NEQ
skutecznie.Testowanie
ErrorLevel
działa dla aplikacji konsolowych , ale jak sugeruje dmihailescu , nie zadziała to, jeśli próbujesz uruchomić aplikację okienkową (np. Opartą na Win32) z wiersza poleceń. Aplikacja działająca w oknie uruchomi się w tle, a kontrola natychmiast powróci do wiersza poleceń (najprawdopodobniej zErrorLevel
zerą wskazującą, że proces został pomyślnie utworzony ). Gdy aplikacja okienkowa ostatecznie kończy działanie, jej status wyjścia zostaje utracony.Zamiast korzystać z konsolowego programu uruchamiającego C ++ wspomnianego w innym miejscu, prostszą alternatywą jest uruchomienie aplikacji okienkowej za pomocą polecenia wiersza
START /WAIT
polecenia. Spowoduje to uruchomienie aplikacji okienkowej, poczekanie na jej zakończenie, a następnie przywrócenie sterowania do wiersza polecenia ze statusem zakończenia procesu ustawionym wErrorLevel
.źródło
if
lubfor
. Rozważ użycie!errorlevel!
zamiast tego, jak opisano w tej odpowiedzi .Użyj wbudowanej zmiennej ERRORLEVEL:
Ale uwaga, jeśli aplikacja zdefiniowała zmienną środowiskową o nazwie ERRORLEVEL !
źródło
$LastExitCode
w PowerShell.Jeśli chcesz dokładnie dopasować kod błędu (np. Wynosi 0), użyj tego:
if errorlevel 0
dopasowaniaerrorlevel
> = 0. Patrzif /?
.źródło
Może nie działać poprawnie, gdy używasz programu, który nie jest podłączony do konsoli, ponieważ ta aplikacja może nadal działać, gdy uważasz, że masz kod wyjścia. Rozwiązanie w C ++ wygląda następująco:
źródło
Warto zauważyć, że pliki .BAT i .CMD działają inaczej.
Czytając https://ss64.com/nt/errorlevel.html odnotowuje:
Nie powodowało to końca smutku, gdy wykonywałem kolejne polecenia, ale ERRORLEVEL pozostałby niezmieniony nawet w przypadku awarii.
źródło
W pewnym momencie musiałem dokładnie przesłać zdarzenia dziennika z Cygwin do dziennika zdarzeń Windows. Chciałem, aby komunikaty w WEVL były niestandardowe, miały poprawny kod wyjścia, szczegóły, priorytety, komunikat itp. Więc stworzyłem mały skrypt Bash, aby się tym zająć. Tutaj jest na GitHub, logit.sh .
Niektóre fragmenty:
Oto część zawartości pliku tymczasowego:
Oto funkcja tworzenia zdarzeń w WEVL:
Wykonanie skryptu wsadowego i wywołanie __create_event:
źródło