微信无操作自动锁定工具源码

查看 84|回复 9
作者:soullesfox   
最近学业繁忙 软件功能懒得再维护了 有大佬没事可以拿去修改优化
监控微信锁定
说明:  这是一款专门为微信窗口锁定的工具 在有些时候 领导或者同事可能会翻看我们的电脑微信聊天记录 这时候又不想让电脑锁屏运行 这款软件就发挥了巨大的作用 就是先监控 指定时间键盘和鼠标无操作的时候 会自动打开微信使用微信自带的快捷键Ctrl + L自动锁定微信 自己回来了之后只要手机解锁一下就行了
使用教程:  需要先点击检测窗口名 找到微信对应的class类名复制一下  粘贴到窗口名中 空闲时间可以自定义  设置完后点启动监控就可以了 点关闭可以隐藏到任务托盘中
使用python版本: 3.13.0
需要在代码目录下放置一个myicon.ico的图标文件
python代码如下:
[Python] 纯文本查看 复制代码import tkinter as tk
from tkinter import ttk, messagebox
import threading
import time
import ctypes
from ctypes import wintypes
import win32gui
import win32con
from pynput.keyboard import Controller, Key
from PIL import Image, ImageTk
import pystray
import sys
import os
# 全局互斥锁名称
MUTEX_NAME = "WeChatAutoLockTool_Mutex"
# 定义获取系统空闲时间的函数
class LASTINPUTINFO(ctypes.Structure):
    _fields_ = [("cbSize", ctypes.c_uint),
                ("dwTime", ctypes.c_uint)]
def get_idle_duration():
    last_input_info = LASTINPUTINFO()
    last_input_info.cbSize = ctypes.sizeof(LASTINPUTINFO)
    ctypes.windll.user32.GetLastInputInfo(ctypes.byref(last_input_info))
    current_tick = ctypes.windll.kernel32.GetTickCount()
    return (current_tick - last_input_info.dwTime) / 1000.0
# 定义激活目标窗口的函数
def activate_target_window(class_name):
    hwnd = win32gui.FindWindow(class_name, None)
    if hwnd:
        # 移除透明样式(如果存在)
        ex_style = win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE)
        if ex_style & win32con.WS_EX_LAYERED:
            win32gui.SetWindowLong(hwnd, win32con.GWL_EXSTYLE, ex_style & ~win32con.WS_EX_LAYERED)
        
        # 激活并前置窗口
        win32gui.ShowWindow(hwnd, win32con.SW_RESTORE)
        win32gui.SetForegroundWindow(hwnd)
        
        # 强制重绘窗口
        win32gui.RedrawWindow(hwnd, None, None,
                              win32con.RDW_ERASE | win32con.RDW_FRAME | win32con.RDW_INVALIDATE)
        return hwnd  # 返回窗口句柄
    return 0  # 返回0表示未找到窗口
# 定义发送快捷键的函数
def send_ctrl_l():
    keyboard = Controller()
    keyboard.press(Key.ctrl)
    keyboard.press('l')
    keyboard.release('l')
    keyboard.release(Key.ctrl)
   
class IdleMonitorApp:
    def __init__(self, root):
        # ==== 单实例检查 ====
        self.mutex = ctypes.windll.kernel32.CreateMutexW(None, False, MUTEX_NAME)
        last_error = ctypes.windll.kernel32.GetLastError()
        
        # 检测到已有实例运行时
        if last_error == 183:  # ERROR_ALREADY_EXISTS
            self.create_already_running_ui(root)
            return  # 不再继续初始化
        
        # ==== 原有初始化代码 ====
        self.root = root
        self.root.title("微信自动锁定工具")
        self.root.geometry("650x460")  # 增大窗口高度以容纳新控件
        self.root.protocol("WM_DELETE_WINDOW", self.minimize_to_tray)
        # 尝试加载图标
        try:
            myicon_path = os.path.join(os.path.dirname(__file__), "myicon.ico")
            self.root.iconbitmap(myicon_path)
        except:
            pass  # 如果找不到图标则忽略
        
        # 监控状态变量
        self.monitoring = False
        self.stop_event = threading.Event()
        self.idle_threshold_sec = 600  # 默认监控时间600秒
        self.target_window_class = "Qt51514QWindowIcon"  # 默认监控微信窗口
        self.time_lock = threading.Lock()  # 用于线程安全更新阈值
        
        # 创建托盘图标
        self.tray_icon = None
        self.tray_thread = None
        
        # 创建界面
        self.create_widgets()
        
        # 初始状态
        self.update_status("就绪 - 等待启动监控")
        
        # 创建托盘图标
        self.create_tray_icon()
   
    def create_already_running_ui(self, root):
        """创建程序已运行的提示界面"""
        root.title("程序已运行")
        root.geometry("370x200")
        root.resizable(False, False)
        
        # 设置窗口图标
        try:
            myicon_path = os.path.join(os.path.dirname(__file__), "myicon.ico")
            root.iconbitmap(myicon_path)
        except:
            pass
        
        # 主容器框架
        main_frame = ttk.Frame(root, padding=20)
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        # 创建警告图标
        warning_icon = tk.Label(main_frame, text="⚠", font=("Arial", 24), foreground="orange")
        warning_icon.pack(pady=(0, 15))
        
        # 创建提示标签
        label = ttk.Label(main_frame, text="微信自动锁定工具已在运行中!", font=("Arial", 11))
        label.pack()
        
        # 创建详细说明标签
        detail = ttk.Label(main_frame, text="请检查系统托盘图标或使用任务管理器查看运行中的程序",
                          foreground="gray", wraplength=350)
        detail.pack(pady=(5, 15))
        
        # 创建确定按钮
        button_frame = ttk.Frame(main_frame)
        button_frame.pack()
        
        button = ttk.Button(button_frame, text="确定", width=15, command=root.destroy)
        button.pack()
        
        # 窗口居中显示
        self.center_window(root)
   
    def center_window(self, window):
        """使窗口居中显示"""
        window.update_idletasks()
        width = window.winfo_width()
        height = window.winfo_height()
        x = (window.winfo_screenwidth() // 2) - (width // 2)
        y = (window.winfo_screenheight() // 2) - (height // 2)
        window.geometry(f'+{x}+{y}')
   
    def create_widgets(self):
        # 状态标签
        status_frame = ttk.Frame(self.root, padding=10)
        status_frame.pack(fill=tk.X)
        
        self.waPojie_var = tk.StringVar(value="吾爱破解www.52pojie.cn")
        self.waPojie = ttk.Label(status_frame, textvariable=self.waPojie_var,
                                    font=("Arial", 10, "bold"), foreground="red")
        self.waPojie.pack(side=tk.RIGHT, padx=10)
        ttk.Label(status_frame, text="当前状态:").pack(side=tk.LEFT)
        self.status_var = tk.StringVar(value="就绪 - 等待启动监控")
        self.status_label = ttk.Label(status_frame, textvariable=self.status_var,
                                    font=("Arial", 10, "bold"), foreground="blue")
        self.status_label.pack(side=tk.LEFT, padx=10)
        
        # 监控时间设置框架
        threshold_frame = ttk.LabelFrame(self.root, text="监控时间设置", padding=10)
        threshold_frame.pack(fill=tk.X, padx=10, pady=5)
        
        ttk.Label(threshold_frame, text="空闲时间阈值(秒):").grid(row=0, column=0, padx=5, sticky=tk.W)
        
        # 使用IntVar绑定输入框值
        self.threshold_var = tk.IntVar(value=self.idle_threshold_sec)
        self.threshold_entry = ttk.Entry(threshold_frame, textvariable=self.threshold_var, width=8)
        self.threshold_entry.grid(row=0, column=1, padx=5)
        
        # 设置按钮
        set_btn = ttk.Button(threshold_frame, text="设置", command=self.set_threshold)
        set_btn.grid(row=0, column=2, padx=10)
        
        # 添加输入验证,只允许输入数字
        validate_cmd = (self.root.register(self.validate_number), '%P')
        self.threshold_entry.config(validate="key", validatecommand=validate_cmd)
        
        # 当前设置显示
        ttk.Label(threshold_frame, text="当前设置:").grid(row=0, column=3, padx=(20, 5))
        self.cur_threshold_var = tk.StringVar(value=f"{self.idle_threshold_sec}秒")
        ttk.Label(threshold_frame, textvariable=self.cur_threshold_var,
                 font=("Arial", 10, "bold")).grid(row=0, column=4, padx=5)
        
        # 目标窗口设置区域
        window_frame = ttk.LabelFrame(self.root, text="目标窗口设置", padding=10)
        window_frame.pack(fill=tk.X, padx=10, pady=5)
        
        ttk.Label(window_frame, text="窗口类名:").grid(row=0, column=0, padx=5, sticky=tk.W)
        
        # 窗口类名输入框
        self.window_class_var = tk.StringVar(value=self.target_window_class)
        self.class_entry = ttk.Entry(window_frame, textvariable=self.window_class_var, width=25)
        self.class_entry.grid(row=0, column=1, padx=5, sticky=tk.W)
        
        # 测试按钮
        test_btn = ttk.Button(window_frame, text="测试窗口", command=self.test_window_class)
        test_btn.grid(row=0, column=2, padx=10)
        
        # 当前设置显示
        ttk.Label(window_frame, text="当前监控:").grid(row=0, column=3, padx=(20, 5))
        self.cur_window_var = tk.StringVar(value=self.target_window_class)
        ttk.Label(window_frame, textvariable=self.cur_window_var,
                 font=("Arial", 9)).grid(row=0, column=4, padx=5, sticky=tk.W)
        
        # 空闲时间显示
        idle_frame = ttk.Frame(self.root, padding=10)
        idle_frame.pack(fill=tk.X, padx=10)
        
        ttk.Label(idle_frame, text="系统空闲时间:").pack(side=tk.LEFT)
        self.idle_var = tk.StringVar(value="0 秒")
        ttk.Label(idle_frame, textvariable=self.idle_var,
                 font=("Arial", 10)).pack(side=tk.LEFT, padx=10)
        
        # 控制按钮
        btn_frame = ttk.Frame(self.root, padding=20)
        btn_frame.pack(fill=tk.X)
        
        self.start_btn = ttk.Button(btn_frame, text="启动监控",
                                  command=self.start_monitoring)
        self.start_btn.pack(side=tk.LEFT, padx=10)
        
        self.stop_btn = ttk.Button(btn_frame, text="停止监控",
                                 command=self.stop_monitoring, state=tk.DISABLED)
        self.stop_btn.pack(side=tk.LEFT, padx=10)
        
        self.licen_btn = ttk.Button(btn_frame, text="检测窗口名",
                                 command=self.print_all_windows)
        self.licen_btn.pack(side=tk.LEFT, padx=10)
        
        # 日志区域
        log_frame = ttk.LabelFrame(self.root, text="操作日志", padding=10)
        log_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)
        
        self.log_text = tk.Text(log_frame, height=8, state=tk.DISABLED)
        self.log_text.pack(fill=tk.BOTH, expand=True)
        
        scrollbar = ttk.Scrollbar(log_frame, command=self.log_text.yview)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.log_text.config(yscrollcommand=scrollbar.set)
    # 检测窗口
    def print_all_windows(self):
        self.add_log("正在扫描系统窗口...")
        self.add_log("{:= current_threshold:
                self.update_status(f"检测到系统空闲超过{current_threshold}秒,激活目标窗口...")
               
                # 获取窗口句柄
                hwnd = activate_target_window(self.target_window_class)
               
                if hwnd:  # 判断句柄有效性
                    self.update_status("目标窗口已激活,正在发送Ctrl+L快捷键...")
                    time.sleep(1)  # 等待窗口激活
                    send_ctrl_l()
                    
                    # 发送快捷键后最小化窗口
                    win32gui.ShowWindow(hwnd, win32con.SW_MINIMIZE)
                    self.update_status("快捷键已发送,窗口已最小化")
                else:
                    self.update_status(f"未找到类名为 {self.target_window_class} 的窗口")
            
            # 每10秒检查一次,但检查停止标志更频繁
            for _ in range(50):
                if self.stop_event.is_set():
                    break
                time.sleep(0.2)
   
    def minimize_to_tray(self):
        self.root.withdraw()
        self.update_status("程序已最小化到系统托盘")
   
    def show_window(self, icon=None, item=None):
        self.root.deiconify()
        self.root.lift()
        self.root.focus_force()
        self.update_status("窗口已从托盘恢复")
   
    def quit_app(self, icon=None, item=None):
        self.stop_monitoring()
        if self.tray_icon:
            self.tray_icon.stop()
        self.root.destroy()
        os._exit(0)
if __name__ == "__main__":
    root = tk.Tk()
    app = IdleMonitorApp(root)
   
    # 检查是否已退出(由于单实例检查)
    if hasattr(app, 'mutex') and ctypes.windll.kernel32.GetLastError() != 183:
        root.mainloop()

窗口, 时间

xuanmobingxi   

【公告】发帖代码插入以及添加链接教程(有福利)
https://www.52pojie.cn/thread-713042-1-1.html
(出处: 吾爱破解论坛)
qsxls   

感谢分享
liujw1991   

谢谢楼主分享
afti   

感觉用ahk写说不定会更灵活些。
ayow   

这样安全性大大提高,感谢分享
liuxh04   

感谢分享
massagebox   

感谢分享
anan097   

感谢分享
massagebox   

感谢分享
您需要登录后才可以回帖 登录 | 立即注册

返回顶部