Как получить код выхода приложения из командной строки Windows?

Я запускаю программу и хочу узнать, каков ее код возврата (поскольку она возвращает разные коды в зависимости от разных ошибок).

Я знаю, что в Bash я могу сделать это, запустив

echo $?

Что мне делать при использовании cmd.exe в Windows?

Также спрашивали у SuperUser: Как проверить код выхода последней команды в пакетном файле?

Deanna 24.06.2013 15:42

Погуглил "Win8 Как получить приглашение CMD для отображения статуса выхода", как мы можем это сделать в Linux. Это был лучший выбор, и он точен.

SDsolar 21.05.2018 23:33

Вы можете быстро увидеть, какое приложение возвращает: app.exe & echo %errorlevel%

marbel82 19.02.2019 13:28
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
841
3
833 682
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Ответ принят как подходящий

Переменная псевдо-среды с именем 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

Ken 30.08.2012 17:51

Также, если вы используете PowerShell, вы можете использовать echo Exit Code is $LastExitCode

Brandon Pugh 16.01.2014 23:47

Примечание. «Errorlevel 1» истинно, если errorlevel> = 1. Таким образом, «errorlevel 0» будет соответствовать всему. Видишь ли, если /?". Вместо этого вы можете использовать «if% ERRORLEVEL% EQU 0 (..)».

Curtis Yallop 29.07.2014 20:06

Обнаружены случаи, когда %ERRORLEVEL% равен 0, даже если произошла ошибка. Произошло при проверке %ERRORLEVEL% в cmd файле. Попытка start /wait не сработала. Единственное, что сработало - это if errorlevel 1 (...)

AlikElzin-kilaka 13.04.2015 15:57

Дружественный совет:% ErrorLevel% - это переменная оболочки, а не переменная среды, и она также возвращает string, а не int, что означает, что вы не можете эффективно использовать EQ / NEQ.

kayleeFrye_onDeck 24.09.2016 03:27

Интересно, можно ли это поместить в командную строку, как в bash?

SDsolar 26.05.2018 05:21

Используйте встроенную переменную ERRORLEVEL:

echo %ERRORLEVEL%

Но будьте осторожны, если приложение определило переменную среды с именем ERRORLEVEL!

Это не фактическая переменная среды (что, очевидно, почему она перестает работать, если существует является, переменная с таким именем).

Joey 26.06.2010 12:13

@SteelBrain: в PowerShell он называется $LastExitCode.

Alex A. 09.03.2015 18:21

Он может работать некорректно при использовании программы, которая не подключена к консоли, потому что это приложение все еще может работать, пока вы думаете, что у вас есть код выхода. Решение сделать это на 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 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;
}

В некоторых конфигурациях вы должны добавить #include <atlstr.h>, чтобы тип CString был преобразован.

Jake OPJ 07.08.2018 23:41

Тестирование ErrorLevel работает для приложений приставка, но, как намекает по dmihailescu, это не сработает, если вы пытаетесь запустить приложение оконный (например, на основе Win32) из ​​командной строки. Оконное приложение будет работать в фоновом режиме, и управление немедленно вернется в командную строку (скорее всего, с нулевым значением ErrorLevel, что указывает на успешное выполнение процесса созданный). Когда оконное приложение в конце концов завершает работу, его статус выхода теряется.

Однако вместо использования консольного средства запуска C++, упомянутого в другом месте, более простой альтернативой является запуск оконного приложения с помощью команды START /WAIT в командной строке. Это запустит оконное приложение, дождется его выхода, а затем вернет управление в командную строку со статусом выхода процесса, установленным в ErrorLevel.

start /wait something.exe
echo %errorlevel%

Хорошо поймал. Я не знал об этой команде. Я только что видел, как работает> запуск / ожидание notepad.exe

dmihailescu 23.01.2013 22:48

Другая причина, по которой он может не работать (всегда нулевой), - это когда он находится внутри if или for. Рассмотрите возможность использования !errorlevel! вместо описано в этом ответе.

Roman Starkov 09.04.2015 01:36

Если вы хотите точно сопоставить код ошибки (например, равен 0), используйте это:

@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 соответствует errorlevel> = 0. См. if /?.

Это чувствительно к регистру?

Nishant 13.08.2018 18:16

Нет. Vars, команды (включая «if») и «equ» работают в любом случае.

Curtis Yallop 16.08.2018 16:51

В какой-то момент мне нужно было точно передать события журнала из 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:

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

Стоит отметить, что файлы .BAT и .CMD работают по-разному.

Читая https://ss64.com/nt/errorlevel.html, он отмечает следующее:

There is a key difference between the way .CMD and .BAT batch files set errorlevels:

An old .BAT batch script running the 'new' internal commands: APPEND, ASSOC, PATH, PROMPT, FTYPE and SET will only set ERRORLEVEL if an error occurs. So if you have two commands in the batch script and the first fails, the ERRORLEVEL will remain set even after the second command succeeds.

This can make debugging a problem BAT script more difficult, a CMD batch script is more consistent and will set ERRORLEVEL after every command that you run [source].

Это доставляло мне нескончаемые страдания, поскольку я выполнял последовательные команды, но УРОВЕНЬ ОШИБКИ останется неизменным даже в случае сбоя.

Другие вопросы по теме