Kill background process launched with shell=True in Windows

送分小仙女□ 提交于 2019-12-11 15:44:05

问题


I'm trying to launch from Python a server to score PMML models in Java. Once the calculations have been made, I want to be able to close that server (i.e. terminate the process). I'm on Windows 10. However, I'm finding it way more confusing than I thought it would be.

First I launch the server like this:

p = subprocess.Popen('START /B java -jar openscoring-server-executable-1.4.3.jar',
                      shell=True)

I make it run on the background so that the CMD window doesn't show up when the user runs the script. To make this possible I think that the shell=True parameter is necessary.

When I try to kill the process using this line:

subprocess.call("TASKKILL /F /PID {pid} /T".format(pid=p.pid))

The process is still running. In fact, the PID that p.pid returns doesn't even exist in the Task Manager. I've confirmed this when trying to use the solution provided in this answer:

def kill(proc_pid):
    process = psutil.Process(proc_pid)
    for proc in process.children(recursive=True):
        proc.kill()
    process.kill()

kill(p.pid)

This returns the exception NoSuchProcess: no process found with pid 5280.

I can see via the Task Manager the PID assigned to the process I want to kill:

But I don't know how to find that PID within Python to terminate it. The answers I've found in the site don't seem to work with processes running in the background.

EDIT:

I think this could be solved if I was able to run the command with shell=False, but I don't know how to do it because of the START /B. This returns an error:

p = subprocess.Popen(['START', '/B', 'java', '-jar openscoring-server-executable-1.4.3.jar'])

回答1:


You could just search for your app here and close.

import psutil
import os

ls = []
for p in psutil.process_iter():
    try:
        name = p.name()
        cmdline = p.cmdline()
        exe = p.exe()
        pid = p.pid
    except (psutil.AccessDenied, psutil.ZombieProcess):
        continue
    except psutil.NoSuchProcess:
        continue



回答2:


If you can't figure out the right PID, I might have an alternative solution leveraging the arguments you used to start the process. It's not as nice, since you will iterate over the process tree until you find a hit, but this way it will find the process for sure.

Just remember that this might not always return the correct process if you have multiple processes with the same argument running.

def process_get(*args):
    """Returns the process matching ``args``.
    Relies on ``args`` matching the argument list of the process to find.

    Args:
        *args: process arguments, e.g. ["java", "-jar", "somejar.jar"]

    Returns:
        :obj:`process`
    """
    import psutil
    for process in psutil.process_iter():
        try:
            if process.cmdline() == args:
                return process
        except psutil.AccessDenied:
            pass
    return None


来源:https://stackoverflow.com/questions/52630855/kill-background-process-launched-with-shell-true-in-windows

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!