功能:工作日自动唤醒和睡眠
- 唤醒任务:到点判断是否工作日,是则唤醒睡眠电脑
- 睡眠任务:到点判断是否工作日,是则执行自动睡眠
3. 一键安装/卸载两套任务,日志统一输出
4. 自动调用Windows睡眠指令,仅工作日生效,节假日/周末跳过
完整代码 workday_auto_gui.py
python
import ctypes
import sys
import os
import datetime
import holidays
import win32com.client
import tkinter as tk
from tkinter import ttk, messagebox, scrolledtext
# ===================== 全局配置 =====================
TASK_WAKE_NAME = "真实工作日自动唤醒"
TASK_SLEEP_NAME = "真实工作日自动睡眠"
LOG_TEXT = None
# ====================================================
def is_admin():
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
def run_as_admin():
if not is_admin():
ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
sys.exit(0)
def log(msg):
global LOG_TEXT
time_str = datetime.datetime.now().strftime("%H:%M:%S")
line = f"[{time_str}] {msg}\n"
LOG_TEXT.insert(tk.END, line)
LOG_TEXT.see(tk.END)
LOG_TEXT.update_idletasks()
def is_real_workday(check_date: datetime.date) -> bool:
"""判断真实工作日:区分节假日、调休、周末"""
cn_holiday = holidays.China(years=check_date.year)
desc = cn_holiday.get(check_date, "")
wd = check_date.weekday()
if desc == "节假日":
return False
if desc == "调休":
return True
if 0 <= wd <= 4:
return True
return False
def create_single_task(task_name, hour, minute, wake_flag: bool):
"""
创建单个定时任务
wake_flag=True:唤醒任务,开启WakeToRun
wake_flag=False:睡眠任务,不需要唤醒
"""
run_as_admin()
scheduler = win32com.client.Dispatch("Schedule.Service")
scheduler.Connect()
folder = scheduler.GetFolder("\\")
try:
folder.DeleteTask(task_name, 0)
log(f"已清理旧任务:{task_name}")
except Exception:
log(f"无旧任务:{task_name}")
task_def = scheduler.NewTask(0)
if wake_flag:
task_def.RegistrationInfo.Description = "工作日唤醒:节假日/周末跳过唤醒"
task_def.Settings.WakeToRun = True
else:
task_def.RegistrationInfo.Description = "工作日睡眠:节假日/周末不执行睡眠"
task_def.Settings.WakeToRun = False
task_def.Settings.Enabled = True
task_def.Settings.AllowStartIfMissed = True
# 每周一至周五触发
trigger = task_def.Triggers.Create(12)
now = datetime.datetime.now()
trigger.StartBoundary = f"{now.year}-{now.month:02d}-{now.day:02d} {hour:02d}:{minute:02d}:00"
trigger.DaysOfWeek = 0b11111
trigger.WeeksInterval = 1
trigger.Enabled = True
# 运行本脚本
action = task_def.Actions.Create(0)
py_path = sys.executable
script_path = os.path.abspath(__file__)
if wake_flag:
action.Arguments = f'"{script_path}" wake'
else:
action.Arguments = f'"{script_path}" sleep'
action.Path = py_path
action.WorkingDirectory = os.path.dirname(script_path)
folder.RegisterTaskDefinition(task_name, task_def, 6, "", "", 0)
log(f"创建成功 [{task_name}] 时间:{hour:02d}:{minute:02d}")
def delete_all_task():
"""卸载唤醒+睡眠两套任务"""
run_as_admin()
scheduler = win32com.client.Dispatch("Schedule.Service")
scheduler.Connect()
folder = scheduler.GetFolder("\\")
del_list = [TASK_WAKE_NAME, TASK_SLEEP_NAME]
for name in del_list:
try:
folder.DeleteTask(name, 0)
log(f"已删除任务:{name}")
except Exception:
log(f"未找到任务:{name}")
messagebox.showinfo("完成", "所有定时任务已卸载")
def execute_wake_logic():
"""唤醒分支逻辑"""
today = datetime.date.today()
if is_real_workday(today):
return
else:
sys.exit(0)
def execute_sleep_logic():
"""睡眠分支逻辑:今日工作日则执行睡眠"""
today = datetime.date.today()
if is_real_workday(today):
log(f"今日{today}为工作日,执行自动睡眠")
# Windows睡眠命令
os.system("rundll32.exe powrprof.dll,SetSuspendState 0,1,0")
else:
log(f"今日{today}休息日,跳过睡眠操作")
sys.exit(0)
def check_today_status():
today = datetime.date.today()
res = is_real_workday(today)
if res:
log(f"今日 {today} → 法定工作日,唤醒、睡眠任务都会正常执行")
else:
log(f"今日 {today} → 休息日,到点不会唤醒、也不会自动睡眠")
def gui_main():
global LOG_TEXT
# 区分定时任务自动运行模式
if len(sys.argv) > 1:
if sys.argv[1] == "wake":
execute_wake_logic()
elif sys.argv[1] == "sleep":
execute_sleep_logic()
return
root = tk.Tk()
root.title("工作日自动唤醒&睡眠工具 v2.0")
root.geometry("560x440")
root.resizable(False, False)
# 唤醒设置区
frame_wake = ttk.LabelFrame(root, text="早上唤醒时间")
frame_wake.pack(pady=8, padx=10, fill="x")
ttk.Label(frame_wake, text="小时:").grid(row=0, column=0, padx=8, pady=8)
spin_wake_h = ttk.Spinbox(frame_wake, from_=0, to=23, width=6)
spin_wake_h.grid(row=0, column=1)
spin_wake_h.insert(0, "8")
ttk.Label(frame_wake, text="分钟:").grid(row=0, column=2, padx=12, pady=8)
spin_wake_m = ttk.Spinbox(frame_wake, from_=0, to=59, width=6)
spin_wake_m.grid(row=0, column=3)
spin_wake_m.insert(0, "30")
# 睡眠设置区
frame_sleep = ttk.LabelFrame(root, text="晚间自动睡眠时间")
frame_sleep.pack(pady=8, padx=10, fill="x")
ttk.Label(frame_sleep, text="小时:").grid(row=0, column=0, padx=8, pady=8)
spin_sleep_h = ttk.Spinbox(frame_sleep, from_=0, to=23, width=6)
spin_sleep_h.grid(row=0, column=1)
spin_sleep_h.insert(0, "22")
ttk.Label(frame_sleep, text="分钟:").grid(row=0, column=2, padx=12, pady=8)
spin_sleep_m = ttk.Spinbox(frame_sleep, from_=0, to=59, width=6)
spin_sleep_m.grid(row=0, column=3)
spin_sleep_m.insert(0, "00")
# 按钮区
frame_btn = ttk.Frame(root)
frame_btn.pack(pady=6)
def btn_install_all():
try:
wh = int(spin_wake_h.get())
wm = int(spin_wake_m.get())
sh = int(spin_sleep_h.get())
sm = int(spin_sleep_m.get())
if not (0<=wh<=23 and 0<=wm<=59 and 0<=sh<=23 and 0<=sm<=59):
messagebox.showerror("错误", "时分必须0~23/0~59")
return
create_single_task(TASK_WAKE_NAME, wh, wm, wake_flag=True)
create_single_task(TASK_SLEEP_NAME, sh, sm, wake_flag=False)
messagebox.showinfo("安装完成", f"唤醒:{wh:02d}:{wm:02d}\n睡眠:{sh:02d}:{sm:02d}\n仅法定工作日生效")
except ValueError:
messagebox.showerror("输入错误", "请输入纯数字时间")
ttk.Button(frame_btn, text="一键安装两套任务", command=btn_install_all).grid(row=0, column=0, padx=4)
ttk.Button(frame_btn, text="卸载全部任务", command=delete_all_task).grid(row=0, column=1, padx=4)
ttk.Button(frame_btn, text="检测今日是否工作日", command=check_today_status).grid(row=0, column=2, padx=4)
# 日志框
frame_log = ttk.LabelFrame(root, text="运行日志")
frame_log.pack(pady=10, padx=10, fill="both", expand=True)
LOG_TEXT = scrolledtext.ScrolledText(frame_log, height=12)
LOG_TEXT.pack(padx=5, pady=5, fill="both", expand=True)
root.mainloop()
if __name__ == "__main__":
gui_main()
一、依赖安装(管理员CMD)
bash
pip install holidays pywin32
二、使用说明
1. 双击运行脚本打开GUI
2. 设置两个时间:
- 唤醒时间:早上自动唤醒睡眠电脑(仅工作日)
- 睡眠时间:晚上自动让电脑进入睡眠(仅工作日,周末/节假日不执行)
3. 一键安装两套定时任务;卸载可一次性清除唤醒+睡眠任务
4. 检测今日按钮可预览当天是否会执行唤醒、睡眠
三、自动睡眠原理
脚本被定时触发后:
1. 判断今日是否真实工作日(调班上班算工作日,放假/周末不算)
2. 是工作日:执行Windows系统睡眠命令,电脑立刻休眠
3. 休息日:直接退出,不做任何操作
睡眠命令说明:
rundll32.exe powrprof.dll,SetSuspendState 0,1,0
- 0 = 睡眠(1代表休眠)
- 1 = 忽略弹窗、强制睡眠
- 0 = 不创建休眠文件(普通睡眠)
四、前置必要设置
1. 允许唤醒定时器(唤醒功能必备)
Win+R → powercfg.cpl → 更改高级电源设置 → 睡眠 → 允许唤醒定时器=启用
2. 关闭快速启动(睡眠异常时)
电源选项 → 选择电源按钮功能 → 更改当前不可用设置 → 取消勾选「启用快速启动」
五、关键限制
1. 自动唤醒:仅电脑处于睡眠/休眠有效;完全断电关机无法唤醒(受BIOS硬件限制)
2. 自动睡眠:无论电脑是开机状态,到点只要是工作日都会睡眠,不受断电影响
3. 节假日数据:每年执行 pip install --upgrade holidays 更新放假调休数据
六、补充:区分睡眠/关机
如果你想要定时关机而不是睡眠,把代码里睡眠那行替换成关机命令:
python
# 替换睡眠语句,强制关机
os.system("shutdown /s /f /t 0")