I’m having some problems trying to kill processes on win32. First things first, if we take a look to the used code by ExecCommand:
def kill(self):
if not self.killed:
self.killed = True
if sys.platform == "win32":
# terminate would not kill process opened by the shell cmd.exe,
# it will only kill cmd.exe leaving the child running
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
subprocess.Popen(
"taskkill /PID " + str(self.proc.pid),
startupinfo=startupinfo)
else:
self.proc.terminate()
self.listener = None
We can see the decission of ExecCommand is leaving child processes still running (dunno the reason)… Anyway, after researching a bit, I’ve found this thread https://stackoverflow.com/questions/1230669/subprocess-deleting-child-processes-in-windows and I’ve decided to give it a shot to the lightweight function:
def kill_command_windows(pid):
'''Run command via subprocess'''
dev_null = open(os.devnull, 'w')
command = ['TASKKILL', '/F', '/T', '/PID', str(pid)]
proc = subprocess.Popen(command, stdin=dev_null, stdout=sys.stdout, stderr=sys.stderr)
Problem is, this method will work very rarely, in one of my tests I’ve experienced how SublimeText process will be frozen. Could anyone advice how to kill properly win32 processes (parent+childs) from SublimeText?
You can reproduce very easily all of this with a couple of lines:
>>> sublime.active_window().run_command("exec", args={"shell_cmd": "notepad.exe"})
>>> sublime.active_window().run_command("exec", args={"kill": True})
And you’ll see notepad will still remain alive, then you can try the posted kill_command_windows
and if you’re lucky enough you’ll leave ST hanging out after the first attempt.
Thx in advance.
PS: To check the processes info (PIDs) you can use the task admin from windows or even better, processExplorer, which is a really great tool. Or… just print self.proc.pid in the execCommand run method