一个可以禁用任意程序的上下行网络的小工具,有倒计时功能
import subprocess import tkinter as tk from tkinter import ttk from datetime import datetime root = tk.Tk() root.title('网络计划任务') root.geometry('500x400') # 创建一个 Text 组件 text_widget = tk.Text(root, height=15, width=65,background="black",foreground="white") text_widget.place(x=20, y=4) import winreg def get_exe_install_path(): try: # 打开HKEY_CURRENT_USER\SOFTWARE\Tencent\WeChat key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\51d76d93-5c99-52d8-8eaf-e2973435dc9b" ) # 读取install_path的值 # 注意:QueryValueEx返回的是一个元组,其中第一个元素是值,第二个元素是值的类型 display_icon, regtype = winreg.QueryValueEx(key, "displayicon") # 分割字符串并获取逗号前的部分 # 关闭注册表项 winreg.CloseKey(key) exe_path = display_icon.split(',')[0].strip() return exe_path except WindowsError as e: # 如果发生错误(例如,键不存在),则打印错误并返回None print(f"Error accessing registry: {e}") return None # 调用函数并打印结果 exe_path = get_exe_install_path() if exe_path: print(f"直播伴侣的安装路径为:{exe_path}") text_widget.insert(tk.END, f"直播伴侣的安装路径为:{exe_path} \n") text_widget.see(tk.END) else: print("无法找到直播伴侣的安装路径") text_widget.insert(tk.END,"无法找到直播伴侣的安装路径") text_widget.see(tk.END) def disableNet(): print(f"开始禁用网络") # 定义要执行的CMD命令 cmd = f'for %a in (in out) do netsh advfirewall firewall add rule action=block name="blocked webcast" dir=%a program="{exe_path}"' # 使用subprocess.run()执行命令并捕获输出 result = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) print(result.stdout) # text_widget.insert(tk.END, f"{result.stdout} \n") # 输出命令的标准错误(如果有) if result.stderr: print("标准错误:") print(result.stderr) text_widget.insert(tk.END, f"标准错误: {result.stderr} \n") text_widget.see(tk.END) # 滚动到最后一个字符 # 检查命令是否成功执行 if result.returncode != 0: print(f"命令执行失败,返回码为:{result.returncode}") text_widget.insert(tk.END, f"命令执行失败,返回码为:{result.returncode} \n") else: # 输出命令的标准输出 # print("已经禁用网络") # 获取当前时间 now = datetime.now() # 格式化当前时间 formatted_now = now.strftime("%Y-%m-%d %H:%M:%S") text_widget.insert(tk.END, f"{formatted_now}---已经禁用网络 \n") text_widget.see(tk.END) # 滚动到最后一个字符 def enableNet(): print(f"开始启用网络 ") # 定义要执行的CMD命令 cmd = 'netsh advfirewall firewall delete rule name="blocked webcast"' # 使用subprocess.run()执行命令并捕获输出 result = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) # 输出命令的标准输出 # print(result.stdout) # text_widget.insert(tk.END, f"{result.stdout} \n") # text_widget.see(tk.END) # 滚动到最后一个字符 # 输出命令的标准错误(如果有) if result.stderr: print("标准错误:") print(result.stderr) text_widget.insert(tk.END, f"${result.stderr} \n") # 检查命令是否成功执行 if result.returncode != 0: print(f"命令执行失败,返回码为:{result.returncode}") text_widget.insert(tk.END, f"命令执行失败,返回码为:{result.returncode} \n") else: print("已经启用网络:") # 获取当前时间 now = datetime.now() # 格式化当前时间 formatted_now = now.strftime("%Y-%m-%d %H:%M:%S") text_widget.insert(tk.END, f"{formatted_now}---已经启用网络 \n") text_widget.see(tk.END) # 滚动到最后一个字符 # 检查是否是第一次执行,如果不是,则设置新的倒计时时间 pass label0 = tk.Label(root, font=("微软雅黑", 10)) label0.config(text="第一次") label0.place(x=10,y=220) minute =tk.Label(root, font=("微软雅黑", 10)) minute.config(text="分钟") minute.place(x=225,y=220) second =tk.Label(root, font=("微软雅黑", 10)) second.config(text="秒钟") second.place(x=405,y=220) minute =tk.Label(root, font=("微软雅黑", 10)) minute.config(text="分钟") minute.place(x=225,y=250) second =tk.Label(root, font=("微软雅黑", 10)) second.config(text="秒钟") second.place(x=405,y=250) disable0 = tk.Label(root, font=("微软雅黑", 10)) disable0.config(text="延时禁用") disable0.place(x=90,y=220) enable0 = tk.Label(root, font=("微软雅黑", 10)) enable0.config(text="延时开启") enable0.place(x=270,y=220) label1 = tk.Label(root, font=("微软雅黑", 10)) label1.config(text="第二次") label1.place(x=10,y=250) disable0 = tk.Label(root, font=("微软雅黑", 10)) disable0.config(text="延时禁用") disable0.place(x=90,y=250) enable0 = tk.Label(root, font=("微软雅黑", 10)) enable0.config(text="延时开启") enable0.place(x=270,y=250) # 初始化变量 disable_countdown=tk.IntVar() disable_countdown.set(8) # 禁用网络的初始倒计时 enable_countdown=tk.IntVar() enable_countdown.set(5) # 启用网络的初始倒计时(仅用于第一次) next_disable_countdown=tk.IntVar() next_disable_countdown.set(80) # 第二次及之后禁用网络的倒计时 next_enable_countdown=tk.IntVar() next_enable_countdown.set(6) # 第二次及之后启用网络的倒计时 def on_value_changed0(): global disable_countdown # 当SpinBox的值改变时,这个函数会被调用 print("当前值:", spinbox0.get()) disable_countdown.set(int(spinbox0.get())) def on_value_changed1(): global enable_countdown # 当SpinBox的值改变时,这个函数会被调用 print("当前值:", spinbox1.get()) enable_countdown.set(int(spinbox1.get())) def on_value_changed2(): global next_disable_countdown # 当SpinBox的值改变时,这个函数会被调用 print("当前值:", spinbox2.get()) next_disable_countdown.set(int(spinbox2.get())) def on_value_changed3(): global next_enable_countdown # 当SpinBox的值改变时,这个函数会被调用 print("当前值:", spinbox3.get()) next_enable_countdown.set(int(spinbox3.get())) spinbox0 = ttk.Spinbox(root, from_=0, to=100, increment=1, command=on_value_changed0,textvariable=disable_countdown,width=8) spinbox0.place(x=150,y=220) spinbox1 = ttk.Spinbox(root, from_=0, to=100, increment=1, command=on_value_changed1,textvariable=enable_countdown,width=8) spinbox1.place(x=330,y=220) spinbox2 = ttk.Spinbox(root, from_=0, to=100, increment=1, command=on_value_changed2,textvariable=next_disable_countdown,width=8) spinbox2.place(x=150,y=250) spinbox3 = ttk.Spinbox(root, from_=0, to=100, increment=1, command=on_value_changed3,textvariable=next_enable_countdown,width=8) spinbox3.place(x=330,y=250) def start_countdown(label, seconds, action): if seconds < 0: return if action == 'disable': text = f"即将禁用网络... 剩余时间: {seconds}秒" elif action == 'enable': text = f"即将启用网络... 剩余时间: {seconds}秒" else: text = f"剩余时间: {seconds}秒" label.config(text=text) root.after(1000, start_countdown, label, seconds - 1, action) def toggle_network_first_time(countdown_label): global disable_countdown global enable_countdown # 第一次的循环逻辑 # start_countdown(countdown_label, 8, 'disable') # 8秒倒计时,提示即将禁用网络 start_countdown(countdown_label, disable_countdown.get()*60, 'disable') # 8秒倒计时,提示即将禁用网络 # root.after(8000, lambda: (disableNet(), start_countdown(countdown_label, 5, 'enable'))) # 禁用网络后,5秒倒计时,提示即将启用网络 # root.after(13000, lambda: (enableNet(), toggle_network_after_first_time(countdown_label))) # 启用网络后,开始后续循环 root.after(disable_countdown.get()*1000*60, lambda: (disableNet(), start_countdown(countdown_label, enable_countdown.get(), 'enable'))) # 禁用网络后,5秒倒计时,提示即将启用网络 root.after(disable_countdown.get()*1000*60+enable_countdown.get()*1000, lambda: (enableNet(), toggle_network_after_first_time(countdown_label))) # 启用网络后,开始后续循环 def toggle_network_after_first_time(countdown_label): global next_disable_countdown global next_enable_countdown # 第二次及以后的循环逻辑 # start_countdown(countdown_label, 10, 'disable') # 10秒倒计时,提示即将禁用网络 start_countdown(countdown_label, next_disable_countdown.get()*60, 'disable') # 10秒倒计时,提示即将禁用网络 # root.after(10000, lambda: (disableNet(), start_countdown(countdown_label, 6, 'enable'))) # 禁用网络后,6秒倒计时,提示即将启用网络 # root.after(17000, lambda: (enableNet(), toggle_network_after_first_time(countdown_label))) # 启用网络后,开始下一次循环 # root.after(next_disable_countdown*1000*60, lambda: (disableNet(), start_countdown(countdown_label, 6, 'enable'))) # 禁用网络后,6秒倒计时,提示即将启用网络 root.after(next_disable_countdown.get()*1000*60, lambda: (disableNet(), start_countdown(countdown_label,next_enable_countdown.get(), 'enable'))) # 禁用网络后,6秒倒计时,提示即将启用网络 root.after(next_disable_countdown.get()*1000*60+next_enable_countdown.get()*1000, lambda: (enableNet(), toggle_network_after_first_time(countdown_label))) # 启用网络后,开始下一次循环 # 倒计时标签 countdown_label = tk.Label(root, font=("微软雅黑", 24)) countdown_label.place(x=20,y=280) # 设置初始文本 countdown_label.config(text="即将开始倒计时...") # 启动第一次的禁用/启用网络循环 def oneClickStart(): root.after(0, lambda: toggle_network_first_time(countdown_label)) button = tk.Button(root, text="禁用网络", command=disableNet,width=10,height=2,background="SlateGray",foreground="white") button2 = tk.Button(root, text="开启网络", command=enableNet,width=10,height=2,background="Navy",foreground="white") button3 = tk.Button(root, text="一键启动",command=oneClickStart ,width=15,height=2,background="IndianRed",foreground="white") button.place(x=10,y=350) button2.place(x=100,y=350) button3.place(x=190,y=350) root.mainloop()
利用的是防火墙的规则,将指定程序 加入出入站规则就可以。要恢复网络,就把规则删除。
for %a in (in out) do netsh advfirewall firewall add rule action=block name="blocked webcast" dir=%a program="{exe_path}"
这里 用的是批处理命令,也就是 cmd 命令,本身就可以将指定程序加入出入站,所以 python在这里使用了subprocess调用了cmd命令,这里看不懂cmd命令没关系,这里因为前面的for命令的关系,%a 的值等于 in 和 out,批量执行了两次,{exepath}是指定的程序绝对路径。 也就是说,上面的代码就相当于下面两次代码。
netsh advfirewall firewall add rule action=block name="blocked webcast" dir=in program="{exe_path}" netsh advfirewall firewall add rule action=block name="blocked webcast" dir=out program="{exe_path}"
这里拿来做实验的是直播伴侣,因为这个程序的安装路径不是固定的,可能不同的机器有人就安装到不同的位置,所以读取了注册表,来获取这个地址
因为注册表这里也没有看到程序实际地址,比如 installPath,只有一个DisplayIcon,是图标的意思,但是这个值确实有程序的实际地址,我们读取出来,把后面的0 去掉就可以,只读取前面部分。
好了,程序运行了怎么知道有没有加入防火墙规则。 可以 电脑 徽标键+R 调出 命令行,输入 firewall.cpl
进入高级设置
就可以看到出入站规则。
点击程序的禁用网络,就会将程序加入出入站的规则,并且禁用他们的上下行流量
要恢复的话,点击启用就会删除规则。启用只需要点击一次就可以,不然会提示错误,因为已经都删除规则了,不能再删第二次,禁用的话可以一直添加多次,但是没意义。一删会全部都删掉。
然后高级的功能就是可以设定倒计时时间来执行启用和禁用网络。第一次设置一个时间,第二次设置一个时间,并且第一次的时间到了,就用第二次的时间来一直循环运行任务。我就不多说了,有点难度,自己看一下代码和注释。
现在我教你打包一下python文件为exe程序,到哪里都可以使用
你需要有一点python基础 和安装了 python 环境 首先 cmd 命令行 输入
pip install auto-py-to-exe
安装好了之后,直接输入 auto-py-to-exe 调出程序界面
最后我的效果是这样的。
png图标地址可以用这个:www.pngsucai.com/
然后再将png 转成 icon,可以用这个地址:www.aconvert.com/cn/icon/png…
最后说明一点,运行这个程序需要管理员权限,就是开启和禁用防火墙那段代码需要管理员权限,你运行的时候鼠标右键有这个选项,【以管理员身份运行】,我就不截图了,因为截不了。 如果你想 打包为exe 之前能管理员权限运行python文件,可以用我这段代码: 新建一个 txt文档, 写入下面代码:
&color a cd %~dp0 python 程序.py pause
然后另存为 比如 x.bat文件,保存类型为所有文件,不是txt文件 编码选择ANSI 就可以
然后右键管理员运行即可。