]> 小龙服务器 Git - 微信监控/commitdiff
排除最小化窗口+恢复前端检测+日志去重 v3.5
author小龙 <xl@szjxzxh.cn>
Wed, 22 Jul 2026 06:38:15 +0000 (14:38 +0800)
committer小龙 <xl@szjxzxh.cn>
Wed, 22 Jul 2026 06:38:15 +0000 (14:38 +0800)
wechat_auto_login.py

index 92093a5625e29f89a0ff92a32bea8f4bc18ac41d..76c9769203e607b57df5a40a6ad51fe9ea800003 100644 (file)
@@ -362,7 +362,8 @@ try:
     class MonitorApp:
         def __init__(self):
             self.running = True
-            self.monitoring = False
+            START_MONITORING = config.getboolean("General", "start_monitoring", fallback=False)
+            self.monitoring = START_MONITORING
 
             # hash 监测模式状态
             self.hash_mode = False
@@ -372,6 +373,7 @@ try:
             self._last_login_hash = None
             self._user_resized = False
             self._resend_link_sent = False
+            self._last_logged_msg = ""
             self._last_logged_status = ""
 
             self._setup_ui()
@@ -435,6 +437,11 @@ try:
             self.root.after(100, self._main_loop_tick)
             self.root.bind("<Configure>", self._on_window_configure)
 
+            # 同步UI到初始监控状态
+            if self.monitoring:
+                self.toggle_btn.config(text="停用监控", bg="#4CAF50", fg="white")
+                self._set_status("监控运行中")
+                log.info("监控已启用")
 
         # ── info dialog ──
         def _show_info(self):
@@ -519,11 +526,31 @@ try:
         # ── status ──
         def _set_status(self, text):
             self.status_var.set(text)
-            if text != self._last_logged_status:
-                log.info("状态: %s", text)
-                self._last_logged_status = text
             self._update_window_width()
 
+        def _log_state(self, level, msg):
+            """去重日志:连续相同消息不重复记录"""
+            if msg != self._last_logged_msg:
+                if level == "info":
+                    log.info("%s", msg)
+                elif level == "warn":
+                    log.warning("%s", msg)
+                elif level == "error":
+                    log.error("%s", msg)
+                self._last_logged_msg = msg
+
+        def _is_wechat_foreground(self):
+            """检查微信是否在前端(活跃窗口),是则不打断用户操作"""
+            try:
+                fg_hwnd = win32gui.GetForegroundWindow()
+                wechat_wins = _find_wechat_windows()
+                for w in wechat_wins:
+                    if hasattr(w, '_hWnd') and w._hWnd == fg_hwnd:
+                        return True
+            except Exception:
+                pass
+            return False
+
         def _update_window_width(self):
             if self._user_resized:
                 return  # 用户已手动调整窗口,不再自动调整
@@ -547,18 +574,6 @@ try:
             self.root.destroy()
             log.info("程序退出")
 
-        def _is_wechat_foreground(self):
-            """检查微信是否在前端(活跃窗口),是则不打断用户操作"""
-            try:
-                fg_hwnd = win32gui.GetForegroundWindow()
-                wechat_wins = _find_wechat_windows()
-                for w in wechat_wins:
-                    if hasattr(w, '_hWnd') and w._hWnd == fg_hwnd:
-                        return True
-            except Exception:
-                pass
-            return False
-
         # ── main loop (every 5 seconds) ──
         def _main_loop_tick(self):
             if not self.running:
@@ -596,9 +611,13 @@ try:
             # ② 找可见的"微信"窗口
             wechat_windows = _find_wechat_windows()
             visible = [w for w in wechat_windows if w.visible]
-            if not visible:
+            # 排除最小化窗口(最小化到任务栏也算"visible"但实际不可交互)
+            active = [w for w in visible if not win32gui.IsIconic(w._hWnd)]
+            if not active:
                 self._set_status("微信运行中")
                 return
+            # 改用 active 进行后续判断
+            visible = active
 
             # ③ 窗口尺寸判断(零API)
             login_window = None
@@ -610,13 +629,13 @@ try:
             if not login_window:
                 self._set_status("微信运行中")
                 if visible:
-                    log.info("微信已登录(主界面 %dx%d)", visible[0].width, visible[0].height)
+                    self._log_state("info", "微信已登录(主界面)")
                 else:
-                    log.info("微信已登录(主界面,无可见窗口)")
+                    self._log_state("info", "微信已登录(主界面)")
                 return
 
             # ④ 最小化其他窗口
-            # 微信在前端就不最小化,避免打断用户
+            # 微信在登录窗口且在前端时,跳过最小化
             if not self._is_wechat_foreground():
                 _minimize_all_except_wechat()
                 time.sleep(0.3)
@@ -663,7 +682,7 @@ try:
             if not login_window:
                 # 窗口变大了 → 登录成功
                 self._set_status("微信运行中")
-                log.info("微信已登录(窗口变大)")
+                self._log_state("info", "微信已登录(主界面)")
                 if self.hash_mode:
                     self.hash_mode = False
                     self._last_login_hash = None
@@ -685,7 +704,7 @@ try:
             elif result == "B":
                 self.qr_sent_count += 1
                 self._set_status(f"请扫码登录 ({self.qr_sent_count}/{MAX_EMAILS})")
-                log.info("检测到二维码,第 %d 次通知", self.qr_sent_count)
+                self._log_state("info", "检测到二维码")
                 qr_path = os.path.join(tempfile.gettempdir(), f"wechat_qr_{int(time.time())}.png")
                 img.save(qr_path, "PNG")
                 send_qr_email(qr_path)
@@ -737,6 +756,13 @@ try:
             # ③ 查窗口尺寸
             wechat_windows = _find_wechat_windows()
             visible = [w for w in wechat_windows if w.visible]
+            # 排除最小化窗口(最小化到任务栏也算"visible"但实际不可交互)
+            active = [w for w in visible if not win32gui.IsIconic(w._hWnd)]
+            if not active:
+                self._set_status("微信运行中")
+                return
+            # 改用 active 进行后续判断
+            visible = active
             login_window = None
             for w in visible:
                 if w.width < 700 and w.height < 850:
@@ -749,14 +775,16 @@ try:
                 self._last_login_hash = None
                 self.qr_sent_count = 0
                 self._set_status("微信运行中")
-                log.info("微信已登录(主界面),退出哈希监测")
+                self._log_state("info", "微信已登录(主界面)")
                 return
 
             # ④ 截图+哈希比较
-            # 微信在前端就不最小化
+            # 微信在登录窗口且在前端时,跳过最小化
             if not self._is_wechat_foreground():
                 _minimize_all_except_wechat()
                 time.sleep(0.3)
+            else:
+                time.sleep(0.3)
             img = _capture_center()
             new_md5 = _md5_of_image(img)
 
@@ -766,7 +794,7 @@ try:
                 return
 
             # 哈希变了:检查窗口尺寸是否变化
-            log.info("二维码已变化,检查登录状态...")
+            self._log_state("info", "二维码已变化")
             wechat_windows = _find_wechat_windows()
             visible = [w for w in wechat_windows if w.visible]
             still_login = False
@@ -780,7 +808,7 @@ try:
                 self._last_login_hash = None
                 self.qr_sent_count = 0
                 self._set_status("微信运行中")
-                log.info("微信已登录,退出哈希监测")
+                self._log_state("info", "微信已登录(主界面)")
                 return
 
             # 仍然是登录窗口→发通知
@@ -839,7 +867,7 @@ try:
                 self.qr_sent_count = 0
                 self._resend_link_sent = False
                 self._set_status("微信运行中")
-                log.info("微信已登录,退出等待重发模式")
+                self._log_state("info", "微信已登录(主界面)")
                 return
 
             # ② 查flag