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

后端 未结 7 756
执笔经年
执笔经年 2020-11-22 02:13

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<

相关标签:
7条回答
  • 2020-11-22 02:42

    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;
    }
    
    0 讨论(0)
  • 2020-11-22 02:44

    At one point I needed to accurately push log events from Cygwin to the Windows Event log. I wanted the messages in WEVL to be custom, have the correct exit code, details, priorities, message, etc. So I created a little Bash script to take care of this. Here it is on GitHub, logit.sh.

    Some excerpts:

    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"
    

    Here is the temporary file contents part:

    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"
    

    Here is a function to to create events in 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
    }
    

    Executing the batch script and calling on __create_event:

    cmd /c "$(cygpath -wa "$LGT_TEMP_FILE")"
    __create_event
    
    0 讨论(0)
  • 2020-11-22 02:45

    It's worth noting that .BAT and .CMD files operate differently.

    Reading https://ss64.com/nt/errorlevel.html it notes the following:

    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].

    This was causing me no end of grief as I was executing successive commands, but the ERRORLEVEL would remain unchanged even in the event of a failure.

    0 讨论(0)
  • 2020-11-22 02:50

    Use the built-in ERRORLEVEL Variable:

    echo %ERRORLEVEL%
    

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

    0 讨论(0)
  • 2020-11-22 02:54

    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 /?.

    0 讨论(0)
  • 2020-11-22 03:03

    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.

    0 讨论(0)
提交回复
热议问题