5

I'm using Windows 10 and Python 3.7.

I ran the following command.

import subprocess
exeFilePath = "C:/Users/test/test.exe"
subprocess.run(exeFilePath)

The .exe file launched with this command, I want to force-quit when the button is clicked or when the function is executed.

Looking at a past question, it has been indicated that the way to force quit is to get a PID and do an OS.kill as follows.

import signal
os.kill(self.p.pid, signal.CTRL_C_EVENT)

However, I don't know how to get the PID of the process started in subprocess.run.

What should I do?

gncc
  • 300
  • 4
  • 13
  • It does not make sense, because `run` is a blocking call. So the idiomatic way is not to use run but create a subprocess, and then use `kill` or `terminate` on it. – Serge Ballesta May 28 '20 at 14:05
  • Does this answer your question? [How to terminate process from Python using pid?](https://stackoverflow.com/questions/17856928/how-to-terminate-process-from-python-using-pid) – Prayson W. Daniel May 28 '20 at 14:06

1 Answers1

5

Assign a variable to your subprocess

import os
import signal
import subprocess

exeFilePath = "C:/Users/test/test.exe"
p = subprocess.Popen(exeFilePath)
print(p.pid) # the pid
os.kill(p.pid, signal.SIGTERM) #or signal.SIGKILL 

In same cases the process has children processes. You need to kill all processes to terminate it. In that case you can use psutil

#python -m pip install —user psutil 

import psutil

#remember to assign subprocess to a variable 

def kills(pid):
    '''Kills all process'''
    parent = psutil.Process(pid)
    for child in parent.children(recursive=True):
        child.kill()
    parent.kill()

#assumes variable p
kills(p.pid)

This will kill all processes in that PID

Prayson W. Daniel
  • 14,191
  • 4
  • 51
  • 57
  • 1
    Thank you for answering my question. However, I get the following error. `AttributeError: 'CompletedProcess' object has no attribute 'pid'`. – gncc May 28 '20 at 14:28
  • 1
    Instead of `subprocess.run`, can you try `subprocess.Popen`? – Prayson W. Daniel May 28 '20 at 14:40
  • 1
    I was able to boot and get the pid that way. Thank you. – gncc May 28 '20 at 14:49
  • 2
    It seems than `run, call` does not return pid. – Prayson W. Daniel May 28 '20 at 14:55
  • Windows does not maintain a process tree. A process only stores the PID of its parent process, which allows for orphaned processes. The only reliable way to kill all child processes is to run the process in a kill-on-close Job object. – Eryk Sun May 30 '20 at 13:42
  • If you need to be extremely strict about not letting any process escape, the Job object has to configured to disallow breakaway. That may make some programs fail if they explicitly try to break away a child process. Also, it's not recommended prior to Windows 8. Older versions of Windows didn't support nested Job objects, so breaking away from an existing Job was the only way to add a child process to a new Job. – Eryk Sun May 30 '20 at 13:46