How to close a process using "atexit" and "subprocess" module when the user close the script

65 views Asked by At

So in my script I run an executable file in headless. But I need to close it when the user exit/close the script. I tried this code but it doesn't work, run.exe is still running in background. (I verified using process hacker)

#....
# Close run.exe at exit
def clear(process):
    subprocess.call(f"TASKKILL /F /IM {process}", shell=True)

#...
# Run no gui "run.exe" in headless
def run():
    exe_path = "engine/run.exe"
    startupinfo = None

    if sys.platform == "win32":
        startupinfo = subprocess.STARTUPINFO()
        startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW

    process = subprocess.Popen(
        exe_path,
        stdout=subprocess.DEVNULL,
        stderr=subprocess.DEVNULL,
        startupinfo=startupinfo,
        creationflags=subprocess.CREATE_NO_WINDOW | subprocess.CREATE_NEW_PROCESS_GROUP,
        close_fds=True,
        shell=False,
    )

    atexit.register(clear, process)

(This doesn't work for me tho)

Python 11.2, Windows (x64)

1

There are 1 answers

0
nigh_anxiety On

The problem you're having is that subprocess.Popen() returns a Popen object, not just the process id. When I tested the example code, the call to TASKKILL returned the error message: The syntax of the command is incorrect., due to not passing in a pid.

The simple solution is to access process.pid at some point, either when calling atexit.register(clear, process),

    atexit.register(clear, process.pid)

or within the clear(process) function itself

# Close run.exe at exit
def clear(process):
    subprocess.call(f"TASKKILL /F /IM {process.pid}", shell=True)

Another consideration would be to use os.kill instead of using subprocess to call TaskKill.

    import os
    import signal
    ...

    atexit.register(os.kill, process.pid, signal.SIGTERM)