Can't stop a process



  • Hi,

    I am using QProcess to launch a .exe process in Windows, lets say db.exe. This db.exe program launches another process, a java.exe process.

    process->start("db.exe", QStringList() << "");
    

    It runs the db.exe and then java.exe properly.
    However, when I try to terminate the process gracefully, it doesn't work. So process->terminate() does nothing.
    If I do process->kill() it kills the db.exe process, but leaving java.exe alive.

    If I run the db.exe program by command line, I can stop it with ctrl+c (it closes both proceses), but I don't know how to send that signal using QProcess.
    I don't have any control over the db.exe application (so I can't modify it.)

    I have a lot of other functionalities relaying on QProcess, so I don't want to start processes without it.
    Any idea?


  • Lifetime Qt Champion

    Hi,

    One possibility would be to call taskkill from another QProcess.

    Hope it helps



  • Hi @enekow
    Its not recommended to kill process from another process. A process should be killed gracefully by itself or by system.
    Its recommended to communicate between process using IPC.
    Start Process2 from Process1. Communicate to Process2 from Process1 using IPC and kill Process2 gracefully.



  • Thanks for your responses :)

    @SGaist said in Can't stop a process:

    One possibility would be to call taskkill from another QProcess.

    I'll try that way, because I dont find another way. However, the only way I have to identify the java.exe process is by name. And it doesn't seems very clever to kill all processes called java.exe.

    @yuvaram said in Can't stop a process:

    Its not recommended to kill process from another process. A process should be killed gracefully by itself or by system.
    Its recommended to communicate between process using IPC.
    Start Process2 from Process1. Communicate to Process2 from Process1 using IPC and kill Process2 gracefully.

    That is what I am trying to do... but I cannot modify Process1 to change its behavior. I launch Process1 and this process launches the Process2 automatically. The only way to communicate with Process2 through Process1 is sending ctrl+c signal to Process1.


  • Lifetime Qt Champion

    You can get the process id using QProcess::processId.



  • @SGaist said in Can't stop a process:

    You can get the process id using QProcess::processId.

    Yeah, but I'll get the PID of Process1 (so the db.exe), not the Process2 (java.exe).



  • @enekow
    This in itself has nothing to do with Qt. It's to do with how processes work under the OS.

    You need either to find parent process IDs (certainly under Linux, not sure how that works under Windows), or possibly send a signal(SIGINT) to db.exe to replicate the Ctrl+C which you say works --- though that might work from terminal only, depending on how it's been written.



  • @JonB
    I know this isn't something only related with Qt, but I was wondering if QProcess had a mechanism to send that crtl+c signal/command.

    I guess I will try to identify the Process2 (java.exe) pid more precisely somehow.

    Thanks



  • @enekow
    No to QProcess "sending Ctrl+C".

    Have a look at https://stackoverflow.com/questions/27771843/whats-the-difference-between-qprocesskill-and-qprocessterminate

    "Under Windows terminate() sends WM_CLOSE window message" means it'll be useless for console applications:

    Console applications on Windows that do not run an event loop, or whose event loop does not handle the WM_CLOSE message, can only be terminated by calling kill().

    I think you need to do something like the following (from http://www.qtcentre.org/threads/36911-Can-t-send-a-Ctrl-C-to-a-QProcess-(Win32)):

    Default Re: Can't send a Ctrl-C to a QProcess (Win32)
    Sorry, yes, Ctrl+C is SIGINT. Nevertheless using terminate() is the way to go. Unfortunately console applications don't support being killed by terminate(). What you can do is try to send the SIGINT signal yourself to the other process using ::kill() (your system should support it).

    Or also there:

    Sorry for the late entrance, but it would seem this is still a valid discussion. I have just solved the problem under Windows 7 with Qt5 by closing the stream to stdin of the child process. I.e. process->close() instead of process->terminate(). The child process was then gracefully able to shut down.

    though note the latter may or may not work.



  • Thanks for your help @JonB

    However I already try those options with no result. I think it could work with GenerateConsoleCtrlEvent (WINAPI) but it sends the event to an entire group of processes (including the main process). Maybe creating the processes detached could work, but not an option for me.

    I think I found the way to go. In windows there is a tool called wmic.

    wmic process where (ParentProcessId="Process1_PID") get ProcessId
    

    This command will return all children pids. Then, I can taskkill using the pids.
    It isn't a very elegant elegant way, but I don't have much options.

    Thank you all :D


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.