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


Je cours un programme et veux voir ce que son code de retour est (puisqu'il renvoie des codes différents basés sur différentes erreurs).

Je sais à Bash que je peux le faire en courant

echo $?

Que faire lors de l'utilisation de cmd.exe sous Windows?


634
2017-12-02 18:04


origine


Réponses:


Une variable pseudo-environnement nommée errorlevel stocke le code de sortie:

echo Exit Code is %errorlevel%

Également if commande 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% retournera cette valeur et non le code de sortie. Utiliser (définir errorlevel=) pour effacer la variable d'environnement, permettant l'accès à la vraie valeur de errorlevel via le %errorlevel% variable d'environnement.


777
2017-12-02 18:07



Essai ErrorLevel fonctionne pour console applications, mais comme l'indique par dmihailescu, cela ne fonctionnera pas si vous essayez d'exécuter un fenêtré application (par exemple Win32) à partir d'une invite de commande. Une application fenêtrée s'exécutera en arrière-plan, et le contrôle retournera immédiatement à l'invite de commande (probablement avec un ErrorLevel de zéro pour indiquer que le processus était créé avec succès). Lorsqu'une application fenêtrée se termine, son statut de sortie est perdu.

Au lieu d'utiliser le lanceur C ++ basé sur la console mentionné ailleurs, une alternative plus simple consiste à démarrer une application fenêtrée à l'aide de l'invite de commande. START /WAIT commander. Cela va démarrer l'application fenêtrée, attendez qu'elle se termine, puis renvoyez le contrôle à l'invite de commande avec le statut de sortie de l'ensemble de processus dans ErrorLevel.

start /wait something.exe
echo %errorlevel%

198
2017-07-13 18:57



Utilisez la variable ERRORLEVEL intégrée:

echo %ERRORLEVEL%

Mais méfiez-vous si une application a défini une variable d'environnement nommée ERRORLEVEL!


85
2017-12-02 18:09



Cela peut ne pas fonctionner correctement lorsque vous utilisez un programme qui n'est pas connecté à la console, car cette application peut toujours être en cours d'exécution lorsque vous pensez avoir le code de sortie. Une solution pour le faire en C ++ ressemble à ci-dessous:

#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;
}

11
2018-06-25 17:05



Si vous voulez faire correspondre exactement le code d'erreur (par exemple égal à 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 allumettes errorlevel > = 0. Voir if /?.


9
2017-07-29 16:08



À un moment donné, j'avais besoin de pousser avec précision les événements du journal de Cygwin vers le journal des événements Windows. Je voulais que les messages dans WEVL soient personnalisés, aient le bon code de sortie, les détails, les priorités, le message, etc. J'ai donc créé un petit script Bash pour m'en occuper. Ici c'est 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"

Voici 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 [[ "$1" == *';'* ]]; then
        local IFS=';'
        for i in "$1"; do
            $cmd "$i" &>/dev/null
        done
    else
        $cmd "$LGT_DESC" &>/dev/null
    fi
}

Exécution du script de traitement par lots et appel à __create_event:

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

0
2018-02-28 19:33