programing

Windows 명령줄에서 응용 프로그램 종료 코드를 가져오려면 어떻게 해야 합니까?

padding 2023. 4. 23. 10:07
반응형

Windows 명령줄에서 응용 프로그램 종료 코드를 가져오려면 어떻게 해야 합니까?

프로그램을 실행 중인데 반환 코드가 무엇인지 알고 싶습니다(다른 오류에 따라 다른 코드를 반환하므로).

배쉬에서는 달리기를 통해 이 일을 할 수 있다는 걸 알아요.

echo 달러?

Windows에서 cmd.exe를 사용할 경우 어떻게 해야 합니까?

"종료 코드"는 다음과 같은 이름의 셸 변수에 저장됩니다.errorlevel.

errorlevel는 콘솔 어플리케이션의 마지막에 설정됩니다.Windows 애플리케이션의 동작은 조금 다릅니다.아래의 @gary의 답변을 참조해 주세요.

를 사용합니다.if명령어 키워드errorlevel비교용:

if errorlevel <n> (<statements>)

오류 수준이 n 이상일 때 문이 실행됩니다.실행if /?자세한 것은, 을 참조해 주세요.

셸 변수 이름errorlevel값은 문자열로 포함되어 있으며 %'s로 래핑하여 참조할 수 있습니다.

스크립트 예시:

my_nifty_exe.exe

rem Give resolution instructions for known exit codes.
rem Ignore exit code 1.
rem Otherwise give a generic error message.

if %errorlevel%==7 (
   echo "Replace magnetic tape."
) else if %errorlevel%==3 (
   echo "Extinguish the printer."
) else if errorlevel 2 (
   echo Unknown Error: %errorlevel% refer to Run Book documentation.
) else (
   echo "Success!"
)

경고:error level이라는 이름의 환경 변수가 있는 경우 error level이라는 이름의 셸 변수를 덮어씁니다. if errorlevel테스트는 영향을 받지 않습니다.

테스트ErrorLevel콘솔 어플리케이션에서는 동작하지만 dmihailescu에서 암시한 바와 같이 명령 프롬프트에서 윈도 어플리케이션(Win32 기반 등)을 실행하려고 하면 동작하지 않습니다.윈도 어플리케이션은 백그라운드에서 실행되며 컨트롤은 즉시 명령 프롬프트로 돌아갑니다(대부분은ErrorLevel프로세스가 정상적으로 작성되었음을 나타냅니다).윈도우가 설정된 응용 프로그램이 최종적으로 종료되면 해당 종료 상태는 손실됩니다.

단, 다른 곳에서 언급한 콘솔 기반 C++ 런처를 사용하는 대신 명령 프롬프트를 사용하여 윈도우 응용 프로그램을 실행하는 것이 더 간단합니다.START /WAIT명령어를 입력합니다.그러면 윈도우 응용 프로그램이 시작되고 종료될 때까지 기다린 후 에서 설정된 프로세스의 종료 상태를 나타내는 명령 프롬프트로 제어가 돌아갑니다.ErrorLevel.

start /wait something.exe
echo %errorlevel%

내장된 ERROR LEVEL 변수를 사용합니다.

echo %ERRORLEVEL%

그러나 애플리케이션에서 ERROR LEVEL이라는 환경 변수를 정의한 경우에는 주의해야 합니다.

에러 코드(예: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 0일치하다errorlevel>= 0 입니다.
if /?.

또는 성공을 처리하지 못하는 경우:

if  %ERRORLEVEL% NEQ 0 (
    echo Failed with exit-code: %errorlevel%
    exit /b %errorlevel%
)

주의할 필요가 있다.BAT 및.CMD 파일은 다르게 동작합니다.

https://ss64.com/nt/errorlevel.html 를 참조하면, 다음의 점에 주의해 주세요.

그 방법에는 중요한 차이가 있다.CMD 및BAT 배치 파일은 오류 수준을 설정합니다.

늙은이.APPEND, ASOC, PATH, PROMT, FTYPE 및 SET의 내부 명령을 실행하는 BAT 배치 스크립트는 오류가 발생한 경우에만 ERROR LEVEL을 설정합니다.따라서 배치 스크립트에 2개의 명령어가 있는데 첫 번째 명령어가 실패하면 두 번째 명령어가 성공한 후에도 ERROR LEVEL은 설정된 상태로 유지됩니다.

이로 인해 문제의 BAT 스크립트의 디버깅이 어려워질 수 있습니다.CMD 배치 스크립트는 일관성이 향상되어 [source]를 실행할 때마다 ERROR LEVEL이 설정됩니다.

이 때문에 연속 명령어를 실행하면서 슬픔이 끊이지 않았지만, 에러 레벨은 실패해도 변하지 않았습니다.

종료 코드가 있다고 생각되는 동안 해당 앱이 계속 실행 중일 수 있으므로 콘솔에 연결되지 않은 프로그램을 사용할 때 올바르게 작동하지 않을 수 있습니다.이를 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;
}

한때 로그 이벤트를 Cygwin에서 Windows 이벤트 로그에 정확하게 푸시해야 했습니다.WEVL의 메시지는 커스텀으로 하고, 종료 코드, 상세, 우선순위, 메시지 등을 올바르게 설정해 주었으면 합니다.그래서 이걸 처리하기 위해 작은 Bash 스크립트를 만들었습니다.여기 GitHub에 있어요, 로짓.!

일부 발췌:

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

언급URL : https://stackoverflow.com/questions/334879/how-do-i-get-the-application-exit-code-from-a-windows-command-line

반응형