确定 QProcess 是不是正在等待用户输入

Posted

技术标签:

【中文标题】确定 QProcess 是不是正在等待用户输入【英文标题】:Determine if QProcess is waiting for user input确定 QProcess 是否正在等待用户输入 【发布时间】:2018-10-31 01:08:21 【问题描述】:

我正在开发一个应用程序(在 Qt 5.11 中开发,工具链 MSVS2017 64 位),在某些时候,它必须执行一个 .bat 脚本。此 .bat 脚本将使用适当的 cmd 行参数调用某些程序。脚本和程序将驻留在同一目录中。该程序可能会或可能不会要求用户在最后按 Enter。如果程序要求用户按 Enter,除非在标准输入中写入换行符,否则程序永远不会结束。

我想检查程序是否在尝试写入其标准输入之前等待用户输入,如果可能的话,只使用 Qt 库。

.bat 脚本会简单地调用程序:

Program arg1 arg2 arg3...

从应用程序,脚本将使用 QProcess 执行: 进程开始后添加睡眠

QProcess process;
process.setWorkingDirectory("C:/path/to/script");
process.start("cmd /C C:/path/to/script/script.bat");

QThread::sleep(someTimeout);  // give enough time for process to finish

if (/*somehow*/ process.isWaitingForInput())
    proces.write("\n");
process.waitForFinished();
process.readAllStandardOutput();
process.readAllStandardInput();
proces.exitCode();

我找到了similar question,答案指向MSDN WaitForInputIdle。

将来可以移植到 Linux 或 Mac,如果可以,我想避免

#if defined(WIN32)
    WaitForInputIdle(...)
#else
    PosixAlternative(...)
#endif

另外,也许是主题,但我很好奇,是否可以从 QProcess 执行 .bat 脚本,以使 cmd/终端窗口与 std 输出一起显示?

【问题讨论】:

你的问题和***.com/questions/6911498/…很不一样 【参考方案1】:

我不确定检查子进程是否正在等待用户输入是否有意义——首先,因为我不相信有任何现实的方法可以做到这一点,其次,因为没有必要——如果/当它尝试从标准输入读取时,您write() 到 QProcess 的任何数据都将被子进程缓冲和读取。 (根据定义,子进程将相对于您自己的进程异步执行,因此任何依赖于知道子进程“当前正在做什么”的方法本质上都是可疑的,因为子进程当前正在执行的操作可以并且将会在没有通知的情况下更改在您的流程有时间做出反应之前,从一瞬间到下一瞬间)

可以做的(如果您愿意的话)是读取子进程的 stdout 和/或 stderr 流,并对子进程的输出做出反应。 (例如,如果您知道子进程将在某个时候将enter your decision now -> 打印到标准输出,您可以从 QProcess 的 StandardOutput 通道读取标准输出数据,并在看到该字符串时做出适当的反应)

【讨论】:

当我阅读您的回答时,我注意到我在启动过程后没有添加睡眠。我知道这个程序会持续一段时间。启动后睡眠,程序将有足够的时间完成其工作。另外我忘了提到该程序不应该需要任何输入数据。但它可能需要用户在其中按 Enter 键(就像我们在 .bat 脚本中添加 pause 一样)。 事实上我可以在进程读取它之前写一些东西到进程的标准输入已经解决了我的问题。

以上是关于确定 QProcess 是不是正在等待用户输入的主要内容,如果未能解决你的问题,请参考以下文章

IPC::Open3 并确定孩子是不是正在等待输入

使用 QProcess 读取标准输出

如何使用 QProcess 等待子进程?

等待 QProcess 完成或持续时间超过 [重复]

确定子进程是不是从标准输入读取

qprocess执行 scp不弹密码框怎么回事