如何在windows c++中的cmd中运行命令后获取退出代码
Posted
技术标签:
【中文标题】如何在windows c++中的cmd中运行命令后获取退出代码【英文标题】:How to get exit code after running command in cmd in windows c++ 【发布时间】:2016-10-25 08:40:20 【问题描述】:我正在使用 Createprocess
在 cmd 中运行命令,并且我正在尝试使用 GetExitCodeProcess()
获取该特定命令执行的退出代码。
如果命令窗口打开并且我尝试GetExitCodeProcess()
,那么我总是得到259(STILL_ACTIVE)
返回码。如果我尝试使用TerminateProcess()
终止进程,那么我会得到退出代码,即我发送的值以终止进程。
下面是我的代码:
STARTUPINFO si;
ZeroMemory(&si,sizeof(STARTUPINFO));
si.cb = sizeof(si);
PROCESS_INFORMATION pi;
ZeroMemory( &pi, sizeof(pi) );
BOOL b = CreateProcess("C:\\Windows\\System32\\cmd.exe","/k dir",NULL,NULL,TRUE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi);
TerminateProcess(pi.hProcess,1);
DWORD dwExitCode = 0;
::GetExitCodeProcess(pi.hProcess, &dwExitCode);
当我将/k dir
作为命令传递时,我应该得到非零错误代码,如果我传递/k dirancbdf
(任何不存在的命令),我应该得到零错误代码。
使用Terminateprocess
的另一个原因是我想根据该命令的成功/失败隐藏/显示命令提示符。
【问题讨论】:
您知道TerminateProcess
会尝试实际终止进程,即使它还没有完成?而且,它是异步的!请阅读链接参考以获取更多信息。
我不清楚您要在这里实现什么,但您可能应该使用/c
而不是/k
并省略CREATE_NEW_CONSOLE
标志。如果您还没有控制台,您可能还需要先创建一个控制台。
@Someprogrammerdude 是的,我知道。如果我不使用 TerminateProcess 并尝试获取退出代码,我将始终得到 259(STILL_ACTIVE)。有什么替代方法?
这是获取目录列表的一种非常糟糕的方式。
如果你要运行的实际命令是一个外部命令——一个应用程序——那么你可以直接运行它而不是通过cmd.exe
。
【参考方案1】:
您将选项/k
传递给cmd.exe
,这意味着您希望shell 在执行命令dir
后保持活动状态。这样做,运行命令的进程将永远不会结束,并且在查询GetExitCodeProcess()
时总是会得到STILL_ACTIVE
(表示该进程仍在运行)。
如果你想要dir
命令的退出代码,你应该使用选项/c
代替(这样cmd.exe
在执行命令dir
之后结束)。此外,在查询GetExitCodeProcess()
之前,您应该使用WaitForSingleObject()
等待进程结束,因为CreateProcess()
将在进程创建后立即返回(它不会等待进程结束)。在这种情况下无需调用TerminateProcess()
:dir
命令返回状态将从GetExitCodeProcess()
获得。
BOOL b = CreateProcess("C:\\Windows\\System32\\cmd.exe","/c dir",NULL,NULL,TRUE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi);
WaitForSingleObject( pi.hProcess, INFINITE ); // wait for process to end
DWORD dwExitCode = 0;
::GetExitCodeProcess(pi.hProcess, &dwExitCode);
如果您希望控制台在发生错误时保持打开状态,您可以使用以下语法:
CreateProcessA("C:\\Windows\\System32\\cmd.exe","/c dir || pause && exit 1",NULL,NULL,TRUE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi);
其中||
确保pause
命令仅在dir
命令失败时执行,&&
确保在出现此类错误时输出退出代码 1。
【讨论】:
我使用了 /c 而不是 /k,但我得到了“/c dir”的 0 个退出代码和“/c dirabc”的 1 个退出代码(任何错误的命令)。我认为我应该根据 GetExitCodeProcess 的文档获得非零值以获得成功。 不,约定是退出代码为零表示成功,非零退出代码表示失败 - 尽管这只是一个约定,而不是规则,并且受程序员的突发奇想。 (以robocopy
为例,任何小于4的退出码都表示成功。)
@shrike 谢谢。我也使用了 WaitForSingleObject 但我也得到了相同的退出代码。
@DeepShah :如果您希望控制台在出错时保持打开状态,请参阅我的上次编辑
@DeepShah :是的,这是因为您获得了退出代码 pause
;我在我的答案中编辑了最后一个 sn-p,以便在dir
命令执行期间出现错误时获得退出代码 1以上是关于如何在windows c++中的cmd中运行命令后获取退出代码的主要内容,如果未能解决你的问题,请参考以下文章
wpf程序调用cmd命令行的方法(C#语言调用C++写的程序)?