缘由:
有个MoUSOCoreWorker 进程,不想它启动,它慢慢的就占用内存达1GB,就想着能不能用Python检测到然后就直接关闭了。
功能:
没有多复杂的功能,就只是输入指定的进程名字,然后点击开始监控,就每3秒循环监控是否存在指定的进程,然后关闭此进程。
运行图:
下载地址:
包含打包好的成品和源代码。
python打包使用的是Pyinstaller打包。
链接:https://ide.lanzouv.com/b0fonmb4f 密码:a6g6
更新:
2024.08.01 v1.0.2
1.更新监控频率自定义
2024.08.01 v1.0.1
1.更新监控状态栏
2.增加可以停止监控功能
2024.07.31 v1.0.0
初始版本
源代码:
一共有4个文件:main.py、ui.py、control.py、config_52pj_pd.ini
main.py
from ui import Win as MainWin
from control import Controller as MainUIController
app = MainWin(MainUIController())
if __name__ == "__main__":
app.mainloop()
ui.py
from tkinter import *
from tkinter.ttk import *
class WinGUI(Tk):
def __init__(self):
super().__init__()
self.__win()
self.tk_label_lz86gwum = self.__tk_label_lz86gwum(self)
self.tk_text_lz86hgpy = self.__tk_text_lz86hgpy(self)
self.tk_button_lz86i78f = self.__tk_button_lz86i78f(self)
self.tk_input_lz86i88e = self.__tk_input_lz86i88e(self)
self.tk_label_lz86ipc7 = self.__tk_label_lz86ipc7(self)
self.tk_label_lz86k0fr = self.__tk_label_lz86k0fr(self)
self.tk_label_lzan8930 = self.__tk_label_lzan8930(self)
self.tk_input_lzan99g4 = self.__tk_input_lzan99g4(self)
self.tk_label_lzaw42hr = self.__tk_label_lzaw42hr(self)
self.tk_input_lzaw4q67 = self.__tk_input_lzaw4q67(self)
self.tk_label_lzaw4vub = self.__tk_label_lzaw4vub(self)
def __win(self):
self.title("检测指定进程后关闭_v1.0.2")
# 设置窗口大小、居中
width = 598
height = 415
screenwidth = self.winfo_screenwidth()
screenheight = self.winfo_screenheight()
geometry = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
self.geometry(geometry)
self.resizable(width=False, height=False)
def scrollbar_autohide(self, vbar, hbar, widget):
"""自动隐藏滚动条"""
def show():
if vbar: vbar.lift(widget)
if hbar: hbar.lift(widget)
def hide():
if vbar: vbar.lower(widget)
if hbar: hbar.lower(widget)
hide()
widget.bind("<Enter>", lambda e: show())
if vbar: vbar.bind("<Enter>", lambda e: show())
if vbar: vbar.bind("<Leave>", lambda e: hide())
if hbar: hbar.bind("<Enter>", lambda e: show())
if hbar: hbar.bind("<Leave>", lambda e: hide())
widget.bind("<Leave>", lambda e: hide())
def v_scrollbar(self, vbar, widget, x, y, w, h, pw, ph):
widget.configure(yscrollcommand=vbar.set)
vbar.config(command=widget.yview)
vbar.place(relx=(w + x) / pw, rely=y / ph, relheight=h / ph, anchor='ne')
def h_scrollbar(self, hbar, widget, x, y, w, h, pw, ph):
widget.configure(xscrollcommand=hbar.set)
hbar.config(command=widget.xview)
hbar.place(relx=x / pw, rely=(y + h) / ph, relwidth=w / pw, anchor='sw')
def create_bar(self, master, widget, is_vbar, is_hbar, x, y, w, h, pw, ph):
vbar, hbar = None, None
if is_vbar:
vbar = Scrollbar(master)
self.v_scrollbar(vbar, widget, x, y, w, h, pw, ph)
if is_hbar:
hbar = Scrollbar(master, orient="horizontal")
self.h_scrollbar(hbar, widget, x, y, w, h, pw, ph)
self.scrollbar_autohide(vbar, hbar, widget)
def __tk_label_lz86gwum(self, parent):
label = Label(parent, text="检测指定进程后关闭_v1.0.2", anchor="center", )
label.place(x=0, y=0, width=598, height=34)
return label
def __tk_text_lz86hgpy(self, parent):
text = Text(parent)
text.bind("<Key>", lambda e: "break")
text.place(x=0, y=179, width=597, height=234)
self.create_bar(parent, text, True, False, 0, 179, 597, 234, 598, 415)
return text
def __tk_button_lz86i78f(self, parent):
btn = Button(parent, text="开始监控", takefocus=False, )
btn.place(x=455, y=135, width=122, height=37)
return btn
def __tk_input_lz86i88e(self, parent):
ipt = Entry(parent, )
ipt.place(x=0, y=63, width=598, height=30)
return ipt
def __tk_label_lz86ipc7(self, parent):
label = Label(parent, text="输入进程名称,多个进程用英文输入状态下的,分隔:", anchor="center", )
label.place(x=0, y=32, width=289, height=30)
return label
def __tk_label_lz86k0fr(self, parent):
label = Label(parent, text="监控记录:", anchor="center", )
label.place(x=0, y=149, width=88, height=30)
return label
def __tk_label_lzan8930(self, parent):
label = Label(parent, text="监控状态:", anchor="center", )
label.place(x=0, y=98, width=88, height=30)
return label
def __tk_input_lzan99g4(self, parent):
ipt = Entry(parent, )
ipt.place(x=94, y=98, width=220, height=30)
ipt.bind("<Key>", lambda e: "break")
return ipt
def __tk_label_lzaw42hr(self, parent):
label = Label(parent, text="监控频率:", anchor="center", )
label.place(x=326, y=98, width=68, height=30)
return label
def __tk_input_lzaw4q67(self, parent):
ipt = Entry(parent, )
ipt.place(x=395, y=98, width=39, height=30)
return ipt
def __tk_label_lzaw4vub(self, parent):
label = Label(parent, text="秒监控一次", anchor="center", )
label.place(x=436, y=98, width=90, height=30)
return label
class Win(WinGUI):
def __init__(self, controller):
self.ctl = controller
super().__init__()
self.__event_bind()
self.__style_config()
self.ctl.init(self)
def __event_bind(self):
self.tk_button_lz86i78f.bind('<Button-1>', self.ctl.startMonitor)
pass
def __style_config(self):
pass
if __name__ == "__main__":
win = WinGUI()
win.mainloop()
control.py
import configparser
import time
import psutil
import threading
import os
import tkinter as tk
from tkinter.messagebox import showinfo
iniFile = "config_52pj_pd.ini"
defaultFrequency = 3
class Controller:
ui: object
def __init__(self):
pass
def init(self, ui):
self.ui = ui
self.loadInitialization()
self.monitor_running = False # 添加一个新的标志
self.stop_event = None # 初始化 stop_event 为 None
self.ui.tk_input_lzaw4q67.config(validate="focusout", validatecommand=self.frequencyValueVerification, invalidcommand=lambda: showinfo(title="提示", message ="请输入数字!"))
def frequencyValueVerification(self):
frequency = self.ui.tk_input_lzaw4q67.get()
return self.setFrequency(frequency,0)
def setFrequency(self, frequency,type=0):
if type == 1:
frequency = self.ui.tk_input_lzaw4q67.get()
try:
frequency = int(frequency)
if type == 1:
return frequency
else:
self.ui.tk_input_lzaw4q67.delete(0, tk.END)
self.ui.tk_input_lzaw4q67.insert(0, frequency)
self.configurationSave('default', 'frequency', frequency)
return True
except ValueError:
self.ui.tk_input_lzaw4q67.delete(0, tk.END)
self.ui.tk_input_lzaw4q67.insert(0, defaultFrequency)
self.configurationSave('default', 'frequency', defaultFrequency)
if type == 1:
return defaultFrequency
else:
return False
def loadInitialization(self):
#判断文件是否存在
if not os.path.exists(iniFile):
with open(iniFile, 'w') as file:
file.write("[default]\nprocess_name = \nfrequency = " + str(defaultFrequency))
config = configparser.ConfigParser()
config.read(iniFile,encoding='GBK')
ini_process_name = config.get('default','process_name')
frequency = config.get('default','frequency')
self.ui.tk_input_lz86i88e.insert(0,ini_process_name)
self.setFrequency(frequency,0)
def startMonitor(self,evt):
if self.monitor_running == True:
return # 如果监控已经在运行,则不执行任何操作
process_name = self.ui.tk_input_lz86i88e.get()
if process_name == "":
showinfo(title="提示", message ="未输入进程!")
return False
process_name = process_name.replace(",",",")
self.configurationSave('default', 'process_name', process_name)
process_name_list = process_name.split(",")
frequency = self.setFrequency(0,1)
# 创建一个线程来更新
self.stop_event = threading.Event() # 创建一个事件对象
self.thread = threading.Thread(target=self.update_counter, args=(process_name_list,frequency))
self.thread.daemon = True
self.thread.start()
self.ui.tk_button_lz86i78f.config(state=tk.DISABLED) # 禁用按钮
self.monitor_running = True
def update_counter(self, process_name_list,frequency):
i = 0
self.stop_event.clear()
while not self.stop_event.is_set(): # 检查是否收到停止信号
current_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
for proc in psutil.process_iter(['pid', 'name']):
if proc.info['name'] in process_name_list:
proc.terminate()
self.ui.tk_text_lz86hgpy.insert(tk.END, f"{current_time}:{proc.info['name']}已被关闭;进程ID:{proc.pid}。\r\n")
self.ui.tk_text_lz86hgpy.see(tk.END) # 自动滚动到底部
self.ui.tk_input_lzan99g4.delete(0, tk.END)
self.ui.tk_input_lzan99g4.insert(0, f"{current_time}:持续监控中...")
if self.stop_event.is_set():
break
# 按钮启用
if i < 6:
i += defaultFrequency
elif i == 6:
self.ui.tk_button_lz86i78f.config(state=tk.NORMAL,text="停止监控",command=lambda: self.stopMonitor())
i = 7
time.sleep(frequency)
def stopMonitor(self):
if self.monitor_running:
self.stop_event.set() # 设置停止事件
self.monitor_running = False
self.ui.tk_button_lz86i78f.config(state=tk.NORMAL, text="开始监控",command=lambda: self.startMonitor(self))
self.ui.tk_input_lzan99g4.delete(0, tk.END)
self.ui.tk_input_lzan99g4.insert(0, f"监控已停止")
#配置保存
def configurationSave(self,section,key,value):
config = configparser.ConfigParser()
config.read('config_52pj_pd.ini',encoding='GBK')
if not config.has_section(section): # 判断是否包含指定section
config.add_section(section) # 添加section到配置文件
config.set(section, key, str(value)) # 添加section的key-value
with open('config_52pj_pd.ini', "w") as f:
config.write(f) # 将configparser对象写入.ini类型的文件
config_52pj_pd.ini
[default]
process_name =
frequency = 3
备注:
取消键盘输入事件代码:root.bind("<Key>", lambda e: "break")