3

I have a Windows Qt application that uses QProcess to run an external program which may or may not need input. The input will always be y followed by ENTER if needed. And, if y is entered, the program exits immediately.

So the actions I take in the code are:

QProcess process;
QString cmd = QString("myprog.exe %1").arg(myParam);

process.start(cmd);
if (! process.waitForStarted(10000))
{
    logError("Timed out starting preparation!");
    return;
}
process.write("y\n");
if (! process.waitForFinished(5000))
{
    process.kill();
    process.waitForFinished(5000);
    logError("Timed out finishing preparation!");
    return;
}

Now I will often see that final error message despite the fact that the process appears to have worked correctly (entering y can be detected after the event so I know it's happening). This is intermittent.

Investigations have led me to the Qt QProcess doco, which has this gem:

bool QProcess::waitForFinished(int msecs = 30000)

Blocks until the process has finished and the finished() signal has been emitted, or until msecs milliseconds have passed.

Returns true if the process finished; otherwise returns false (if the operation timed out, if an error occurred, or if this QProcess is already finished).

I suspect it may be that last sentence which is biting me. Since the process exits as soon as you enter y, I think it's no longer there when I get to the point of first calling WaitForFinished(). So that function will return false and I'll assume it didn't work properly.

So I have two questions based on that. First, is my understanding correct? Is there a chance that the process will have exited before checking and will that result in a false return value.

Second, if that is the case, how would you tell the difference between a process that has exited before you check, and one that hasn't exited before your time-out kicks in?

Community
  • 1
  • 1
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • As seen in the [source code](https://code.woboq.org/qt5/qtbase/src/corelib/io/qprocess.cpp.html#_ZN8QProcess15waitForFinishedEi), it checks if the process state is `QProcess::NotRunning` and returns false if so. You could do this check yourself before calling `QProcess::waitForFinished`. – thuga Dec 13 '17 at 11:03

1 Answers1

4

When you think that the process is already closed when you call waitForFinished(), you should check if the process is running.

process.write("y\n");
process.waitForFinished(5000)
if(process.state() != QProcess::NotRunning)
{ 
  ..
}
Louis Kröger
  • 344
  • 3
  • 10