如何在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中运行命令后获取退出代码的主要内容,如果未能解决你的问题,请参考以下文章

如何在windows的命令行环境下编译C++程序?

如何在Windows CMD里面用命令行操作DB2数据库

如何在Windows CMD里面用命令行操作DB2数据库

wpf程序调用cmd命令行的方法(C#语言调用C++写的程序)?

windows如何用cmd命令解压指定的zip文件到指定目录里?

如何在windows cmd下运行python