QProcess detection running or finished state - hints needed
-
Qt mates, I need your help
The issue is as follow - I have a QProcess started, and I need either to detect when it has been finished, or if it is still running.
1st attempt was:qint64 pid = 0; QProcess::startDetached("cmd", args, qApp->applicationDirPath() + "/Stuff", &pid);
sadly, the returned pid is incorrect (Qt bug probably) compared to what Windows Task Manager shows, so I couldn't use https://stackoverflow.com/questions/13633797/how-to-check-if-a-program-is-running-by-its-name-with-qt-c/13635127#13635127
Well then, another attempt:
QProcess *process = new QProcess(parent); bool b = QObject::connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), parent, SLOT(finished(int, QProcess::ExitStatus))); qDebug() << "połączenie sygnału finished: " << b; b = QObject::connect(process, SIGNAL(errorOccurred(QProcess::ProcessError)), parent, SLOT(errorOccurred(QProcess::ProcessError))); qDebug() << "połączenie sygnału error: " << b; b = QObject::connect(process, SIGNAL(started()), parent, SLOT(processStarted())); qDebug() << "połączenie sygnału started: " << b; process->setWorkingDirectory(qApp->applicationDirPath() + "/Stuff"); process->setArguments(args); process->setProgram("cmd"); process->start();
NOPE - finished() signal is not emitted. Hmmm, so maybe this approach:
//all the stuff as above, except start: int returnCode = process->execute("cmd", args);
and guess what, NOPE. Such call does not respect setWorkingDirectory(); a pity as execute() is the closest to my needs.
Tell me mates, what else I could use?
OS Windows 7, Qt 5.11.1
-
@MasterBLB said in QProcess detection running or finished state - hints needed:
args << "/C" << "start" << "cmd_ddl.bat";
Why "start" ? May it be that this creates a second cmd.exe instance, hence the wrong PID?
How about:
args << "/c" << "cmd_ddl.bat";
?Regards
-
@MasterBLB said in QProcess detection running or finished state - hints needed:
args << "/C" << "start" << "cmd_ddl.bat";
Just to reply to your first interrogation why PID seems to be wrong for you: adding "start" to launch the batch file will start "cmd_ddl.bat" in another process. You will get the PID for the "cmd.exe", but not for "cmd_ddm.bat"
qint64 pid = 0; QProcess::startDetached("cmd", QStringList() << "/c" << "cmd_ddl.bat" , qApp->applicationDirPath() + "/Stuff", &pid);
Shoud do what you want to do... now you have to be sure "cmd_ddl.bat" will finish!
Regards
-
@MasterBLB "now you have to be sure "cmd_ddl.bat" will finish!"
-
@MasterBLB said in QProcess detection running or finished state - hints needed:
The pid is neither for cmd, nor for cmd_ddl.bat, nor ddl.exe (stuff run from the .bat)
But are you sure you batch is finishing?
Do you have tried to kill it from Task Manager to see if signal is raised? -
@MasterBLB
Could we (re-)start by discovering, given that you want to know if it is still running, why you want to usestartDetached()
rather thanstart()
? Is it that your bat file/sub-process needs to request a (visible) console, or why? -
@MasterBLB
I do not know how the pid returned fromstartDetached()
relates to that of the process spawned, and to detecting sub-process termination. Remember that says:If the function is successful then *pid is set to the process identifier of the started process. Note that the child process may exit and the PID may become invalid without notice. Furthermore, after the child process exits, the same PID may be recycled and used by a completely different process.
If you really were to stick with
startDetached()
, you would probably need to use WindowsEnumProcesses()
to detect if yourddl.exe
is still running or not. But......Given that it is giving you problems, if you cannot resolve why don't you remove that complication by trying out
start()
instead? You can handle displaying an error message, if that's allddl.exe
needs a console for(?), from within Qt. If you just test it out, do you fare better withstart()
overstartDetached()
? You will not be using pid, just seeing whether or not you have receivedfinished()
/errorOccurred()
.