如何从Windows命令行获取应用程序退出代码?
我正在运行一个程序,想看看它的返回代码是什么(因为它根据不同的错误返回不同的代码) 我知道在Bash中,我可以通过运行 回声$如何从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
在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++启动程序,更简单的选择是使用命令提示符的代码>启动/等待/代码>命令启动窗口应用程序。这将启动窗口应用程序,等待它退出,然后返回进程命令集的退出状态的命令提示符。nErrorLevel
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