Windowsコマンドラインからアプリケーションの終了コードを取得するにはどうすればよいですか?


797

私はプログラムを実行していて、その戻りコードが何であるかを確認したいと思います(さまざまなエラーに基づいてさまざまなコードを返すため)。

私はBashで実行してこれを行うことができることを知っています

エコー$?

Windowsでcmd.exeを使用する場合はどうすればよいですか?



1
Linuxでできるように、「Win8 CMDプロンプトで終了ステータスを表示する方法」を検索しました。これは最高の選択であり、正確です。
SDsolar

1
:あなたはすぐにどのようなアプリリターン見ることができますapp.exe & echo %errorlevel%
marbel82

回答:


976

という名前の疑似環境変数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%ます。


38
Windowsコマンドラインから直接実行していて、常に0が返される場合は、Garyの回答を参照してください。stackoverflow.com
Ken

9
また、Powershellを使用している場合は、次を使用できますecho Exit Code is $LastExitCode
Brandon Pugh

11
注:「errorlevel 1」は、errorlevel> = 1の場合にtrueになるため、「errorlevel 0」はすべてに一致します。「if /?」を参照してください。代わりに、「if%ERRORLEVEL%EQU 0(..)」を使用できます。
Curtis Yallop、2014

1
%ERRORLEVEL%エラーが発生しても0であるケースが見つかりました。%ERRORLEVEL%cmdファイルをチェックインするときに発生しました。試してstart /waitもうまくいきませんでした。機能した唯一のものはif errorlevel 1 (...)
AlikElzin-kilaka

1
フレンドリーなアドバイス:%ErrorLevel%はシェル変数であり、環境変数ではありstringません。また、notを返します。intつまり、EQ/をNEQ効果的に使用できません。
kayleeFrye_onDeck 2016

277

テストErrorLevelコンソールアプリケーションで機能しますが、dmihailescuが示唆しいるように、コマンドプロンプトからウィンドウアプリケーション(Win32ベースなど)を実行しようとすると、機能しません。ウィンドウ化されたアプリケーションはバックグラウンドで実行され、コントロールはすぐにコマンドプロンプトに戻ります(ErrorLevelプロセスが正常に作成されたことを示すゼロの場合がほとんどです)。ウィンドウ化されたアプリケーションが最終的に終了すると、その終了ステータスは失われます。

ただし、他の場所で説明されているコンソールベースのC ++ランチャーを使用する代わりに、コマンドプロンプトのSTART /WAITコマンドを使用してウィンドウアプリケーションを起動する方法がより簡単です。これにより、ウィンドウ化されたアプリケーションが起動し、終了するのを待ってから、コマンドプロンプトに制御を戻し、プロセスの終了ステータスをに設定しErrorLevelます。

start /wait something.exe
echo %errorlevel%

20
「START / wait」のアイデアに感謝します。それは私のために働いた:)
Timotei

3
ナイスキャッチ。そのコマンドについては知りませんでした。私はそれが動作するのを見た> start / wait notepad.exe
dmihailescu 2013年

1
機能しない可能性があるもう1つの理由(常にゼロ)は、ifまたはの内部にある場合forです。この回答で説明され!errorlevel!ているように、代わりに使用を検討してください。
Roman Starkov、2015

100

組み込みのERRORLEVEL変数を使用します。

echo %ERRORLEVEL%

ただし、アプリケーションがERRORLEVELという名前の環境変数を定義している場合は注意してください


6
これは実際の環境変数ではありません(そのため、そのように名前が付けられた変数がある動作しなくなるのは明らかです)。
ジョーイ

17
@SteelBrain:$LastExitCodePowerShellで呼び出されます。
Alex A.

23

エラーコードを正確に一致させたい場合(たとえば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 0errorlevel> = 0に一致しif /?ます。を参照してください。


大文字と小文字が区別されますか?
Nishant 2018

1
いいえ。変数、コマンド( "if"を含む)、 "equ"は、どのような場合でも機能します。
Curtis Yallop 2018

14

コンソールに接続されていないプログラムを使用すると、終了コードがあると思われる間、そのアプリがまだ実行されている可能性があるため、正しく機能しない可能性があります。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型が認識されるようにする必要があります。
ジェイクOPJ 2018

8

.BATファイルと.CMDファイルの動作は異なることに注意してください。

https://ss64.com/nt/errorlevel.htmlを読むと、次のことがわかります。

.CMDと.BATバッチファイルがエラーレベルを設定する方法には、主な違いがあります。

「新しい」内部コマンドを実行する古い.BATバッチスクリプト:APPEND、ASSOC、PATH、PROMPT、FTYPE、およびSETは、エラーが発生した場合にのみERRORLEVELを設定します。したがって、バッチスクリプトに2つのコマンドがあり、最初のコマンドが失敗した場合、2番目のコマンドが成功した後でも、ERRORLEVELは設定されたままになります。

これにより、問題のBATスクリプトのデバッグがより困難になり、CMDバッチスクリプトの一貫性が高まり、[ソース]を実行するすべてのコマンドの後にERRORLEVELが設定されます。

これにより、一連のコマンドを実行しているときに悲しみの終わりはありませんでしたが、エラーが発生した場合でもERRORLEVELは変更されません。


0

ある時点で、ログイベントを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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.