我正在运行一个程序,想看看它的返回代码是什么(因为它根据不同的错误返回不同的代码)。
我知道在Bash我可以通过跑步来做到这一点
回声$?
在Windows上使用cmd.exe时该怎么办?
名为errorlevel的伪环境变量存储退出代码:
errorlevel
echo Exit Code is %errorlevel%
此外,if命令有一个特殊的语法:
if
if errorlevel
详情见if /?。
if /?
@echo offmy_nifty_exe.exeif errorlevel 1 (echo Failure Reason Given is %errorlevel%exit /b %errorlevel%)
警告:如果设置环境变量名称errorlevel,%errorlevel%将返回该值而不是退出代码。使用(set errorlevel=)清除环境变量,允许通过%errorlevel%环境变量访问errorlevel的真值。
%errorlevel%
set errorlevel=
使用内置的ERRORLEVEL变量:
echo %ERRORLEVEL%
注意应用程序是否定义了名为ERRORLEVEL的环境变量!
使用未附加到控制台的程序时,它可能无法正常工作,因为该应用程序可能在您认为拥有退出代码时仍在运行。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 lineNULL, // Process handle not inheritableNULL, // Thread handle not inheritableFALSE, // Set handle inheritance to FALSE0, // No creation flagsNULL, // Use parent's environment blockNULL, // Use parent's starting directory&si, // Pointer to STARTUPINFO structure&pi ) // Pointer to PROCESS_INFORMATION structure){printf( "CreateProcess failed (%d)\n", GetLastError() );return GetLastError();}elseprintf( "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() );}elseprintf("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;}
测试ErrorLevel适用于控制台的应用程序,但正如作者:dmihailescu所暗示的,如果您尝试从命令提示符运行窗口的应用程序(例如基于Win32的应用程序),这将不起作用。窗口应用程序将在后台运行,控制将立即返回到命令提示符(很可能是ErrorLevel表示进程创建成功)。当窗口应用程序最终退出时,其退出状态丢失。
ErrorLevel
不过,与其使用其他地方提到的基于控制台的C++启动器,更简单的替代方法是使用命令提示符的START /WAIT命令启动窗口应用程序。这将启动窗口应用程序,等待它退出,然后将控制权返回到命令提示符,并在ErrorLevel中设置进程的退出状态。
START /WAIT
start /wait something.exeecho %errorlevel%
如果您想完全匹配错误代码(例如等于0),请使用:
@echo offmy_nify_exe.exeif %ERRORLEVEL% EQU 0 (echo Success) else (echo Failure Reason Given is %errorlevel%exit /b %errorlevel%)
说明,if errorlevel 0匹配errorlevel>=0。if /?.
if errorlevel 0
或者,如果你不处理成功:
if %ERRORLEVEL% NEQ 0 (echo Failed with exit-code: %errorlevel%exit /b %errorlevel%)
有一次,我需要准确地将日志事件从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 offset LGT_EXITCODE="$LGT_ID"exit /b %LGT_ID%EOFunix2dos "$LGT_TEMP_FILE"
这是一个在WEVL中创建事件的函数:
__create_event () {local cmd="eventcreate /ID $LGT_ID /L Application /SO $LGT_SOURCE /T $LGT_PRIORITY /D "if [[ "$1" == *';'* ]]; thenlocal IFS=';'for i in "$1"; do$cmd "$i" &>/dev/nulldoneelse$cmd "$LGT_DESC" &>/dev/nullfi}
执行批处理脚本并调用__create_event:
cmd /c "$(cygpath -wa "$LGT_TEMP_FILE")"__create_event
值得注意的是。BAT和。CMD文件的操作方式不同。
阅读https://ss64.com/nt/errorlevel.html它注意到以下内容:
. CMD和. BAT批处理文件设置错误级别的方式有一个关键区别: 运行“new”内部命令的旧的. BAT批处理脚本:APPEND、ASSOC、PATH、PROMPT、FTYPE和SET只会在发生错误时设置ERRORLEVEL。因此,如果批处理脚本中有两个命令并且第一个失败,即使第二个命令成功,ERRORLEVEL也会保持设置。 这会使调试问题BAT脚本更加困难,CMD批处理脚本更加一致,并且会在您运行[source]的每个命令后设置ERRORLEVEL。
. CMD和. BAT批处理文件设置错误级别的方式有一个关键区别:
运行“new”内部命令的旧的. BAT批处理脚本:APPEND、ASSOC、PATH、PROMPT、FTYPE和SET只会在发生错误时设置ERRORLEVEL。因此,如果批处理脚本中有两个命令并且第一个失败,即使第二个命令成功,ERRORLEVEL也会保持设置。
这会使调试问题BAT脚本更加困难,CMD批处理脚本更加一致,并且会在您运行[source]的每个命令后设置ERRORLEVEL。
当我执行连续的命令时,这让我没有结束悲伤,但即使在失败的情况下,ERRORLEVEL也会保持不变。