Comment puis-je obtenir le code de sortie de L'application à partir d'une ligne de commande Windows?

j'exécute un programme et je veux voir quel est son code de retour (puisqu'il renvoie des codes différents basés sur des erreurs différentes).

je sais en Bash, je peux le faire en cours d'exécution

echo $?

Que dois-je faire lorsque j'utilise cmd.exe sur Windows?

654
demandé sur Skrud 2008-12-02 21:04:17

7 réponses

une variable d'environnement pseudo nommée errorlevel stocke le code de sortie:

echo Exit Code is %errorlevel%

aussi, la commande if a une syntaxe spéciale:

if errorlevel

voir if /? pour plus de détails.

exemple

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

Avertissement: Si vous définissez un nom de variable d'environnement errorlevel , %errorlevel% permet de retourner la valeur et non le code de sortie. Utilisation (set errorlevel= ) pour effacer la variable d'environnement, permettant l'accès à la vraie valeur de errorlevel via le %errorlevel% variable d'environnement.

795
répondu Samuel Renkert 2016-08-09 16:11:59

Test ErrorLevel travaille pour console applications, mais aussi de faire allusion à une par dmihailescu , cela ne fonctionnera pas si vous essayez d'exécuter un fenêtré de l'application (par exemple, Win32) à partir d'une invite de commande. Une application fenêtrée s'exécute en arrière-plan, et le contrôle retourne immédiatement à l'invite de commande (très probablement avec un ErrorLevel de zéro pour indiquer que le processus a été créé avec succès). Quand une application fenêtrée sort finalement, son statut de sortie est perdu.

au lieu d'utiliser le lanceur C++ basé sur la console mentionné ailleurs, cependant, une alternative plus simple est de démarrer une application fenêtrée en utilisant la commande START /WAIT de l'invite de commande. Cela va lancer la fenêtre de l'application, attendre pour sortir, puis revenir à l'invite de commandes avec le code de sortie du processus défini dans ErrorLevel .

start /wait something.exe
echo %errorlevel%
203
répondu Gary 2018-06-19 18:06:54

utilisez la Variable ERRORLEVEL intégrée:

echo %ERRORLEVEL%

mais attention si une application a défini une variable d'environnement appelée ERRORLEVEL !

87
répondu Adam Rosenfield 2011-08-16 12:44:10

cela pourrait ne pas fonctionner correctement en utilisant un programme qui n'est pas attaché à la console, parce que cette application pourrait toujours être en cours d'exécution alors que vous pensez avoir le code de sortie. Une solution pour le faire en C++ ressemble à ceci:

#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;
}
12
répondu dmihailescu 2011-08-16 12:44:41

si vous voulez faire correspondre exactement le code d'erreur (eg égale 0), utilisez ceci:

@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 correspond à errorlevel >= 0. Voir if /? .

10
répondu Curtis Yallop 2018-06-20 02:02:45

à un moment, j'ai eu besoin de pousser avec précision les événements de journal de Cygwin au Journal D'événements de Windows. Je voulais que les messages dans WEVL soient personnalisés, aient le code de sortie correct, les détails, les priorités, le message, etc. Alors j'ai créé un petit script Bash pour m'occuper de ça. Le voici sur GitHub, logit.sh .

quelques extraits:

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"

Voici la partie du contenu du fichier temporaire:

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"

ici est une fonction pour créer des événements dans WEVL:

__create_event () {
    local cmd="eventcreate /ID $LGT_ID /L Application /SO $LGT_SOURCE /T $LGT_PRIORITY /D "
    if [[ "" == *';'* ]]; then
        local IFS=';'
        for i in ""; do
            $cmd "$i" &>/dev/null
        done
    else
        $cmd "$LGT_DESC" &>/dev/null
    fi
}

exécution du script de lot et appel à _ _ create _ event:

cmd /c "$(cygpath -wa "$LGT_TEMP_FILE")"
__create_event
0
répondu jonretting 2017-04-21 15:43:56

il est intéressant de noter que .Chauve-souris et .Les fichiers CMD fonctionnent différemment.

Lire https://ss64.com/nt/errorlevel.html il note ce qui suit:

il y a une différence clé entre le chemin .CMD and .Les fichiers batch mis errorlevels:

Un vieux .Le script BAT-bat qui exécute les' nouvelles ' commandes internes: ajoute, ASSOC, PATH, PROMPT, FTYPE et SET ne définira ERRORLEVEL que si un erreur se produit. Ainsi, si vous avez deux commandes dans le script batch et que la première échoue, le niveau D'erreur restera défini même après que la seconde commande ait réussi.

cela peut rendre le débogage d'un script BAT plus difficile, un script cmd batch est plus cohérent et définira ERRORLEVEL après chaque commande que vous lancerez [source].

cela ne me causait aucune fin de chagrin car j'exécutais des commandes successives, mais le niveau D'erreur serait restent inchangés même en cas de panne.

0
répondu RockDoctor 2018-09-18 06:13:09