How do I get the application exit code from a Windows command line?

924,305

Solution 1

A pseudo environment variable named errorlevel stores the exit code:

echo Exit Code is %errorlevel%

Also, the if command has a special syntax:

if errorlevel

See if /? for details.

Example

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

Warning: If you set an environment variable name errorlevel, %errorlevel% will return that value and not the exit code. Use (set errorlevel=) to clear the environment variable, allowing access to the true value of errorlevel via the %errorlevel% environment variable.

Solution 2

Testing ErrorLevel works for console applications, but as hinted at by dmihailescu, this won't work if you're trying to run a windowed application (e.g. Win32-based) from a command prompt. A windowed application will run in the background, and control will return immediately to the command prompt (most likely with an ErrorLevel of zero to indicate that the process was created successfully). When a windowed application eventually exits, its exit status is lost.

Instead of using the console-based C++ launcher mentioned elsewhere, though, a simpler alternative is to start a windowed application using the command prompt's START /WAIT command. This will start the windowed application, wait for it to exit, and then return control to the command prompt with the exit status of the process set in ErrorLevel.

start /wait something.exe
echo %errorlevel%

Solution 3

Use the built-in ERRORLEVEL Variable:

echo %ERRORLEVEL%

But beware if an application has defined an environment variable named ERRORLEVEL!

Solution 4

If you want to match the error code exactly (eg equals 0), use this:

@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 matches errorlevel >= 0. See if /?.

Solution 5

It might not work correctly when using a program that is not attached to the console, because that app might still be running while you think you have the exit code. A solution to do it in C++ looks like below:

#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;
}
Share:
924,305
Skrud
Author by

Skrud

Updated on June 18, 2020

Comments

  • Skrud
    Skrud almost 4 years

    I am running a program and want to see what its return code is (since it returns different codes based on different errors).

    I know in Bash I can do this by running

    echo $?

    What do I do when using cmd.exe on Windows?

    • Deanna
      Deanna almost 11 years
    • SDsolar
      SDsolar almost 6 years
      Googled for "Win8 How to get CMD prompt to show exit status" like we can do in Linux. This was top selection, and is accurate.
    • marbel82
      marbel82 about 5 years
      You can quickly see what app returns: app.exe & echo %errorlevel%
  • Rich
    Rich almost 14 years
    It's not an actual environment variable (which is, obviously, why it ceases to work if there is a variable named that way).
  • user3162901
    user3162901 over 11 years
    If you're running directly from a Windows command line and always seeing 0 returned, see Gary's answer: stackoverflow.com/a/11476681/31629
  • dmihailescu
    dmihailescu over 11 years
    nice catch. I did not know about that command. I've just seen it working for > start /wait notepad.exe
  • Brandon Pugh
    Brandon Pugh over 10 years
    Also if you're in powershell you can use echo Exit Code is $LastExitCode
  • Curtis Yallop
    Curtis Yallop almost 10 years
    Note: "errorlevel 1" is true if errorlevel >= 1. So "errorlevel 0" will match everything. See "if /?". Instead, you can use "if %ERRORLEVEL% EQU 0 (..)".
  • Alex A.
    Alex A. about 9 years
    @SteelBrain: It's called $LastExitCode in PowerShell.
  • Roman Starkov
    Roman Starkov about 9 years
    Another reason why it might not work (always zero) is when it's inside an if or for. Consider using !errorlevel! instead, as described in this answer.
  • AlikElzin-kilaka
    AlikElzin-kilaka about 9 years
    Found cases where %ERRORLEVEL% is 0 even though an error occurred. Happened when checking %ERRORLEVEL% in a cmd file. Trying start /wait didn't work. The only thing that worked is if errorlevel 1 (...)
  • kayleeFrye_onDeck
    kayleeFrye_onDeck over 7 years
    Friendly advice: %ErrorLevel% is a shell variable, not an environment variable, and it also returns a string not an int, meaning you can't use EQ/NEQ effectively.
  • SDsolar
    SDsolar almost 6 years
    I wonder if this can be put into the prompt like I have in bash?
  • Jake OPJ
    Jake OPJ almost 6 years
    In some configurations you should add #include <atlstr.h> so that the CString type is recongnized.
  • Nishant
    Nishant almost 6 years
    Is it case-sensitive?
  • Curtis Yallop
    Curtis Yallop almost 6 years
    No. vars, commands (including "if") and "equ" work no matter what the case is.