我不善言辞,但还是想教你做个没用的东西
一个可以禁用任意程序的上下行网络的小工具,有倒计时功能
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文档, 写入下面代码:
@echo off &color a
cd %~dp0
python 程序.py
pause
然后另存为 比如 x.bat文件,保存类型为所有文件,不是txt文件 编码选择ANSI 就可以
然后右键管理员运行即可。
好了,今天有没有一点收获呢? 有的话欢迎评论点赞转发收藏,我才有动力多写几篇文章。 下次给你们带来
无人直播软件的制作,日不落下媲美真人的卖场语音直播。
但是人不够多的话,我就不写了。
转载自:https://juejin.cn/post/7386497602193539113