Googled для «Win8 Как получить приглашение CMD для отображения состояния выхода», как мы можем сделать в Linux. Это был лучший выбор, и это точно.
SDsolar
1
Вы можете быстро увидеть, что возвращает приложение:app.exe & echo %errorlevel%
marbel82
Ответы:
977
Псевдопеременная переменная named errorlevelхранит код выхода:
echo Exit Code is %errorlevel%
Также ifкоманда имеет специальный синтаксис:
if errorlevel
Смотрите if /?подробности.
пример
@echo off
my_nify_exe.exe
if errorlevel 1 (
echo Failure Reason Given is %errorlevel%
exit /b %errorlevel%
)
Предупреждение: если вы зададите имя переменной среды errorlevel, %errorlevel%будет возвращено это значение, а не код выхода. Используйте ( set errorlevel=) для очистки переменной среды, предоставляя доступ к истинному значению переменной errorlevelчерез %errorlevel%переменную среды.
Если вы работаете непосредственно из командной строки Windows и всегда видите возвращенный 0, посмотрите ответ Гэри: stackoverflow.com/a/11476681/31629
Кен,
9
Также, если вы в PowerShell, вы можете использоватьecho Exit Code is $LastExitCode
Брэндон Пью
11
Примечание. «Errorlevel 1» имеет значение true, если errorlevel> = 1. Таким образом, «errorlevel 0» будет соответствовать всему. Видишь ли, если /?". Вместо этого вы можете использовать «if% ERRORLEVEL% EQU 0 (..)».
Кертис Яллоп
1
Найдены случаи, когда %ERRORLEVEL%0, хотя произошла ошибка. Произошло при проверке %ERRORLEVEL%в cmd-файле. Попытка start /waitне сработала. Единственное, что сработало,if errorlevel 1 (...)
АликЭльзин-килака
1
Дружественный совет:% ErrorLevel% - это переменная оболочки, а не переменная окружения, и она также возвращает stringnot int, то есть вы не можете использовать EQ/ NEQэффективно.
kayleeFrye_onDeck
277
Тестирование ErrorLevelработает для консольных приложений, но, как намекнул dmihailescu , это не сработает, если вы пытаетесь запустить оконное приложение (например, на основе Win32) из командной строки. Оконное приложение будет работать в фоновом режиме, и элемент управления немедленно вернется в командную строку (скорее всего, с ErrorLevelнулем, указывающим, что процесс был успешно создан ). Когда оконное приложение в конечном итоге завершает работу, его состояние выхода теряется.
Однако вместо использования средства запуска C ++ на основе консоли, упомянутого в другом месте, более простой альтернативой является запуск оконного приложения с помощью команды командной строки START /WAIT. Это запустит оконное приложение, дождется его завершения и вернет управление в командную строку со статусом завершения процесса, установленным в ErrorLevel.
Большое спасибо за идею "START / wait". Это сработало для меня :)
Timotei
3
Хорошо поймал. Я не знал об этой команде. Я только что видел, как это работает для> запуска / ожидания notepad.exe
dmihailescu
1
Другая причина, по которой он может не работать (всегда ноль) - это когда он внутри ifили for. Попробуйте использовать !errorlevel!вместо этого, как описано в этом ответе .
Нет. Vars, команды (включая «if») и «equ» работают независимо от ситуации.
Кертис Яллоп
14
Он может работать некорректно при использовании программы, которая не подключена к консоли, потому что это приложение может все еще работать, пока вы думаете, что у вас есть код выхода. Решение сделать это в C ++ выглядит следующим образом:
#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;}
Между способами пакетных файлов .CMD и .BAT установить уровни ошибок:
Старый пакетный скрипт .BAT, выполняющий «новые» внутренние команды: APPEND, ASSOC, PATH, PROMPT, FTYPE и SET, будет только устанавливать ERRORLEVEL в случае возникновения ошибки. Таким образом, если у вас есть две команды в пакетном сценарии, и первая не выполняется, ERRORLEVEL останется установленным даже после успешного выполнения второй команды.
Это может усложнить отладку проблемного сценария BAT, пакетный сценарий CMD более согласован и будет устанавливать значение ERRORLEVEL после каждой команды, которую вы запускаете [source].
Это приводило меня к бесконечной скорби, поскольку я выполнял последовательные команды, но ОШИБКА оставалась неизменной даже в случае сбоя.
В какой-то момент мне нужно было точно передать события журнала из Cygwin в журнал событий Windows. Я хотел, чтобы сообщения в WEVL были персонализированными, имели правильный код завершения, детали, приоритеты, сообщения и т. Д. Поэтому я создал небольшой скрипт Bash, чтобы позаботиться об этом. Вот это на GitHub, logit.sh .
Некоторые выдержки:
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"
Вот часть содержимого временного файла:
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"
Вот функция для создания событий в 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
}
Выполнение пакетного сценария и вызов __create_event:
app.exe & echo %errorlevel%
Ответы:
Псевдопеременная переменная named
errorlevel
хранит код выхода:Также
if
команда имеет специальный синтаксис:Смотрите
if /?
подробности.пример
Предупреждение: если вы зададите имя переменной среды
errorlevel
,%errorlevel%
будет возвращено это значение, а не код выхода. Используйте (set errorlevel=
) для очистки переменной среды, предоставляя доступ к истинному значению переменнойerrorlevel
через%errorlevel%
переменную среды.источник
echo Exit Code is $LastExitCode
%ERRORLEVEL%
0, хотя произошла ошибка. Произошло при проверке%ERRORLEVEL%
в cmd-файле. Попыткаstart /wait
не сработала. Единственное, что сработало,if errorlevel 1 (...)
string
notint
, то есть вы не можете использоватьEQ
/NEQ
эффективно.Тестирование
ErrorLevel
работает для консольных приложений, но, как намекнул dmihailescu , это не сработает, если вы пытаетесь запустить оконное приложение (например, на основе Win32) из командной строки. Оконное приложение будет работать в фоновом режиме, и элемент управления немедленно вернется в командную строку (скорее всего, сErrorLevel
нулем, указывающим, что процесс был успешно создан ). Когда оконное приложение в конечном итоге завершает работу, его состояние выхода теряется.Однако вместо использования средства запуска C ++ на основе консоли, упомянутого в другом месте, более простой альтернативой является запуск оконного приложения с помощью команды командной строки
START /WAIT
. Это запустит оконное приложение, дождется его завершения и вернет управление в командную строку со статусом завершения процесса, установленным вErrorLevel
.источник
if
илиfor
. Попробуйте использовать!errorlevel!
вместо этого, как описано в этом ответе .Используйте встроенную переменную ERRORLEVEL:
Но будьте осторожны, если приложение определило переменную среды с именем ERRORLEVEL !
источник
$LastExitCode
в PowerShell.Если вы хотите точно соответствовать коду ошибки (например, равно 0), используйте это:
if errorlevel 0
совпаденияerrorlevel
> = 0. Смотритеif /?
.источник
Он может работать некорректно при использовании программы, которая не подключена к консоли, потому что это приложение может все еще работать, пока вы думаете, что у вас есть код выхода. Решение сделать это в C ++ выглядит следующим образом:
источник
Стоит отметить, что файлы .BAT и .CMD работают по-разному.
Читая https://ss64.com/nt/errorlevel.html, он отмечает следующее:
Это приводило меня к бесконечной скорби, поскольку я выполнял последовательные команды, но ОШИБКА оставалась неизменной даже в случае сбоя.
источник
В какой-то момент мне нужно было точно передать события журнала из Cygwin в журнал событий Windows. Я хотел, чтобы сообщения в WEVL были персонализированными, имели правильный код завершения, детали, приоритеты, сообщения и т. Д. Поэтому я создал небольшой скрипт Bash, чтобы позаботиться об этом. Вот это на GitHub, logit.sh .
Некоторые выдержки:
Вот часть содержимого временного файла:
Вот функция для создания событий в WEVL:
Выполнение пакетного сценария и вызов __create_event:
источник