Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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 You never get finished() because the process is always running!

    Do you have add "/c" as argument for the cmd process to ensure cmd will terminate after running command?



  • Sure thing:

    args << "/C" << "start" << "cmd_ddl.bat";
    

  • Lifetime Qt Champion

    @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



  • The same



  • @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



  • The pid is neither for cmd, nor for cmd_ddl.bat, nor ddl.exe (stuff run from the .bat)


  • Lifetime Qt Champion

    @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 use startDetached() rather than start()? Is it that your bat file/sub-process needs to request a (visible) console, or why?



  • Indeed, ddl.exe which is called from inside of the cmd_ddl.bat needs to have visible console whose in not closed immediately in case of error.



  • @MasterBLB
    I do not know how the pid returned from startDetached() 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 Windows EnumProcesses() to detect if your ddl.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 all ddl.exe needs a console for(?), from within Qt. If you just test it out, do you fare better with start() over startDetached()? You will not be using pid, just seeing whether or not you have received finished()/errorOccurred().


Log in to reply