如何从Windows命令行获取应用程序退出代码?

如何从Windows命令行获取应用程序退出代码?,windows,command-line,process,cmd,exit-code,Windows,Command Line,Process,Cmd,Exit Code,我正在运行一个程序,想看看它的返回代码是什么(因为它根据不同的错误返回不同的代码) 我知道在Bash中,我可以通过运行 回声$ 在Windows上使用cmd.exe时该怎么办?名为errorlevel的伪环境变量存储退出代码: echo Exit Code is %errorlevel% 另外,if命令具有特殊语法: if errorlevel 有关详细信息,请参见if/? 例子 警告:如果设置环境变量名errorlevel,%errorlevel%将返回该值,而不是退出代码。使用(set

我正在运行一个程序,想看看它的返回代码是什么(因为它根据不同的错误返回不同的代码)

我知道在Bash中,我可以通过运行

回声$


在Windows上使用cmd.exe时该怎么办?

名为
errorlevel
的伪环境变量存储退出代码:

echo Exit Code is %errorlevel%
另外,
if
命令具有特殊语法:

if errorlevel
有关详细信息,请参见
if/?

例子
警告:如果设置环境变量名
errorlevel
%errorlevel%
将返回该值,而不是退出代码。使用(
set errorlevel=
)清除环境变量,允许通过
%errorlevel%
环境变量访问
errorlevel
的真实值。

使用内置errorlevel变量:

echo %ERRORLEVEL%

但是

当使用未连接到控制台的程序时,它可能无法正常工作,因为当您认为您有退出代码时,该应用程序可能仍在运行。 C++中的一个解决方案,如下所示:

#包括“stdafx.h”
#包括“windows.h”
#包括“stdio.h”
#包括“tchar.h”
#包括“stdio.h”
#包括“shellapi.h”
int_tmain(int argc,TCHAR*argv[])
{
CString cmdline(GetCommandLineW());
cmdline.trimlefit(“\”);
CString-self(argv[0]);
自修剪(“\”);
CString args=cmdline.Mid(self.GetLength()+1);
args.trimpleft(\u T(“\”);
printf(“传递的参数:'%ws'\n',args);
STARTUPINFO si;
处理信息;
零内存(&si,sizeof(si));
si.cb=sizeof(si);
零内存(&pi,sizeof(pi));
如果(argc<2)
{
printf(“用法:%s arg1,arg2….\n”,argv[0]);
返回-1;
}
CString strCmd(args);
//启动子进程。
如果(!CreateProcess(NULL,//没有模块名称(使用命令行)
(LPTSTR)(strCmd.GetString()),//命令行
NULL,//进程句柄不可继承
NULL,//线程句柄不可继承
FALSE,//将句柄继承设置为FALSE
0,//没有创建标志
NULL,//使用父级的环境块
NULL,//使用父级的起始目录
&si,//指向STARTUPINFO结构的指针
&pi)//指向进程信息结构的指针
) 
{
printf(“CreateProcess失败(%d)\n”,GetLastError());
返回GetLastError();
}
其他的
printf(“等待\%ws\”退出…\n”,strCmd);
//等待子进程退出。
WaitForSingleObject(pi.hProcess,无限);
int结果=-1;
if(!GetExitCodeProcess(pi.hProcess,(LPDWORD)和result))
{ 
printf(“GetExitCodeProcess()失败(%d)\n”,GetLastError());
}
其他的
printf(““%ws”的退出代码是%d\n”,(LPTSTR)(strCmd.GetString()),result);
//关闭进程和线程句柄。
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
返回结果;
}

测试
ErrorLevel
适用于控制台应用程序,但正如所暗示的,如果您试图从命令提示符运行窗口应用程序(例如基于Win32的应用程序),这将不起作用。窗口应用程序将在后台运行,控制将立即返回到命令提示符(最有可能是
ErrorLevel
为零,表示进程已成功创建)。当窗口应用程序最终退出时,其退出状态将丢失

<> >而不是使用其他地方提到的基于控制台的C++启动程序,更简单的选择是使用命令提示符的代码>启动/等待/代码>命令启动窗口应用程序。这将启动窗口应用程序,等待它退出,然后返回进程命令集的退出状态的命令提示符。n
ErrorLevel

start /wait something.exe
echo %errorlevel%

如果要精确匹配错误代码(例如等于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/?

在某一点上,我需要将日志事件从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"
执行批处理脚本并调用_create_事件:

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

值得注意的是.BAT和.CMD文件的操作方式不同

阅读时注意到以下几点:

.CMD和.BAT批处理文件设置错误级别的方式有一个关键区别:

旧的.BAT批处理脚本运行“新”内部命令:APPEND、ASSOC、PATH、PROMPT、FTYPE和SET,只有在出现错误时才会设置ERRORLEVEL。因此,如果批处理脚本中有两个命令,而第一个命令失败,则即使第二个命令成功,ERRORLEVEL仍将保持设置

这会使调试有问题的BAT脚本变得更加困难,CMD批处理脚本更加一致,并且会在运行[source]的每个命令后设置ERRORLEVEL


当我执行连续的命令时,这让我痛苦不已,但即使出现故障,ERRORLEVEL也会保持不变。

它不是一个实际的环境变量(很明显,这就是为什么如果有一个名为way的变量,它会停止工作的原因)@SteelBrain:它在PowerShell中被称为
$LastExitCode
。如果您直接从Windows命令行运行并且总是看到0返回,请参阅Gary的回答:如果您在PowerShell中,您也可以使用
回显退出代码是$LastExitCode
注意:如果errorlevel>=1,则“errorlevel 1”为真。因此“errorlevel 0”“将匹配所有内容。请参阅“if/?”。您可以改为使用“if%ERRORLEVEL%eq 0(..)”。找到了
%ERRORLEVEL%
为0的情况,即使发生了错误。在检查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"
__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
}
cmd /c "$(cygpath -wa "$LGT_TEMP_FILE")"
__create_event