使用QProcess,是不是需要在waitForFinished之后调用waitForReadyRead?

Posted

技术标签:

【中文标题】使用QProcess,是不是需要在waitForFinished之后调用waitForReadyRead?【英文标题】:With QProcess, Is it necessary to call waitForReadyRead after waitForFinished?使用QProcess,是否需要在waitForFinished之后调用waitForReadyRead? 【发布时间】:2019-01-24 15:18:17 【问题描述】:

我使用下面的代码从命令行实用程序的标准输出中捕获“帮助”。这段代码一直没有问题,直到今天早上有人遇到问题(出现的消息框显示该命令看起来很奇怪)。

我似乎无法重现该问题,因此我将其归结为系统异常,因为该实用程序位于网络共享驱动器上,并且我们的系统承载着安全进程,这会导致很多滞后。

添加waitForReadyRead 检查是否有益,还是多余?

任何想法或建议将不胜感激。

QProcess cmd_process;
cmd_process.setWorkingDirectory("x:/working/directory");
cmd_process.start(R"(t:\bin\win\cmdlineutility.exe)", QStringList() << "/help");
if(cmd_process.waitForFinished())

    // TODO - should waitForReadyRead() go here?
    QByteArray ba = cmd_process.readAll();
    if(ba.contains("something good"))
    
        // do stuff here
    
    else
    
        QMessageBox::information(0, "Something wrong", "cmdlineutility looks odd");
    

else

    QMessageBox::information(0, "something wrong", "total fail");

【问题讨论】:

那是真正的代码吗?字符串文字中的单个反斜杠启动转义序列。您确定有问题的命令在命令行中仍能按预期工作吗? 不是真正的代码。无法复制真实代码。我会解决的。 是的,该命令确实有效,这部分代码在过去几年中一直是这样工作的。 【参考方案1】:

至少在qprocess_win.cpp两者中 QProcessPrivate::waitForReadyRead(int msecs)QProcessPrivate::waitForFinished(int msecs) 执行相同的操作:

打电话

stdoutChannel.reader &amp;&amp; stdoutChannel.reader-&gt;waitForReadyRead(0)

完成后,调用

drainOutputPipes()

所以当waitForFinished() 返回时,所有可用数据都将被读入输出缓冲区。

【讨论】:

我注意到waitForReadyRead 会检查drainOutputPipes 的返回值,而waitForFinished 不会。我使用的是 Qt 5.8.0,所以可能在最新版本中有所不同。围绕代码工作,看看这是否对我的情况有影响...... 已确认。对waitForReadyRead 的调用在waitForFinished 之后返回false。 @JimmyG 那是因为waitForReadyRead() 需要告诉调用者是否有任何要阅读的内容。

以上是关于使用QProcess,是不是需要在waitForFinished之后调用waitForReadyRead?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不冻结 UI 的情况下使用 QProcess 循环的输出更新 UI?

如何在不冻结 UI 的情况下使用 QProcess 循环的输出更新 UI?

命令在终端中工作,但不是通过 QProcess

在 PyQt 中使用 QProcess 运行类方法

如果子进程崩溃,是不是会发出 QProcess::finished?

如何检查 QProcess 是不是正确执行?