PySimpleGUI/Demo_psutil_Kill_Processes.py

102 lines
3.8 KiB
Python
Raw Normal View History

2018-10-06 16:49:06 +00:00
#!/usr/bin/env python
import sys
import sys
if sys.version_info[0] >= 3:
import PySimpleGUI as sg
else:
import PySimpleGUI27 as sg
import os
import signal
import psutil
import operator
"""
2018-10-07 02:42:47 +00:00
Utility to show running processes, CPU usage and provides way to kill processes.
Based on psutil package that is easily installed using pip
2018-10-06 16:49:06 +00:00
"""
def kill_proc_tree(pid, sig=signal.SIGTERM, include_parent=True,
timeout=None, on_terminate=None):
"""Kill a process tree (including grandchildren) with signal
"sig" and return a (gone, still_alive) tuple.
"on_terminate", if specified, is a callabck function which is
called as soon as a child terminates.
"""
if pid == os.getpid():
raise RuntimeError("I refuse to kill myself")
parent = psutil.Process(pid)
children = parent.children(recursive=True)
if include_parent:
children.append(parent)
for p in children:
p.send_signal(sig)
gone, alive = psutil.wait_procs(children, timeout=timeout,
callback=on_terminate)
return (gone, alive)
def main():
# ---------------- Create Form ----------------
2018-10-07 02:42:47 +00:00
sg.ChangeLookAndFeel('Topanga')
2018-10-06 16:49:06 +00:00
layout = [[sg.Text('Process Killer - Choose one or more processes',
size=(45,1), font=('Helvetica', 15))],
2018-10-07 02:42:47 +00:00
[sg.Listbox(values=[' '], size=(50, 30), select_mode=sg.SELECT_MODE_EXTENDED, font=('Courier', 12), key='_processes_')],
2018-10-06 16:49:06 +00:00
[sg.Text('Click refresh once or twice.. once for list, second to get CPU usage')],
2018-10-07 02:42:47 +00:00
[sg.T('Filter by typing name', font='ANY 14'), sg.In(size=(15,1), font='any 14', key='_filter_')],
[sg.RButton('Refresh'),
2018-10-07 02:57:57 +00:00
sg.RButton('Kill', button_color=('white','red'), bind_return_key=True),
2018-10-07 02:42:47 +00:00
sg.Exit(button_color=('white', 'sea green'))]]
2018-10-06 16:49:06 +00:00
window = sg.Window('Process Killer',
keep_on_top=True,
auto_size_buttons=False,
default_button_element_size=(9,1),
2018-10-07 02:42:47 +00:00
return_keyboard_events=True,
2018-10-06 16:49:06 +00:00
grab_anywhere=False).Layout(layout)
2018-10-07 02:42:47 +00:00
proc_list = []
2018-10-06 16:49:06 +00:00
# ---------------- main loop ----------------
while (True):
# --------- Read and update window --------
button, values = window.Read()
# --------- Do Button Operations --------
if values is None or button == 'Exit':
break
if button == 'Refresh':
psutil.cpu_percent(interval=1)
procs = psutil.process_iter()
top = {proc.name(): (proc.cpu_percent(), proc.pid) for proc in procs}
# cpu_percent = psutil.cpu_percent(interval=interval) # if don't wan to use a task
# --------- Create list of top % CPU porocesses --------
top_sorted = sorted(top.items(), key=operator.itemgetter(0), reverse=False)
if top_sorted:
top_sorted.pop(0)
2018-10-07 02:42:47 +00:00
proc_list = []
2018-10-06 16:49:06 +00:00
for proc, pair in top_sorted:
cpu, pid = pair
2018-10-07 02:42:47 +00:00
proc_list.append('{:5d} {:5.2f} {}\n'.format(pid, cpu/10, proc))
2018-10-06 16:49:06 +00:00
2018-10-07 02:42:47 +00:00
window.FindElement('_processes_').Update(proc_list)
elif button == 'Kill':
2018-10-06 16:49:06 +00:00
processes_to_kill = values['_processes_']
for proc in processes_to_kill:
pid = int(proc[0:5])
if sg.PopupYesNo('About to kill {} {}'.format(pid, proc[13:]), keep_on_top=True) == 'Yes':
kill_proc_tree(pid=pid)
2018-10-07 02:42:47 +00:00
else:
new_output = []
for line in proc_list:
if values['_filter_'] in line.lower():
new_output.append(line)
window.FindElement('_processes_').Update(new_output)
2018-10-06 16:49:06 +00:00
if __name__ == "__main__":
main()