From c3b98f4c4e5b0f63c41870f071dbe9687d368c70 Mon Sep 17 00:00:00 2001 From: xiaoxiao_unai Date: Wed, 16 Sep 2026 10:12:49 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=BE=AE=E4=BF=A1=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8C=96=E5=AE=A2=E6=9C=8D(wechatauto-replica)=20=E5=B9=B2?= =?UTF-8?q?=E5=87=80=E5=8E=86=E5=8F=B2=E5=AF=BC=E5=85=A5=20-=20AI=20?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E5=9B=9E=E5=A4=8D/=E8=AF=AD=E9=9F=B3?= =?UTF-8?q?=E6=94=B6=E5=8F=91/=E6=9C=8B=E5=8F=8B=E5=9C=88=E5=8F=91?= =?UTF-8?q?=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 68 + GUIDE.md | 558 +++++ LICENSE | 201 ++ README.md | 224 ++ README.zh-CN.md | 655 ++++++ README_pypi.md | 868 +++++++ diagnose.py | 41 + diagnose_sender.py | 45 + docs/demo_db_files.gif | Bin 0 -> 546546 bytes docs/技术文档.md | 514 ++++ publish_moment_v10.py | 113 + pyproject.toml | 51 + start_ai_reply.bat | 7 + start_engine.bat | 3 + .../LICENSE.txt | 674 ++++++ third_party/ffmpeg_path.txt | 1 + third_party/silk-v3-decoder/silk2mp3.exe | Bin 0 -> 660008 bytes .../silk-v3-decoder/silk_v3_decoder.exe | Bin 0 -> 179037 bytes .../silk-v3-decoder/silk_v3_encoder.exe | Bin 0 -> 318514 bytes verify_reply.py | 31 + voice2text.py | 138 ++ wechat_ai_reply.py | 491 ++++ wechat_daemon.py | 147 ++ wechatauto/__init__.py | 100 + wechatauto/__main__.py | 15 + wechatauto/db.py | 1915 +++++++++++++++ wechatauto/demo.py | 76 + wechatauto/demo_db.py | 97 + wechatauto/demo_emoji_capture.py | 100 + wechatauto/demo_forward_voice.py | 89 + wechatauto/demo_group_messages.py | 356 +++ wechatauto/demo_guia.py | 95 + wechatauto/demo_listen.py | 122 + wechatauto/demo_media.py | 225 ++ wechatauto/demo_reply_at.py | 76 + wechatauto/demo_robust.py | 173 ++ wechatauto/demo_send.py | 193 ++ wechatauto/demo_v109.py | 192 ++ wechatauto/diagnose_keys.py | 175 ++ wechatauto/exceptions.py | 65 + wechatauto/guia.py | 2066 +++++++++++++++++ wechatauto/languages.py | 279 +++ wechatauto/logger.py | 131 ++ wechatauto/media.py | 664 ++++++ wechatauto/moment.py | 811 +++++++ wechatauto/msgs/__init__.py | 81 + wechatauto/msgs/base.py | 285 +++ wechatauto/msgs/friend.py | 112 + wechatauto/msgs/mattr.py | 79 + wechatauto/msgs/msg.py | 140 ++ wechatauto/msgs/mtype.py | 1112 +++++++++ wechatauto/msgs/self.py | 112 + wechatauto/param.py | 75 + wechatauto/py.typed | 0 wechatauto/sender.py | 220 ++ wechatauto/ui/__init__.py | 23 + wechatauto/ui/base.py | 64 + wechatauto/ui/chatbox.py | 400 ++++ wechatauto/ui/component.py | 305 +++ wechatauto/ui/main.py | 268 +++ wechatauto/ui/navigationbox.py | 62 + wechatauto/ui/sessionbox.py | 276 +++ wechatauto/uia/__init__.py | 356 +++ wechatauto/uia_driver.py | 1300 +++++++++++ wechatauto/utils/__init__.py | 34 + wechatauto/utils/lock.py | 127 + wechatauto/utils/tools.py | 340 +++ wechatauto/utils/win32.py | 402 ++++ wechatauto/wx.py | 810 +++++++ 69 files changed, 19828 insertions(+) create mode 100644 .gitignore create mode 100644 GUIDE.md create mode 100644 LICENSE create mode 100644 README.md create mode 100644 README.zh-CN.md create mode 100644 README_pypi.md create mode 100644 diagnose.py create mode 100644 diagnose_sender.py create mode 100644 docs/demo_db_files.gif create mode 100644 docs/技术文档.md create mode 100644 publish_moment_v10.py create mode 100644 pyproject.toml create mode 100644 start_ai_reply.bat create mode 100644 start_engine.bat create mode 100644 third_party/ffmpeg-master-latest-win64-gpl/LICENSE.txt create mode 100644 third_party/ffmpeg_path.txt create mode 100644 third_party/silk-v3-decoder/silk2mp3.exe create mode 100644 third_party/silk-v3-decoder/silk_v3_decoder.exe create mode 100644 third_party/silk-v3-decoder/silk_v3_encoder.exe create mode 100644 verify_reply.py create mode 100644 voice2text.py create mode 100644 wechat_ai_reply.py create mode 100644 wechat_daemon.py create mode 100644 wechatauto/__init__.py create mode 100644 wechatauto/__main__.py create mode 100644 wechatauto/db.py create mode 100644 wechatauto/demo.py create mode 100644 wechatauto/demo_db.py create mode 100644 wechatauto/demo_emoji_capture.py create mode 100644 wechatauto/demo_forward_voice.py create mode 100644 wechatauto/demo_group_messages.py create mode 100644 wechatauto/demo_guia.py create mode 100644 wechatauto/demo_listen.py create mode 100644 wechatauto/demo_media.py create mode 100644 wechatauto/demo_reply_at.py create mode 100644 wechatauto/demo_robust.py create mode 100644 wechatauto/demo_send.py create mode 100644 wechatauto/demo_v109.py create mode 100644 wechatauto/diagnose_keys.py create mode 100644 wechatauto/exceptions.py create mode 100644 wechatauto/guia.py create mode 100644 wechatauto/languages.py create mode 100644 wechatauto/logger.py create mode 100644 wechatauto/media.py create mode 100644 wechatauto/moment.py create mode 100644 wechatauto/msgs/__init__.py create mode 100644 wechatauto/msgs/base.py create mode 100644 wechatauto/msgs/friend.py create mode 100644 wechatauto/msgs/mattr.py create mode 100644 wechatauto/msgs/msg.py create mode 100644 wechatauto/msgs/mtype.py create mode 100644 wechatauto/msgs/self.py create mode 100644 wechatauto/param.py create mode 100644 wechatauto/py.typed create mode 100644 wechatauto/sender.py create mode 100644 wechatauto/ui/__init__.py create mode 100644 wechatauto/ui/base.py create mode 100644 wechatauto/ui/chatbox.py create mode 100644 wechatauto/ui/component.py create mode 100644 wechatauto/ui/main.py create mode 100644 wechatauto/ui/navigationbox.py create mode 100644 wechatauto/ui/sessionbox.py create mode 100644 wechatauto/uia/__init__.py create mode 100644 wechatauto/uia_driver.py create mode 100644 wechatauto/utils/__init__.py create mode 100644 wechatauto/utils/lock.py create mode 100644 wechatauto/utils/tools.py create mode 100644 wechatauto/utils/win32.py create mode 100644 wechatauto/wx.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0e39744 --- /dev/null +++ b/.gitignore @@ -0,0 +1,68 @@ +# Python +__pycache__/ +*.py[cod] +*$py.class + +# Build artifacts +build/ +dist/ +*.egg-info/ +.eggs/ + +# Runtime logs +wxauto_logs/ +@AutomationLog.txt +*.log + +# Virtual environments +.venv/ +venv/ +env/ + +# IDE +.idea/ +.vscode/ +*.swp +COMMIT_MSG.txt + +# sibling repo +WeChatBot-new/ + +# 敏感:API 密钥 / 聊天记录 / 本地数据 +ai_config.json +data/ +kb/ +*.lock + +# 虚拟环境 +.venv_clean/ + +# 调试截图与临时产物 +_debug*.png +_now*.png +snap_*.png +debug_*.png +debug_*.txt +*.wav +*.mp3 +*.bak_* + +# 诊断脚本(一次性) +_check_last_reply.py +_diag_sender*.py +_read_msgs.py +query_default_rec.ps1 + +# 大压缩包 +third_party/*.zip +_test_moment.jpg +_tree_now.txt + +# 调试目录与 ffmpeg 文档 +voice_debug/ +third_party/ffmpeg-master-latest-win64-gpl/doc/ +third_party/ffmpeg-master-latest-win64-gpl/presets/ + +# 大二进制(ffmpeg 等,按需自行下载) +third_party/ffmpeg-master-latest-win64-gpl/bin/*.exe +third_party/silk-v3-decoder/ffmpeg.exe diff --git a/GUIDE.md b/GUIDE.md new file mode 100644 index 0000000..34bbf93 --- /dev/null +++ b/GUIDE.md @@ -0,0 +1,558 @@ +# wechatauto-replica 详细使用指南 / Detailed Usage Guide + +> 面向**微信 4.x Windows 客户端**(非网页版)的自动化库。本文档覆盖从安装、 +> 数据库读取、实时监听、消息发送、媒体下载、朋友圈到多账号与常见问题的 +> 全部用法,并附带可直接运行的示例。 +> +> Automation for the **WeChat 4.x Windows desktop client** (not the web version). +> This guide covers everything: installation, database reading, real-time +> listening, sending, media download, Moments, multi-account, and FAQ — with +> runnable examples throughout. + +--- + +## 目录 / Table of Contents + +1. [安装与准备 / Installation & Setup](#1-安装与准备--installation--setup) +2. [整体架构 / Architecture Overview](#2-整体架构--architecture-overview) +3. [数据库读取 / Database Reading (WeChatDB)](#3-数据库读取--database-reading-wechatdb) +4. [实时消息监听 / Real-time Listening](#4-实时消息监听--real-time-message-listening) +5. [发送消息 / Sending Messages](#5-发送消息--sending-messages) +6. [媒体下载 / Media Download](#6-媒体下载--media-download) +7. [朋友圈 / Moments](#7-朋友圈--moments) +8. [多账号 / Multi-account](#8-多账号--multi-account) +9. [导出聊天记录 / Export](#9-导出聊天记录--exporting-chat-history) +10. [群聊操作 / Group Chat](#10-群聊操作专题--group-chat-operations) +11. [常见问题与排错 / FAQ](#11-常见问题与排错--faq--troubleshooting) +12. [API 速查表 / Quick Reference](#12-api-速查表--api-quick-reference) + +--- + +## 1. 安装与准备 / Installation & Setup + +### 1.1 环境要求 / Requirements + +| 项目 / Item | 要求 / Requirement | +|---|---| +| 系统 / OS | Windows 10 / 11 | +| Python | 3.9+(已在 3.12 验证 / verified on 3.12) | +| 微信 / WeChat | 4.1.12+(数据库读取对版本不敏感 / DB reading is version-insensitive) | +| 登录状态 / Login | 微信必须**已登录**(数据库密钥在进程内存中)/ WeChat must be **logged in** (DB keys live in process memory) | + +### 1.2 安装 / Install + +```bash +pip install wechatauto-replica + +# 发送路径需要额外依赖(OCR 兜底 + 拼音输入)/ Sending path needs extra deps (OCR fallback + pinyin IME): +pip install winsdk pypinyin +``` + +从源码开发 / From source: + +```bash +git clone <仓库地址 / repo> +cd wechatauto-replica +pip install -e . +``` + +### 1.3 验证安装 / Verify + +```python +import wechatauto +print(wechatauto.__version__) # 1.1.5.1 (beta) +``` + +> ⚠️ 首次运行 `WeChatDB()` 会扫描微信进程内存提取数据库密钥,首次约 6 秒, +> 之后密钥缓存到本地,秒开。 +> The first `WeChatDB()` call scans the WeChat process memory to extract DB keys +> (~6s). Keys are cached locally afterwards, so later runs are instant. + +--- + +## 2. 整体架构 / Architecture Overview + +| 能力 / Capability | 技术路线 / Tech | 模块 / Module | +|---|---|---| +| **读消息 / Read** | 本地 SQLCipher 4 数据库解密 / Local SQLCipher 4 DB decryption | `db.py` (WeChatDB) | +| **实时监听 / Listen** | 数据库增量轮询 + 每会话工作线程 / DB incremental polling + per-chat workers | `db.py` (Listener) | +| **发消息 / Send** | UIA 优先,坐标 + OCR 兜底 / UIA-first, coordinate + OCR fallback | `guia.py`, `wx.py` | +| **媒体下载 / Media** | `.dat` AES 解密 / SILK 语音 / 文件复制 / `.dat` AES decrypt / SILK voice / file copy | `media.py` (MediaDownloader) | +| **朋友圈 / Moments** | `sns.db` 直读 + UIA / direct read + UIA | `moment.py` | + +核心对象 / Core objects: + +- `WeChatDB` —— 一切数据读取的入口(解密数据库、查消息、查联系人)/ entry point for all data reading +- `Listener` —— 实时监听器(轮询 + 工作线程)/ real-time listener +- `MediaDownloader` —— 媒体下载 / media download +- `WeChat` / `Chat` —— 面向发送的 wxauto 风格接口 / wxauto-style sending API +- `WeChatGUI` / `quick_send` —— 底层 GUI 驱动与便捷函数 / low-level GUI driver + convenience functions + +--- + +## 3. 数据库读取 / Database Reading (WeChatDB) + +### 3.1 初始化 / Init + +```python +from wechatauto import WeChatDB + +db = WeChatDB() # 自动检测账号与数据目录 / auto-detect account & data dir +# db = WeChatDB(account="wxid_xxx") # 多账号时指定 / specify account for multi-account +``` + +### 3.2 会话(聊天列表)/ Sessions (chat list) + +```python +info = db.get_self_info() # 当前账号信息 / current account info +for s in db.get_sessions(limit=10): # 会话列表 / session list + print(s["username"], s["unread"], s["summary"]) +``` + +`get_sessions()` 返回的 `username` 是**会话唯一标识** / unique session identifier: + +- 私聊 / Private chat:`wxid_xxx` +- 群聊 / Group chat:`xxx@chatroom` + +> ⚠️ 后续所有 API 都认 `username` 而非昵称。可用 `search_contact()` 转换。 +> All APIs take `username`, not nickname. Use `search_contact()` to convert. + +### 3.3 搜索联系人 / Search + +```python +hits = db.search_contact("Ayi") # 按昵称/备注/微信号模糊搜索 / fuzzy search +print(hits[0]["username"]) # -> wxid_xxx 或 xxx@chatroom + +nick = db.get_nickname("wxid_xxx") # 反查昵称 / reverse lookup nickname +``` + +### 3.4 读取消息 / Read messages + +```python +# 最近 N 条(按 sort_seq 降序)/ latest N (sort_seq desc) +msgs = db.get_messages("filehelper", limit=10) +for m in msgs: + print(m["local_id"], m["type"], m["sender_id"], m["content"], m["create_time"]) + +# 单条原始行(媒体下载用,含 server_id / packed_info)/ single raw row +row = db.get_message_row("filehelper", 123) +``` + +消息 dict 字段 / Message dict fields: + +| 字段 / Field | 含义 / Meaning | +|---|---| +| `local_id` | 消息 ID(下载媒体用)/ message ID (media download) | +| `type` | 中文类型:文本/图片/语音/视频/动画表情/文件/系统消息 | +| `sender_id` | 发送者 ID(`2` 表示自己;群聊是成员 ID)/ sender (`2` = self) | +| `content` | 内容(图片等已转换为可读摘要)/ content | +| `create_time` | 时间戳 / timestamp | +| `sort_seq` | 全局排序序号(增量监听用)/ global ordering | + +### 3.5 增量消息(供轮询监听)/ Incremental messages + +```python +new = db.get_new_messages("filehelper", since_seq=12345, limit=200) +``` + +### 3.6 按类型批量取媒体 ID / Batch media IDs + +```python +# 返回该会话全部图片 local_id(不受总消息分页限制)/ all image IDs, ignores msg-limit +img_ids = db._find_media_rows("群名", {3}) +# 类型码 / type codes:1文本 3图片 34语音 43视频 47动画表情 49文件 +# 1 text, 3 image, 34 voice, 43 video, 47 emoji, 49 file +``` + +--- + +## 4. 实时消息监听 / Real-time Message Listening + +两种方式:**db.Listener**(推荐,纯数据库轮询)和 **WeChat.AddListenChat**(wxauto 风格封装)。 +Two ways: **db.Listener** (recommended, pure DB polling) and **WeChat.AddListenChat** (wxauto-style). + +### 4.1 db.Listener(推荐 / recommended) + +```python +from wechatauto import WeChatDB +from wechatauto.db import Listener + +db = WeChatDB() +lst = Listener(db, interval=1.0) # 每秒轮询一次 / poll every second + +def on_msg(msg, lst): + print(f"[{msg['type']}] {msg['sender_id']}: {msg['content']}") + # 可在此扩展业务:关键词回复、媒体下载、通知推送等 / extend here + +lst.add_listener("filehelper", on_msg) # 参数是会话 username +lst.start() # 启动(后台线程)/ background thread +# ... 你的主程序逻辑 / your main logic ... +lst.stop() # 停止 / stop +``` + +**并发模型 / Concurrency model**: + +- 轮询线程只读库 + 分派,不会被慢回调阻塞 / the poller never blocks on slow callbacks +- 每个会话一条独立工作线程:**同会话保序、跨会话并行** / per-chat worker: in-order per chat, parallel across chats +- 慢回调(AI 调用、图片识别)不影响整体监听 / slow callbacks don't affect polling + +**监听无聊天记录的联系人 / Contact with no history**:消息表按需创建,对方发第一条消息后下次轮询即可捕获,只需 `add_listener("wxid_xxx", cb)`。 + +**watermark 持久化 / Watermark persistence**:监听器记录已消费的 `sort_seq`,下次启动可传入避免重复推送。 + +### 4.2 WeChat.AddListenChat(wxauto 风格 / wxauto-style) + +```python +from wechatauto import WeChat +from wechatauto.msgs import TextMessage, ImageMessage + +wc = WeChat() + +def on_msg(msg, chat): + print(f"[{msg.type}] {chat.who}: {msg.content}") + if isinstance(msg, ImageMessage): + md = MediaDownloader(chat._db) + out = md.download_image(chat._wxid, msg.local_id) + +wc.AddListenChat(nickname="群名", callback=on_msg) # 传昵称即可,内部解析 +wc.GetListenMessage() # 阻塞监听循环(Ctrl+C 退出)/ blocking listen loop +# 或 / or wc.KeepRunning() +``` + +`WeChat` 还提供 / also offers: + +```python +wc.GetSession() # 会话列表 / session list [SessionItem] +wc.ChatWith("filehelper") # 切换当前会话 / switch current chat +wc.GetAllSubWindow() # 所有会话窗口 / all chat windows +``` + +--- + +## 5. 发送消息 / Sending Messages + +### 5.1 快速函数 / Quick functions (guia) + +```python +from wechatauto.guia import ( + quick_send, quick_send_file, quick_send_image, quick_reply, +) + +quick_send("你好", "filehelper", verify=True) # 文本,verify=True 从库回读确认 +quick_send_file(r"D:\report.pdf", "filehelper") # 文件 / file +quick_send_image(r"D:\photo.png", "filehelper") # 图片 / image +quick_reply("回复内容", "filehelper", 123) # 回复某条消息 / reply +``` + +### 5.2 WeChat / Chat 对象(wxauto 风格 / wxauto-style) + +```python +from wechatauto import WeChat + +wc = WeChat() +chat = wc.ChatWith("filehelper") # 或 / or Chat("filehelper", wc._gui, wc._db) + +resp = chat.SendMsg("你好") # 发送到当前会话 / send to current chat +resp = chat.SendMsg("大家好", "群名", at=["@张三", "@李四"]) # 群聊 @ 成员 / group @members +resp = chat.SendFiles([r"D:\a.pdf", r"D:\b.docx"]) # 多个文件 / multiple files +``` + +### 5.3 消息对象操作 / Message objects + +```python +msgs = chat.GetAllMessage() # 全部消息 / all messages +new = chat.GetNewMessage() # 新消息 / new messages +last = chat.GetLastMessage() # 最后一条 / last message + +for m in msgs: + print(m.type, m.content, m.sender, m.create_time) +``` + +### 5.4 语音通话 / 拍一拍 / 撤回 / Voice call / Poke / Recall + +```python +chat.VoiceCall() # 语音通话 / voice call +chat.VoiceCall(video=True) # 视频通话 / video call +chat.Poke() # 拍一拍 / poke +chat.RecallLastMessage() # 撤回最近一条自己发的消息 / recall latest own message +``` + +### 5.5 转发语音 / Forward voice + +```python +chat.ForwardVoiceMessage(target="群名") # 从当前会话提取语音转成文件发送 +``` + +### 5.6 发送的验证机制(防误发)/ Anti-misdelivery verification + +`send_msg` 链路带**目标对象三重校验**(UIA 路径)/ triple target verification (UIA path): + +1. `open_chat` 打开后从 UIA 树读回输入框名称比对 / reads back input-box name after opening +2. 发送前确认 `current_chat() == 目标` / confirms current chat is the target +3. `verify=True` 时从数据库回读确认消息落库 / reads back from the DB to confirm + +**目标不在好友/会话列表时安全失败**,不会误发给当前打开的会话(区别于旧版 wxauto3)。 +**If the target isn't in your list, sending fails safely** — never falls back to the current chat. + +--- + +## 6. 媒体下载 / Media Download + +### 6.1 初始化与密钥 / Init & keys + +```python +from wechatauto import WeChatDB, MediaDownloader + +db = WeChatDB() +md = MediaDownloader(db) # 默认保存到 ~/Documents/wechatauto_media +# md = MediaDownloader(db, save_dir=r"D:\media") # 指定保存目录 / specify save dir +``` + +图片 AES 密钥处理 / Image AES key handling: + +```python +md.detect_image_key() # 扫描进程内存提取密钥(首次需要,之后持久化) +# md = MediaDownloader(db, image_key="16位密钥") # 或手动注入 / inject manually +``` + +> ⚠️ 图片 AES 密钥仅在**微信中点开图片查看**时驻留内存约 5 分钟。首次运行请先在 +> 微信里点开任意一张图;`detect_image_key(monitor=True)` 可自动轮询等待;找到后 +> 持久化到 `image_keys.json`,之后无需再扫。 +> The image AES key is only resident while **viewing an image in WeChat** (~5 min). + +### 6.2 下载 API / Download API + +```python +# 按类型自动分发(3图片 34语音 43视频 49文件)/ auto-dispatch by type +out = md.download_media("filehelper", 123, save_dir=r"D:\media") + +out = md.download_image("filehelper", 123) # jpg/png/gif +out = md.download_voice("filehelper", 123) # .silk +out = md.download_video("filehelper", 123) # .mp4 +out = md.download_file("filehelper", 123) # 原文件 / original file +``` + +返回落盘路径,失败返回 `None`。 / Returns the saved path, or `None` on failure. + +### 6.3 群聊图片 / Group chat images + +- 群聊图片原图**只有点开查看过才落盘**;否则只有缩略图 / originals only stored after being opened +- `download_image` 会自动回退缩略图,文件名带 `_thumb` 标记 / auto-falls back to thumbnail (`_thumb`) +- 无 ffmpeg 时 wxgf 格式存为 `.wxgf` 原始数据兜底 / without ffmpeg, wxgf saved as `.wxgf` + +### 6.4 批量下载全部图片 / Batch download all images + +```python +ids = db._find_media_rows("群名", {3}) # 全部图片 ID,不管会话消息总量多大 +for lid in ids: + out = md.download_image("群名", lid) + if out: + print("downloaded:", out) +``` + +命令行也有现成脚本 / There is also a CLI demo: + +```bash +python demo_media.py 群名 --images 100 # 下载该群最近 100 张图片 +python demo_media.py 群名 --images 100000 # 超过总数即全部 / all if > total +python demo_media.py 文件传输助手 --filter 图片,文件 +``` + +--- + +## 7. 朋友圈 / Moments + +```python +from wechatauto import MomentDB + +moments = MomentDB(db) # 基于 sns.db 直读 / direct sns.db reads +for feed in moments.get_moments(limit=10): + print(feed["nickname"], feed["text"]) + print(" images:", [i["md5"] for i in feed["images"]]) + print(" likes:", [l["nickname"] for l in feed["likes"]]) + print(" comments:", [(c["nickname"], c["content"]) for c in feed["comments"]]) +``` + +GUI 交互版(点赞/评论读取)使用 `Moment` 对象,见 `demo` 脚本。 + +--- + +## 8. 多账号 / Multi-account + +```python +from wechatauto import list_accounts, WeChatDB + +accts = list_accounts() # 列出本机所有微信账号 / list all accounts +for a in accts: + print(a) + +db = WeChatDB(account="wxid_xxx") # 指定账号 / pick an account +``` + +--- + +## 9. 导出聊天记录 / Exporting Chat History + +```python +db.export_history( + out_dir=r"D:\export", + out_format="json", # json / sqlite + include_media=True, +) + +for chat in db.list_message_chats(): # 有消息的会话 / chats that have messages + print(chat) +``` + +--- + +## 10. 群聊操作专题 / Group Chat Operations + +### 10.1 获取群信息 / Group info + +```python +info = chat.ChatInfo() # 群成员、群主等 / members, owner, etc. +``` + +### 10.2 群聊发消息并 @ 成员 / Send & @ members + +```python +chat.SendMsg("大家看这个", at=["张三", "李四"]) +# 或指定群 / or +wc.ChatWith("群名") +wc.SendMsg("开会了", at=["全体成员"]) +``` + +### 10.3 群聊监听 / Listen to a group + +```python +lst.add_listener("44054166277@chatroom", on_msg) # 用群 username +``` + +### 10.4 群聊图片 / 语音 / Group images & voice + +```python +md.download_image("群名", local_id) # 自动缩略图回退 / auto thumbnail fallback +md.download_voice("群名", local_id) # 自动搜索所有 media_*.db / searches all media_*.db +``` + +--- + +## 11. 常见问题与排错 / FAQ & Troubleshooting + +### Q1: `RuntimeError: 数据库无可用密钥` / no usable DB key + +- 确认微信**已登录**(密钥在进程内存)/ make sure WeChat is **logged in** +- 确认运行账号有权限读取微信进程(同用户运行)/ run as the same user +- 微信版本差异可能影响内存扫描,升级微信或查看 issue / some versions differ in memory layout + +### Q2: 图片下载失败 / 无法获取 AES 密钥 / image key not found + +- 先在微信里**点开一张图片看大图**,立即重试 / open any image in WeChat first +- 或 `md.detect_image_key(monitor=True)` 持续等待 +- 或手动传 `image_key="16位"` 给 `MediaDownloader` + +### Q3: 群聊图片只有几张 / 很多下不了 / group chat only a few images + +- 群聊图片原图未点开查看时只有缩略图,`download_image` 会自动回退 +- 若要全部,用 `_find_media_rows` + 遍历(6.4),或用 `--images` 参数 + +### Q4: 发送失败 / sending fails + +- 微信窗口需可见(不能锁屏/最小化到托盘)/ window must be visible +- `desktop_available()` 为 False 时发送会安全失败 +- 换用 `verify=True` 获得回读确认 + +### Q5: 语音下载不到 / voice not downloading + +- 1.1.4+ 已支持搜索所有 `media_*.db`(微信分片存储)/ 1.1.4+ searches all media_*.db +- 确认升级到最新版本 / make sure you're on the latest version + +### Q6: 监听无聊天记录的联系人 / contact with no history + +- 消息表按需创建,对方发第一条消息后轮询即捕获 +- 需要知道对方 wxid(用 `search_contact`) + +### Q7: `WeChatAuto` 导入报错 / ImportError + +- 本库入口类是 **`WeChat`**,不存在 `WeChatAuto` +- 教程代码若用旧类名,把 `WeChatAuto()` 换成 `WeChat()` + +--- + +## 12. API 速查表 / API Quick Reference + +### WeChatDB(数据读取 / data) + +| 方法 / Method | 说明 / Description | +|---|---| +| `get_self_info()` | 当前账号信息 / current account info | +| `get_sessions(limit)` | 会话列表 / session list | +| `search_contact(kw)` | 搜索联系人 / search contacts | +| `get_nickname(user)` | 反查昵称 / reverse nickname lookup | +| `get_messages(user, limit, offset)` | 最近消息 / recent messages | +| `get_message_row(user, local_id)` | 单条原始行 / single raw row | +| `get_new_messages(user, since_seq)` | 增量消息 / incremental messages | +| `_find_media_rows(user, types)` | 按类型取全部媒体 ID / all media IDs by type | +| `list_message_chats()` | 有消息的会话 / chats that have messages | +| `export_history(...)` | 导出聊天记录 / export history | +| `list_accounts()` | 列出账号(模块级)/ list accounts (module-level) | + +### Listener(实时监听 / realtime) + +| 方法 / Method | 说明 / Description | +|---|---| +| `add_listener(user, cb)` | 注册回调 / register callback | +| `remove_listener(user, cb)` | 移除回调 / remove callback | +| `start()` / `stop()` | 启停 / start / stop | +| `watermark` | 已消费序号 / consumed seq | + +### MediaDownloader(媒体 / media) + +| 方法 / Method | 说明 / Description | +|---|---| +| `detect_image_key(monitor)` | 提取图片密钥 / extract image key | +| `download_image(user, lid)` | 图片(含缩略图/wxgf 回退)/ image | +| `download_voice(user, lid)` | 语音 .silk / voice | +| `download_video(user, lid)` | 视频 .mp4 / video | +| `download_file(user, lid)` | 原文件 / original file | +| `download_media(user, lid)` | 按类型自动分发 / auto-dispatch by type | + +### WeChat / Chat(发送,wxauto 风格 / sending) + +| 方法 / Method | 说明 / Description | +|---|---| +| `ChatWith(who)` | 切换会话 / switch chat | +| `SendMsg(msg, who, at)` | 发文本(支持群 @)/ send text | +| `SendFiles(paths, who)` | 发文件 / send files | +| `GetAllMessage()` / `GetNewMessage()` | 读消息 / read messages | +| `VoiceCall(video)` | 语音/视频通话 / voice/video call | +| `Poke()` | 拍一拍 / poke | +| `RecallLastMessage()` | 撤回最近消息 / recall latest message | +| `ForwardVoiceMessage(target)` | 转发语音 / forward voice | +| `AddListenChat(nickname, cb)` | 监听(WeChat)/ listen | +| `KeepRunning()` | 阻塞保持运行 / block & stay alive | + +### guia(快捷函数 / convenience) + +| 函数 / Function | 说明 / Description | +|---|---| +| `quick_send(text, who, verify)` | 发文本 / send text | +| `quick_send_file(path, who)` | 发文件 / send file | +| `quick_send_image(path, who)` | 发图片 / send image | +| `quick_reply(text, who, msg_id)` | 回复消息 / reply to a message | + +### 消息对象 / Message objects (msgs) + +`TextMessage` `ImageMessage` `VoiceMessage` `VideoMessage` `FileMessage` +`QuoteMessage` `LinkMessage` `LocationMessage` `SystemMessage` `FriendMessage` `SelfMessage` + +常用属性 / Common attributes:`.type` `.content` `.sender` `.create_time` `.local_id` + +--- + +## 参考 / References + +- [README(英文 / English)](README.md) +- [README(中文 / 中文)](README.zh-CN.md) +- `wechatauto/demo_*.py` —— 各功能的可运行示例 / runnable demos \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..1948288 --- /dev/null +++ b/README.md @@ -0,0 +1,224 @@ +[**English**](README.md) | [**中文**](README.zh-CN.md) + +> [!NOTE] +> **📢 维护状态 / Maintenance Notice** +> 本人因今年升高一,明天(8月23日)报到。开学后几乎没有时间继续更新本项目(如果有时间,争取周日更新)。遇到问题请自行在 Issues 区讨论,或询问 AI 协助解决。感谢支持! +> +> I'm starting senior high school and will register tomorrow (Aug 23). After school starts I'll have almost no time to keep updating (Sundays if possible). Please discuss issues in the Issues section or ask an AI. Thanks for your support! + + +# wechatauto-replica — WeChat 4.x Windows Automation (wxauto-compatible) + +![PyPI version](https://img.shields.io/pypi/v/wechatauto-replica) +![PyPI downloads](https://img.shields.io/pypi/dw/wechatauto-replica) +![Python](https://img.shields.io/pypi/pyversions/wechatauto-replica) +![License](https://img.shields.io/github/license/fanyuantaier/wechatauto-replica) +![GitHub stars](https://img.shields.io/github/stars/fanyuantaier/wechatauto-replica) + +Automate the **WeChat 4.x Windows desktop client** (not the web version): read messages, listen in real time, download media, export full history, read Moments (朋友圈), and send messages — by driving the local client directly. + +> **Current version:** 1.1.7 · Windows 10/11 · Python 3.9+ (verified on 3.12) · WeChat **4.1.12+** +> +> **Why this project exists:** the classic [wxauto](https://github.com/cluic/wxauto) relies on the UI Automation tree, which WeChat 4.x broke with self-drawn rendering (no accessibility nodes). wechatauto-replica is a drop-in-style replacement: messages are read through **local database decryption** (SQLCipher 4), and sending uses a **UIA + OCR hybrid** driver that auto-falls back between engines. + +![Reading encrypted WeChat 4.x databases](docs/demo_db_files.gif) + +*Reading the encrypted `contact.db` / `message_*.db` / `sns.db` files directly from `xwechat_files/.../db_storage/` — no web API, all local.* + +## ✨ Features + +| Capability | Status | How | +|---|---|---| +| Read messages | ✅ verified | Local SQLCipher 4 DB decryption (`wechatauto/db.py`) | +| Real-time message listening | ✅ verified | `Listener` incremental polling, per-chat worker threads | +| Emoji message capture | ✅ verified | Screen capture + direction-aware bubble auto-cropping | +| Full history export | ✅ verified | JSON / SQLite | +| Media download (image / voice / file) | ✅ verified | `MediaDownloader`: image v2 AES decryption, SILK voice, files | +| Moments (朋友圈) read | ✅ verified | Direct `sns.db` reads (3382 feeds verified) | +| Multi-account | ✅ verified | `list_accounts()` + `account=` | +| Send text / file / image / reply / @member | ✅ verified | UIA-first, coordinate + OCR fallback | +| Voice call / Poke (拍一拍) | ✅ verified | UIA buttons + OCR menus | +| UIAutomation tree | ✅ after hot-activation | Writes the Qt accessibility gate inside Weixin.dll | + +## 🚀 Quick Start + +> 📖 **Full usage guide**: [GUIDE.md](GUIDE.md) (中英对照 / bilingual) + +```bash +pip install -e . +# extra deps for the OCR sending path: +pip install winsdk pypinyin +``` + +### Read messages + +```python +from wechatauto import WeChatDB + +db = WeChatDB() # auto-detects account & data dir (WeChat must be logged in) + +info = db.get_self_info() # current account +for s in db.get_sessions(limit=10): # session list + print(db.get_nickname(s["username"]), s["unread"]) + +hits = db.search_contact("Ayi") # search contacts +for m in db.get_messages("filehelper", limit=10): # recent messages + print(m["create_time"], m["sender_id"], m["type"], m["content"]) +``` + +### Send a message + +```python +from wechatauto.guia import quick_send, quick_send_file + +quick_send("Hello", "filehelper", verify=True) # verify=True reads back from DB +quick_send_file(r"D:\report.pdf", "filehelper") +``` + +### Real-time listening + +```python +from wechatauto import WeChatDB +from wechatauto.db import Listener + +db = WeChatDB() +lst = Listener(db, interval=1.0) +lst.add_listener("filehelper", lambda msg, lst: print("new:", msg["content"])) +lst.start() +# ... your code ... +lst.stop() +``` + +Callbacks run on dedicated per-chat worker threads: messages in one chat are processed in order, different chats in parallel; slow callbacks (AI calls, image recognition) never block the poller. + +### Media & Moments + +```python +from wechatauto import WeChatDB, MediaDownloader, MomentDB + +db = WeChatDB() +md = MediaDownloader(db) +md.detect_image_key() # scan process memory for the image AES key (persisted after first hit) +for m in db.get_messages("filehelper", limit=50): + out = md.download_media("filehelper", m["local_id"]) + if out: + print("downloaded:", out) + +moments = MomentDB(db) +for feed in moments.get_moments(limit=10): + print(feed["nickname"], feed["text"]) + print(" images:", [i["md5"] for i in feed["images"]]) + print(" likes:", [l["nickname"] for l in feed["likes"]]) + print(" comments:", [(c["nickname"], c["content"]) for c in feed["comments"]]) +``` + +## 🧠 How It Works + +- **Reading** — WeChat 4.x stores everything in SQLCipher 4 encrypted SQLite databases under `xwechat_files//db_storage/` (`contact.db`, `message_*.db`, `media_0.db`, `sns.db`, …). Each DB has its own 32-byte key living in the Weixin.exe process memory (`com.Tencent.WCDB.Config.Cipher` config objects). The library locates them with a **read-only memory scan**, validates candidates with SQLCipher HMAC rules, decrypts pages to a temp dir and caches the result (first decrypt ~6s, then instant). WAL incremental merging with frame-salt filtering prevents `database disk image is malformed` corruption. +- **Sending** — WeChat 4.x chat UI is self-drawn (no accessibility nodes), so sending uses a hybrid driver: hot-activate the **Qt accessibility gate** inside Weixin.dll (RVA scan, writes the screen-reader flag) to materialize the `mmui::*` UIA tree — search box, `chat_input_field`, etc. Sending is **UIA-first, coordinate + OCR fallback**: auto-calibrating layout (`~/.wechatauto/layout-.json`), zoomed OCR (3x) with multi-round voting for rare Chinese characters, clipboard + Ctrl+V input to dodge IME interception. +- **Media** — image `.dat` files are `[6B sig][4B aes_size][4B xor_size] + AES-ECB + plaintext + xor` chunks. The account-level AES key is transient (only resident in memory while viewing an image); `MediaDownloader` scans for it, validates via JPEG/PNG magic, and **persists it to `image_keys.json`** so later runs need no scanning (or pass `image_key=` explicitly). Voice is plain SILK read from `media_0.db`; files are read from `msg/file/` with original names resolved from `message_resource.db`. + +## ⚖️ vs wxauto + +| | wxauto | wechatauto-replica | +|---|---|---| +| WeChat 4.x | ❌ UIA tree gone → broken | ✅ DB decryption + UIA hot-activation | +| Message reading | via UI tree | via local DB (full history, faster) | +| Sending | UIA clicks | UIA-first + OCR fallback | +| Media | limited | image AES decrypt, SILK voice, files | +| Moments | read | read (posting dropped: self-drawn UI) | + +## ⚠️ Known Limitations + +1. **WeChat must be logged in** — DB keys live in process memory; cached after first extraction, re-extracted automatically after re-login. +2. **Image AES key is transient** — only resident while viewing an image; persisted to `image_keys.json` once found, or inject via `image_key=`. +3. **Sending is a GUI operation** — fails cleanly when the desktop is locked (`desktop_available()` returns False). +4. **Videos** are downloadable only when the mp4 already exists on disk (`msg/video/`). +5. **Group-chat image originals** are stored locally only after being opened (viewed) in WeChat; until then only the thumbnail (`_t.dat`) exists — `download_image` falls back to the thumbnail (marked `_thumb` in the filename). +6. **Moments posting is dropped** (4.x self-drawn UI, unreliable); reading/likes/comments are supported. + +## 🗺️ Roadmap + +- Calibrate and verify file/image/reply/@ sending on unlocked desktops +- Video message download (4.x storage location TBD) +- Performance: parallel export / first-scan, incremental memory-scan cache + +## 📝 Changelog + +### v1.1.7 (2026-08-22) +- **Master-key based key extraction (PR #10, thanks [NothingFumo](https://github.com/NothingFumo))**: instead of scanning process memory for per-DB `Config.Cipher` literals (which fails on WeChat 4.1.12.26+), we now extract the **single master key** from the `cfg` structure (`cfg+0x2B8` cipher XORed with 4×movabs constants from the DLL) and **derive each DB key offline** via `PBKDF2-HMAC-SHA512(master_key, db_salt, 256000)` — 27/27 SQLCipher4 DBs verified. This fixes key extraction on 4.1.12.26+ (issues #3 / #7). +- **Unified image-key pipeline**: template collection (`*_t.dat`, top 16 by mtime) → tail-byte majority XOR (replaces the old single-file probe that could wrongly fall back to `0x88`) → `cfgDword` derivation (deterministic, offline) preferred, with injected/cached/memory-scan AES fallbacks. Probe-verified on 3000/3000 real ciphertexts. +- **Account fields from cfg**: `WeChatDB` now also returns `name` / `number` / `phone` alongside the master key, matching the output format of mainstream key tools. +- New optional params `master_key` / `cfg_dword` are fully backward compatible — if not passed, the original path is used. Core decryption functions unchanged. + +### v1.1.6.3 (2026-08-21) +- **Fix import hang**: `import wechatauto` no longer blocks permanently on systems where `uiautomation` / COM initialization hangs (e.g. WeChat or other Qt apps occupying COM). The `uiautomation` and `comtypes` imports are now deferred — loaded lazily on first UIA access, not at `import wechatauto` time. +- **Fix OCR hang**: `ScreenOCR.recognize` now wraps the WinRT async call in `asyncio.wait_for(..., 8s)` — a hung `Windows.Media.Ocr` async (e.g. Chinese-locale systems) previously blocked `quick_send` forever; it now times out and degrades to empty OCR results. +- **Fix first-run calibrate_layout hang**: `calibrate_layout` now runs each OCR detection step in a daemon thread with a 5-second timeout. Previously, if WinRT OCR hung on a first-run (no layout config), the entire `WeChatGUI.__init__` would block forever; now it times out and falls back to default layout ratios. +- **Support WeChat builds with plaintext-header (key+salt) DBs**: key extraction now accepts SQLCipher 4 "Raw Key with Explicit Salt" form (`x'<96hex>'` = 32B key + 16B explicit salt, used with `cipher_plaintext_header_size`). A 48-byte key (32B key + 16B salt) is verified and decrypted in plaintext-header layout (page-1 keeps its plaintext header); a 32-byte key keeps the standard file-header-salt path. This unblocks DB decryption on builds where the old offsets point at the class-name table instead of the Cipher instance (e.g. a 4.1.12.26 environment). +- **Fix `wxid_*` hardcoding**: account discovery no longer assumes directories start with `wxid_` — any subdirectory of `db_dir` containing `db_storage/` is recognized. This supports custom WeChat IDs (e.g. user-chosen usernames that don't use the `wxid_` prefix). +- **Listen to all messages**: `WeChat.AddListenAll(callback)` now monitors ALL sessions (friends, groups, file transfer, etc.) with a single call, including auto-discovery of new sessions. `WeChat.RemoveListenAll()` stops it. The callback receives `(Message, Chat)` where `Chat.who` is the session username. + +### v1.1.6.1 (2026-08-20) +- **PyPI description fix**: v1.1.6 was uploaded without the synced `README_pypi.md` (description still showed 1.1.5.1); this patch restores the full v1.1.6 changelog and bumps the version marker. + +### v1.1.6 (2026-08-20) +- **Auto-diagnosis on missing key**: `数据库无可用密钥` now runs a built-in check before raising — Python bitness (32-bit can't read 64-bit Weixin memory), per-PID `OpenProcess`/`ReadProcessMemory` permission, and multi-account mismatch (all `wxid_*` dirs vs. picked account, suggesting `WeChatDB(account=...)`). No need to run `diagnose_keys` first. +- **New diagnostic tool**: `wechatauto/diagnose_keys.py` (`python -m wechatauto.diagnose_keys`, WeChat logged in) dumps lib version, Python bitness, Weixin PIDs with per-process read-permission checks, all accounts vs. picked account, cached keys, fresh in-memory extraction, and key verification — paste the output when reporting key-extraction failures. +- **Skip `migrate\unspportmsg.db`**: WeChat's reserved "unsupported message" DB has no in-memory key and is never queried; it was forcing a full process-memory scan on every init. + +### v1.1.5.1 (2026-08-18) — beta +- **Fix real-time listening**: `WeChatDB.get_new_messages()` referenced an undefined `found` (NameError swallowed by `Listener._poll_once`), so **no** message callbacks ever fired — including first messages from contacts you had never chatted with. +- **Dynamic message shards**: `_message_dbs()` now re-scans the disk so shards WeChat creates at runtime (e.g. `message_5.db`) are picked up and their keys extracted automatically. + +### v1.1.5 (2026-08-18) +- **Version cleanup**: normalized the patch version (1.1.4.2 → 1.1.5) after the `media_*.db` voice fix. + +### v1.1.4.2 (2026-08-18) +- **PyPI description cleanup**: removed the demo default-group changelog line from the PyPI description. + +### v1.1.4.1 (2026-08-18) +- **PyPI readme bilingual**: merged the Chinese (`README.zh-CN.md`) and English (`README.md`) into one PyPI description so the Chinese version is visible on the package page. + +### v1.1.4 (2026-08-18) +- **Voice download across all media databases**: `download_voice()` now searches every `media_*.db` (not just `media_0.db`) — WeChat shards voice data across multiple media DBs; previously voices stored in `media_1.db` etc. could not be found (thanks uiharukazari0105). +- **`demo_media.py --images N`**: download the latest N images of a chat directly from the DB (by local_type), bypassing the total-message `--limit` — no more "only a few images listed" when a group has thousands of messages. +- **`WeChatDB._find_media_rows(user, types)`**: new helper returning all media local_ids of a chat for a set of local_types (batch download). +- **Group-chat image thumbnail fallback**: original images in group chats are only downloaded after being opened in WeChat; `download_image` now falls back to the thumbnail (`_t.dat`) when the original is missing, saving it with a `_thumb` suffix. + +### v1.1.3 (2026-08-17) + +### v1.1.2 (2026-08-16) +- **UIA driver thread-safety**: `WeChatUIA` now initializes COM on the current thread (`CoInitializeEx`, idempotent) — fixes crashes when instantiated from background threads / host apps (e.g. WeChatBot) with "CoInitialize not called / cannot load UIAutomationCore.dll" errors. +- **Main-window filtering**: only windows whose process loaded `Weixin.dll` are considered — auxiliary processes without the DLL (whose hot-activation always fails) no longer produce noise warnings. +- **Forward-voice fix**: `Chat.ForwardVoiceMessage` uses `self` when no target is given (the previous `_cur()` could resolve the wrong chat). +- **Re-entrant UI lock**: `LockManager` is now re-entrant per thread — `@uilock` functions calling each other (e.g. `ForwardVoiceMessage` → `VoiceMessage.forward_to`) no longer deadlock. + +### v1.1.1 (2026-08-16) +- **Recall last message** (`Chat.RecallLastMessage` / `uia_driver.recall_last_message`): right-click the latest own message → UIA-first menu-item click (`mmui::XMenuView` found inside the main-window subtree), OCR fallback; fails cleanly when the 2-minute recall window has passed (menu only shows "Delete"). +- UIA robustness: menu-item lookup scoped to the main-window subtree (avoids the Windows UIA root-traversal hang), removed the fragile `WindowControl(ClassName=...)` fallback. +- Media fix: video id bytes→str decoding in `MediaDownloader`. +- `demo_media.py --photos` default 3 → 10. + +### v1.1.0 (2026-08-15) +- **Image AES key auto-capture** (`media.py`): the V2 image key is only resident in memory while viewing an image (~5 min). `_scan_aes_key()` gained a `monitor` mode — polls continuously and persists the key to `image_keys.json` once found; users just open one image to finish setup. +- Fixed the process-ordering scan bug (removed the memory-usage sort that pushed the main process last). +- **Forward voice messages**: SILK extraction from `media_0.db` + file-message send (`demo_forward_voice.py`). +- New demos: `demo_group_messages.py` (group + red-packet ZSTD parsing), `demo_robust.py`. + +## 🤝 Acknowledgments + +Thanks to [vesio](https://github.com/vesio) for sharing the WeChat 4.1.12 UIA control-tree approach and debugging ideas in [issue #1](https://github.com/fanyuantaier/wechatauto-replica/issues/1) — it made the UIA hybrid driver (v1.0.8) possible. + +Thanks to [nanshanjack](https://github.com/nanshanjack) for finding the UI-lock re-entrancy problem (fixed in v1.1.2). + +Thanks to [maozhitao12450](https://github.com/maozhitao12450) for reporting the WXAM (wxgf) image download issue (fixed in v1.1.3). + +Thanks to [uiharukazari0105](https://github.com/uiharukazari0105) for finding that voice data stored in `media_1.db` (and later) was never searched (fixed in v1.1.4). +Thanks to [NothingFumo](https://github.com/NothingFumo) for the master-key extraction design (cfg + PBKDF2-derived per-DB keys, v1.1.7). + +## 📄 License & Disclaimer + +Apache-2.0. This project is for personal learning and automation research only — please respect the WeChat software license agreement and applicable laws. + +Contact: fanyuantaier@163.com diff --git a/README.zh-CN.md b/README.zh-CN.md new file mode 100644 index 0000000..2a98fa7 --- /dev/null +++ b/README.zh-CN.md @@ -0,0 +1,655 @@ +[**English**](README.md) | [**中文**](README.zh-CN.md) + +> [!NOTE] +> **📢 维护状态 / Maintenance Notice** +> 本人因今年升高一,明天(8月23日)报到。开学后几乎没有时间继续更新本项目(如果有时间,争取周日更新)。遇到问题请自行在 Issues 区讨论,或询问 AI 协助解决。感谢支持! +> +> I'm starting senior high school and will register tomorrow (Aug 23). After school starts I'll have almost no time to keep updating (Sundays if possible). Please discuss issues in the Issues section or ask an AI. Thanks for your support! + + +# wechatauto —— 微信 4.x Windows 客户端自动化(wxauto 复刻版) + +![PyPI version](https://img.shields.io/pypi/v/wechatauto-replica) +![PyPI downloads](https://img.shields.io/pypi/dw/wechatauto-replica) +![Python](https://img.shields.io/pypi/pyversions/wechatauto-replica) +![License](https://img.shields.io/github/license/fanyuantaier/wechatauto-replica) +![GitHub stars](https://img.shields.io/github/stars/fanyuantaier/wechatauto-replica) + + +本项目复刻上游 wxauto 项目,目标是实现对当前微信 4.x Windows 客户端的自动化 +(读取消息、发送消息、媒体下载、朋友圈),非网页版,直接操作本机客户端。 + +> 当前版本:1.1.7 +> +> **兼容范围**:Windows 10/11 | Python 3.9+(已在 3.12 验证)| 微信 **4.1.12+** +> (数据库读取路线对微信版本不敏感;坐标+OCR 发送路线依赖 4.1.12+ 自绘渲染 +> 布局,其它 4.x 小版本可能需校准 `guia.py` 布局常量)。 + +![解密读取微信 4.x 加密数据库](docs/demo_db_files.gif) + +*直接解密读取 `xwechat_files/.../db_storage/` 下的 `contact.db` / `message_*.db` / `sns.db` 加密库——纯本地,无 Web API。* + +--- + +## 🤝 致谢 + +> 感谢 [vesio](https://github.com/vesio) 在 [issue #1](https://github.com/fanyuantaier/wechatauto-replica/issues/1) 提供微信 4.1.12 的 UIA 控件树代码与思路,促成了 v1.0.8 的 UIA 混合驱动。 +> +> 感谢 [nanshanjack](https://github.com/nanshanjack) 发现 UI 锁的可重入问题(v1.1.2 修复)。 +> +> 感谢 [maozhitao12450](https://github.com/maozhitao12450) 报告 WXAM (wxgf) 图片下载问题(v1.1.3 修复)。 +> +> 感谢 [uiharukazari0105](https://github.com/uiharukazari0105) 发现语音数据分片存储(`media_1.db` 等)从未被搜索的问题(v1.1.4 修复)。 +感谢 [NothingFumo](https://github.com/NothingFumo) 提出主密钥提取方案(cfg + PBKDF2 派生逐库密钥,v1.1.7)。 + +--- + +## 版本记录 + +### v1.1.7(2026-08-22) + +- **基于主密钥的密钥提取(PR #10,感谢 [NothingFumo](https://github.com/NothingFumo))**:不再依赖进程内存中逐个库的 `Config.Cipher` 字面量扫描(微信 4.1.12.26+ 已失效),改为从 `cfg` 结构提取**单一主密钥**(`cfg+0x2B8` 密文 ⊕ DLL 中 4×movabs 常量),再通过 `PBKDF2-HMAC-SHA512(主密钥, 库salt, 256000)` **离线派生各库独立密钥**——27/27 个 SQLCipher4 数据库实测验证通过。解决 4.1.12.26+ 密钥提取失效(issue #3 / #7)。 +- **图片密钥统一流程**:模板收集(`*_t.dat`,按 mtime 取前 16)→ 尾字节众数统计 XOR(替代原单文件探测误回退 `0x88` 的缺陷)→ 优先 `cfgDword` 派生(确定性、离线),注入/缓存/内存扫描 AES 兜底。3000/3000 真实密文探针验证通过。 +- **cfg 同步返回账号字段**:`WeChatDB` 现在随主密钥一起返回 `name` / `number` / `phone`,与主流密钥工具输出格式逐字段对齐。 +- 新参数 `master_key` / `cfg_dword` 全部可选、完全向后兼容——不传则走原路径。核心解密函数零改动。 + +### v1.1.6.3(2026-08-21) + +- **修复导入卡死**:`import wechatauto` 不再在部分系统上永久阻塞(如微信或其他 Qt 应用占用 COM 导致 `uiautomation` / COM 初始化挂起)。`uiautomation` 和 `comtypes` 现在延迟导入——首次访问 UIA 功能时才加载,不在 `import wechatauto` 时触发。 +- **修复 OCR 挂起**:`ScreenOCR.recognize` 的 WinRT 异步调用现在用 `asyncio.wait_for(..., 8s)` 包住——`Windows.Media.Ocr` 异步永不完成(如中文系统环境)时,此前会让 `quick_send` 永久挂起;现在 8 秒超时后降级为空 OCR 结果。 +- **修复首次校准卡死**:`calibrate_layout` 的每个 OCR 检测步骤现在用守护线程 + 5 秒超时。此前首次运行(无布局配置文件)时 WinRT OCR 若挂起,整个 `WeChatGUI.__init__` 会永久阻塞;现在超时后回退使用默认布局比例。 +- **支持明文头(key+salt)微信构建的库解密**:密钥提取现在接受 SQLCipher 4 的 "Raw Key with Explicit Salt" 形式(`x'<96hex>'` = 32 字节 key + 16 字节显式 salt,配合 `cipher_plaintext_header_size` 使用)。48 字节密钥(32B key + 16B salt)按明文头布局验证与解密(页 1 保留其明文头);32 字节密钥保持标准文件头 salt 路径。这解除了部分构建上因旧偏移指向类名表而非 Cipher 实例(如 4.1.12.26 环境)而无法解密库的问题。 +- **修复 `wxid_*` 硬编码**:账号发现不再假设目录以 `wxid_` 开头——`db_dir` 下任何含 `db_storage/` 子目录的子目录都会被识别。这支持自定义微信号(如用户手动修改、不含 `wxid_` 前缀的账号)。 +- **全局消息监听**:`WeChat.AddListenAll(callback)` 现在一次监听所有会话(好友、群聊、文件传输助手等),支持自动发现新会话。`WeChat.RemoveListenAll()` 停止全局监听。回调签名为 `(Message, Chat)`,其中 `Chat.who` 为会话原始 username。 + +### v1.1.6.1(2026-08-20) + +- **PyPI 描述修复**:1.1.6 发布时漏同步 `README_pypi.md`(描述停留在 1.1.5.1),本补丁版补全 v1.1.6 更新记录并同步版本号。 + +### v1.1.6(2026-08-20) + +- **缺密钥报错自动诊断**:`数据库无可用密钥` 报错前会自动检测三项最常见根因——Python 位数(32 位读不了 64 位微信内存)、逐个微信进程的 `OpenProcess`/`ReadProcessMemory` 读取权限、多账号目录与所选账号对比(提示用 `WeChatDB(account=...)` 显式指定),无需先手动运行 `diagnose_keys`。 +- **新增诊断工具**:`wechatauto/diagnose_keys.py`(微信登录后运行 `python -m wechatauto.diagnose_keys`)输出库版本、Python 位数、微信进程 PID 及逐个进程的读取权限检测、磁盘全部账号与所选账号对比、已缓存密钥、进程内存重新提取结果与密钥校验情况——报密钥提取问题时把输出完整发给维护者即可定位。 +- **跳过 `migrate\unspportmsg.db`**:该库是微信保留的「未支持消息」库,进程内存中无对应密钥、代码也从不会访问;此前它会让每次初始化都触发一次全进程内存扫描。 + +### v1.1.5.1(2026-08-18)— 测试版 / beta + +- **修复实时监听不触发**:`WeChatDB.get_new_messages()` 引用了未定义的 `found`(NameError 被 `Listener._poll_once` 吞掉),导致消息回调从未触发——包括从未聊过天的联系人的首条消息。 +- **动态消息分片**:`_message_dbs()` 现在会重新扫描磁盘,微信运行中新建的分片(如 `message_5.db`)会被自动发现并提取密钥。 + +### v1.1.5(2026-08-18) + +- **版本号规范化**:语音跨库下载修复后整理补丁版本号(1.1.4.2 → 1.1.5)。 + +### v1.1.4.2(2026-08-18) + +- **PyPI 描述清理**:移除 v1.1.4 版本记录中关于 demo 默认群改动的条目。 + +### v1.1.4.1(2026-08-18) + +- **PyPI 页面中英双语**:PyPI 描述合并中文(`README.zh-CN.md`)与英文(`README.md`)两个版本,中文版在包页面可见。 + +### v1.1.4(2026-08-18) + +- **跨全部媒体库下载语音**:`download_voice()` 现在搜索所有 `media_*.db`(不再只查 `media_0.db`)——微信把语音分片存到多个媒体库;此前存在 `media_1.db` 等的语音无法找到(感谢 uiharukazari0105)。 +- **群聊图片缩略图回退**:群聊的图片原图只有被点开(查看)后才会落盘本地;原图未点开不下发时,`download_image` 自动回退到缩略图(`_t.dat`),保存为带 `_thumb` 后缀的文件。 +- **`WeChatDB._find_media_rows(user, types)`**:新增批量查媒体接口——返回某会话指定 `local_type` 集合的全部媒体 `local_id`(用于批量下载)。 +- **`demo_media.py --images N`**:按 `local_type` 直接从数据库下载某会话最近 N 张图片,绕过总消息数 `--limit` 的限制——群聊消息上万条时不再「只列出几张图」。 + +### v1.1.3(2026-08-17) + +- **WXAM (wxgf) 图片解码**:微信 4.x 现在把**普通图片**(不仅是动图贴纸)也存进 WXAM 容器 + (内部为 HEVC 比特流)。`MediaDownloader.download_image` 新增 wxgf 处理:提取 HEVC + Annex-B 流,用 ffmpeg 转码为 JPG(优先用 `imageio-ffmpeg` 内置二进制,其次 PATH 上的 + ffmpeg);ffmpeg 不可用时不再丢弃数据,改为保存原始解密数据为 `.wxgf` 兜底。 +- 新增依赖:`imageio-ffmpeg>=0.4.9`。 + +### v1.1.2(2026-08-16) + +- **UIA 驱动线程安全**:`WeChatUIA` 实例化时在当前线程初始化 COM(`CoInitializeEx`,幂等)——修复后台线程/宿主进程(如 WeChatBot)实例化报「尚未调用 CoInitialize / 无法加载 UIAutomationCore.dll」。 +- **主窗口过滤**:只认加载了 `Weixin.dll` 的主进程窗口,过滤无 DLL 的辅助进程窗口(其热激活必然失败,不再刷噪音警告)。 +- **转发语音修复**:`Chat.ForwardVoiceMessage` 未指定目标时用 `self`(原 `_cur()` 可能误取会话)。 +- **UI 锁可重入**:`LockManager` 同线程可重入——`@uilock` 函数互相调用(如 `ForwardVoiceMessage` → `VoiceMessage.forward_to`)不再死锁。 + +### v1.1.1(2026-08-16) + +- **撤回消息**(`Chat.RecallLastMessage` / `uia_driver.recall_last_message`):右键最新一条自己发的消息 → UIA 优先 + (主窗口树内 `mmui::XMenuView` 菜单项定位「撤回」,Invoke/Select 或鼠标点击),OCR 兜底(全屏识别「撤回」 + 文字定位点击);菜单只剩「删除」(超过 2 分钟撤回时限)时返回失败。 +- **UIA 健壮性**:菜单项查找限定在主窗口子树内(避免触发 Windows UIA 根遍历的系统挂起 bug);移除脆弱的 + `WindowControl(ClassName=...)` 兜底定位。 +- **媒体修复**:视频 id bytes→str 解码(`MediaDownloader`),修复视频文件定位。 +- `demo_media.py` `--photos` 默认 3 → 10。 + +### v1.1.0(2026-08-15) + +- **图片 AES 密钥自动监控捕获**(`media.py`):微信 4.x 的 V2 图片 AES 密钥仅在 + 查看图片大图时短暂驻留进程内存(实测约 5 分钟后释放)。`_scan_aes_key()` 新增 + `monitor` 模式——首次扫描未命中时自动持续轮询并提示去微信点开一张图片看大图, + 密钥进入内存后自动捕获并持久化到 `image_keys.json`,之后免扫描直接解密。 + 首次用户无需手工找密钥,看图一次即可完成配置。 +- **修复进程排序扫描 bug**:移除 `_scan_aes_key` 中按内存占用排序进程的逻辑 + (`GetProcessMemoryInfo` 结构体大小传错导致工作集全为 0,`reverse` 排序反而把 + 主进程排到最后,错过密钥驻留窗口),恢复按微信进程原顺序扫描(主进程优先命中)。 +- **语音/视频/文件不受影响**:仅图片 `.dat` 为 V2 AES 加密需密钥;语音(SILK)、 + 视频(MP4)、文件均为明文直接读取。 + +### v1.0.9(2026-08-14) + +- **open_chat 账号/微信号搜索修复**(`uia_driver.py`):微信搜索框不认 wxid + (系统账号),`open_chat` 传入 username 时自动通过本地 DB 映射为昵称/备注/ + 微信号再搜索(`_resolve_search_keyword`),并清空搜索框残留重试; + 实测 `open_chat('wxid_sb9or2x9zxj012')` 成功。 +- **UIA 表情包精确读取**(`msgs/mtype.py` + `uia_driver.py`):热激活后消息 + 列表暴露 `mmui::RecyclerListView`,新增 `find_in_message_list()` 用鼠标滚轮 + 驱动虚拟化列表滚动,按 ClassName/Name 定位表情行并取 BoundingRectangle + 精确坐标;`EmojiMessage.capture()` 优先走 UIA 定位 + 方向感知气泡裁剪 + (`_crop_bubble_from_row`),实测 1.1s 裁出 271×271 表情,替代原先 + 「截图全消息区 + 连通域猜气泡」的脆弱方案;失败自动回退原连通域逻辑。 +- **语音通话**(`uia_driver.voice_call` + `Chat.VoiceCall`):标题栏暴露 + `mmui::ChatVoIPView.voip_button`(Name=语音通话),控件树动态重建需重试 + 定位;video=True 尝试找视频通话按钮(当前版本未暴露,通常失败)。 +- **拍一拍**(`uia_driver.poke` + `Chat.Poke`):微信 4.x 拍一拍只能通过 + 右键对方头像触发,菜单为自绘不暴露 UIA;实现为「内容重心定位 friend + 消息行 → 右键头像 → 全屏 OCR 定位「拍一拍」→ 点击」,实测 3.2s 发出 + (网络正常时对方收到,网络异常时微信显示失败提示,链路本身正确)。 +- `EmojiMessage.capture()` / `voice_call` / `poke` 失败均自动回退或返回 + WxResponse 失败,不影响既有 OCR 发送路径。 + +### v1.0.8(2026-08-13) +- 🎉 **特别感谢 [vesio](https://github.com/vesio)**:在 issue #1 中提供了微信 4.1.12 可出 UIA 控件树的代码与调试思路,本版 UIA 混合驱动由此而来; +- **UIA 混合驱动**(`uia_driver.py`,微信 4.1.12.26 实测): + - 新增 `WeChatUIA` 引擎:冷启动时 `Qt51514QWindowIcon` 只是空壳(Qt + 无障碍门未激活),通过写 Weixin.dll 内的 Qt accessibility gate + (RVA 扫描定位)**热激活**后,锚点变为 `mmui::MainWindow`,搜索框 + `mmui::XValidatorTextEdit` / 搜索下拉 `search_list` / 输入框 + `chat_input_field` 全部可用; + - 发送链路全部走 UIA:搜索下拉选人(`search_item_*`)打开会话 → + `chat_input_field` 直接输入 + 回车发送,`current_chat` 校验防误配, + 无 OCR 抖动;Windows 冷状态热激活后 UIA 树保持可用; + - `guia.py` 集成混合路径:`_get_uia()` 惰性启用,`open_chat` / + `send_msg` **UIA 优先、OCR 兜底**——UIA 树不可用(版本变更新增 RVA) + 或失败时自动降级到坐标 + 放大 OCR 方案,首次失败本次会话内不再重试。 + - 实测:`send_msg('文件传输助手')` 10.2s、`send_msg('卢立竺')` 13.2s + 均走 UIA 并数据库确认成功(含 verify);UIA 对生僻字会话名不再依赖 + OCR 识别。 +- 新增依赖:`uiautomation`(UIA 客户端库)。 + +### v1.0.7(2026-08-13) + +- **OCR 识别可靠性提升**(`guia.py`,针对生僻字/小字号会话名识别失败): + - 新增 `ocr_zoomed()`:对区域放大 N 倍后再 OCR,坐标按 1/N 还原;实测 + 微信小字号中文在放大 3 倍时识别率最高(放大 6 倍图像过大反而整块 + 返回空),超过 5 倍即回落; + - `_chat_is_open` 标题检测改用放大 3 倍 + y 范围扩到 0-185(微信 4.x + 标题实际渲染在 y≈80-180,原 15-100 的区间会漏检已打开的会话); + - `_search_chat` 搜索回退排除「群聊」节标题以下行、含「包含」的群成员 + 预览行(如「00,包含:卢立竺」)与群名结尾行,只点联系人,修复 + 「搜索选中群聊而非联系人」的问题; + - `_chat_open_confirmed` 改为**优先标题命中**,标题读不到才退而用面板 + 非空白作为已打开判据,修复「点错会话也误判成功」; + - `open_chat` 首查 `_chat_is_open && _pane_has_content`,右侧面板已打开 + 目标会话时直接成功(不再滚动/搜索),已打开场景耗时 45s → 2.7s。 +- **OCR 多轮投票**(`find_session._scan_vote`):WinRT OCR 对生僻字存在 + 抖动(同一行不同轮次可能读出「卢立竺」或「亠人五」)。对侧栏放大 3x + 扫描 4 轮,命中行按 y 聚类(≤30px 视为同行),票数 ≥2 才返回,显著 + 降低误配;普通会话仍走单轮快速路径,无性能损失。 +- 实测:`find_session('卢立竺')` 连续 5 轮 4/4 票一致、稳定命中; + `open_chat` + `send_msg` 全链路成功。 + +### v1.0.6(2026-08-11) + +- **元数据与门面优化**:README 增加徽章(PyPI 版本/下载量/Python 版本/License/Stars)、PyPI description/keywords/classifiers SEO 优化、Homepage 修正为项目 GitHub 地址。 + +### v1.0.5(2026-08-10) + +- **表情截图跨机器修复**:`EmojiMessage.capture()` 表情气泡自动裁剪全面重构: + - 主路径改用**连通域分析**(`_crop_last_bubble`),按消息方向(左=对方/右=自己) + 精确定位最后一条消息气泡,自动过滤细长竖条(滚动条/面板边框)、剔除头像类 + 小元素,从根源解决右缘滚动条/边框被当成内容导致的右侧大片空白; + - 圆形表情顶部/底部在缩放采样时因 LANCZOS 模糊丢失边缘像素:加大裁剪边距 + (`pad = max(10, scale*5)`)并在全分辨率下**逐像素边缘扩展**找回丢失内容, + 且扩展遇**连续空白行**(消息间分隔)即停,避免吃进相邻消息; + - 时间戳等居中小文字(水平居中约 50% 宽度)不再被误当成消息:方向判定加 + 阈值(左侧 <45% 宽度、右侧 >55%),居中元素两边都不匹配; + - 最终尺寸校验:`min(crop) < 50` 视为时间戳/文字误判,自动回退到 + 「消息分隔空白」「头像锚点」等备用定位,仍过小则判定失败返回 None; + - 本机与高 DPI 机器均已实测通过(完整表情、无空白、无切顶、不截时间戳)。 + +### v1.0.4(2026-08-10) + +- **多特征兜底窗口定位**:主窗口定位不再只依赖类名 `Qt51514QWindowIcon` + (类名降级为软条件),联合 进程名 `weixin.exe` / 窗口可见 / 大尺寸 + (≥800px)/ 标题关键词(微信/Weixin/WeChat)评分定位——Qt 升级改名 + (`Qt51514` → `Qt6xxx`)也不失效;渲染子窗口按前缀 `MMUIRenderSubWindow` + 匹配(兼容 `MMUIRenderSubWindowHW` / `MMUIRenderSubWindow` 等变体), + 找不到时退回用主窗口矩形计算坐标。 +- **布局自动校准**:首次运行自动校准——OCR 检测「搜索」「发送」锚点实测 + 布局比例,保存到 `~/.wechatauto/layout-<机器标识>.json`,之后自动加载; + 布局漂移(DPI/窗口尺寸/缩放变化)时自动重新校准。 +- **最大化状态保持**:激活窗口时先 `GetWindowPlacement` 记录状态,原为 + 最大化则用 `SW_SHOWMAXIMIZED` 恢复(原 `SW_RESTORE` 会把最大化窗口 + 缩成普通大小),最小化恢复不再破坏用户窗口布局。 +- **发送模块窗口兜底**:`find_main_window` 类名查找失败后按标题「微信」 + 兜底,适配类名不同的机器。 + +### v1.0.3(2026-08-08) + +- **文本消息还原**:微信 4.x 部分文本消息 content 为「容器头 + UTF-8 明文 + + 尾部填充」结构,此前显示为 `[文本]`/空。新增 `_extract_text_from_blob` + 还原明文,数据库读取与 bot 均可见真实内容(含群消息 `wxid_xxx:` 前缀)。 +- **表情截图方向感知与兼容性**:`_db_row_to_message` 写入 `msg.attr` + (`self`/`friend`),`EmojiMessage.capture()` 按方向定位气泡(自己发的用 + 消息分隔空白、对方发的用头像锚点),避免截图前自己又发了一条消息时误截到 + 自己的气泡;裁剪阈值自适应截图尺寸,跨分辨率/DPI 可用。微信 4.x 主窗口为 + Qt 自绘渲染,不暴露 UIA 子树,故截图定位全部基于屏幕像素分析。 +- **发送会话复用**:`send_msg` 记录 `_current_chat`,目标会话已打开时跳过 + `open_chat`(重扫侧栏+点击),逐条连续发送不再反复点击对话框,效率提升。 +- **搜索联系人选第一条**:`_search_chat` 按视觉顺序排序并过滤「搜索网络结果/ + 搜一搜」节标题,点选第一条联系人而非网络搜索。 +- **动画表情不再落盘伪 `.gif`**:`download_image` 识别到 `wxgf` 容器(微信 + 动画表情私有格式)时返回 `None`,不再生成打不开的假图片。 +- **`Listener.stop()` 崩溃修复**:`db.py` 补 `import sys`(`_run/_poll_once` + 使用 `sys.stderr` 却未导入)。 + +### v1.0.2(2026-08-08) + +- **表情消息支持**:新增 `EmojiMessage` 消息类型(`type='emotion'`), + "动画表情"不再被归为 `OtherMessage`,并按收发方向提供 + `FriendEmojiMessage` / `SelfEmojiMessage`。微信 4.x 表情消息在本地数据库中的 + content 为加密数据,无法直接还原成图片,因此新增 `EmojiMessage.capture()`: + 采用「打开会话 → 滚动到底 → 截取消息区 → 自动裁剪最后一条消息气泡」 + 的屏幕截图方案,返回图片路径,可直接供 AI 视觉识别使用 + (示例见 `demo_emoji_capture.py`)。 +- **监听器并发工作线程**:`Listener` 回调移到独立工作线程执行,每个被监听 + 会话对应一条**串行**工作线程——同一会话内消息按序处理、不同会话间并行; + 轮询线程只负责读取数据库并分派任务,不再被慢回调(AI 调用 / 图片识别等) + 阻塞,`stop()` 优雅关闭所有工作线程。 +- **数据库消息兼容增强**:`_db_row_to_message` 支持 bytes 类型 content + (自动解码还原文本)、`local_type` 缺失时自动推导消息类型, + `_extract_group_sender` 兼容 bytes 内容。 + +--- + +## 一、项目状态 + +| 能力 | 状态 | 实现方式 | +| ---- | ---- | -------- | +| 读取消息 | ✅ 已完成并验证 | 本地数据库解密(`wechatauto/db.py`) | +| 消息监听(轮询) | ✅ 已完成并验证 | `Listener` + `get_new_messages` 增量回调 | +| 表情消息识别与截图 | ✅ 已完成并验证(v1.0.3 方向感知) | `EmojiMessage` + `capture()`(屏幕截图自动裁剪) | +| WAL 增量合并 | ✅ 已修复并验证 | 帧盐校验合并 `-wal`(见 §2.4) | +| 历史消息全量导出 | ✅ 已完成并验证 | `export_history`(JSON / SQLite) | +| 媒体下载(图片/语音/文件) | ✅ 已完成并验证 | `wechatauto/media.py`(图片 V2 解密) | +| 朋友圈读取 | ✅ 已完成并验证 | `MomentDB` 直接读 `sns.db` | +| 多账号管理 | ✅ 已完成并验证 | `list_accounts()` + `account=` 参数 | +| 读取会话列表 | ✅ 已完成并验证 | 同上 | +| 搜索联系人 | ✅ 已完成并验证 | 同上 | +| 发送消息 | ✅ 已完成并验证 | UIA + 坐标+OCR 混合(`wechatauto/guia.py`) | +| 发送文件/图片/回复/艾特 | ✅ 已完成并验证 | 剪贴板 CF_HDROP + OCR | +| 语音通话 / 拍一拍 | ✅ 已完成并验证 | UIA 按钮 + OCR 菜单(`Chat.VoiceCall` / `Chat.Poke`) | +| UI 自动化(UIAutomation) | ✅ 热激活后可用 | 写 Weixin.dll Qt accessibility gate,物化 `mmui::*` 树 | + +**结论**:微信 4.1.x 聊天界面使用自绘渲染(`MMUIRenderSubWindow*`),冷启动 +对 UIAutomation 只暴露 `Qt51514QWindowIcon` 空壳(原 wxauto 的 UI 方案因此 +失效)。本项目通过**热激活 Qt accessibility gate**(写 Weixin.dll 内读屏 +标志位,从 `qt.accessibility.core` 引用扫描 RVA)物化 `mmui::*` UIA 树, +实现发送/语音通话/拍一拍等操作(UIA 优先、坐标+OCR 兜底);消息读取仍走 +「**本地数据库解密**」(已全链路验证)。 + +--- + +## 二、读取原理 + +微信 4.x 的数据存放在本地 SQLCipher 4 加密的 SQLite 数据库中: + +``` +D:\微信文件\xwechat_files\_xxxx\db_storage\ +├── contact\contact.db 联系人(昵称、备注) +├── session\session.db 会话列表(未读数、摘要) +├── message\message_0..4.db 聊天消息(按会话分表 Msg_,跨分库分片) +├── message\media_0.db 语音(VoiceInfo.voice_data,SILK 二进制) +├── message\message_resource.db 文件原名(MessageResourceDetail.packed_info) +├── sns\sns.db 朋友圈(SnsTimeLine,SnsDataItem XML) +└── ... +``` + +### 2.1 密钥提取(进程内存只读扫描) + +每个数据库有**独立的 32 字节密钥**,保存在微信进程内存中的 +`com.Tencent.WCDB.Config.Cipher` 配置对象里: + +1. 在 Weixin.exe 所有可读内存区域中查找该字符串; +2. 由字符串地址定位配置对象(`[ptr][len]` 结构回溯); +3. 数据块与固定掩码异或后得到 `x'<64位hex密钥><32位hex盐>'` 明文配置; +4. 用 SQLCipher 4 HMAC 校验规则验证每个候选密钥; +5. 验证通过的密钥保存到 `%TEMP%\wechatauto_db\<账号>\keys.json` 缓存。 + +### 2.2 数据库解密 + +- SQLCipher 4,页大小 4096,`PBKDF2-HMAC-SHA512`(加密密钥 256000 次迭代); +- 解密结果按页写入临时目录,校验源 mtime/size 复用缓存; +- 首次解密 contact.db 约 6s,之后全部秒级。 + +### 2.3 消息查询 + +- 会话名 → `Md5(会话微信号)` → 表名 `Msg_`(同一会话可能分片在多个 + `message_*.db`,按 `sort_seq` 合并排序); +- 关键列:`local_type`、`real_sender_id`(2=自己,其他为数字 id,可通过 + `message_resource.SenderName2Id` 反查微信号)、`server_id`、 + `packed_info_data`(图片/视频 md5)、`sort_seq`。 + +### 2.4 WAL 增量合并(已修复) + +微信 `-wal` 是预分配文件:checkpoint 时 WAL 头 salt+1 并清零写游标,但 +**旧世代帧仍留在文件中**。若合并时不过滤帧盐,会把过期页覆盖进主库导致 +`database disk image is malformed`。修复方案: + +- `_merge_wal` 读取 WAL 头后**仅合并 salt 与当前 WAL 头一致的帧**, + 旧世代帧直接跳过; +- 缓存 stamp 加入版本号 `STAMP_VERSION=2`,旧损坏缓存自动强制全量重建; +- 合并结果用 `PRAGMA integrity_check` 校验,失败自动重试全量重建。 + +验证:contact.db 合并后 integrity OK,2354 个联系人全部可查。 + +### 2.5 媒体存储与解密(图片 v2 格式) + +- 图片:`msg\attach\<会话md5>\\Img\.dat`(加密); +- 语音:`media_0.db` → `VoiceInfo.voice_data`(SILK 明文 BLOB); +- 文件:`msg\file\\<原文件名>`(原名来自 message_resource); +- 视频:`msg\video\\.mp4`(未落盘时返回 None)。 + +图片 `.dat` 为 **v2 格式**:`[6B sig 070856320807][4B aes_size LE][4B xor_size LE]` ++ AES-ECB 密文 + 明文段 + 异或段: + +- **AES 密钥**:16 字节 ASCII,账户级稳定密钥,但仅在微信查看图片时驻留 + 进程内存。`MediaDownloader` 通过内存扫描反测(AES 解首块后校验 JPEG/PNG + 魔数)获取,**命中后持久化到 `image_keys.json`**;也支持 `image_key=` 参数 + 显式注入。本机实测:单一密钥稳定解密 35/40 张随机图片(其余为微信动画 + 表情容器 `wxgf`)。 +- **XOR 密钥**:单字节,从同图缩略图 `_t.dat` 尾部 JPEG 结束标记 + `FF D9` 反推(`key = tail[0] ^ 0xFF`)。 + +--- + +## 三、快速开始 + +> 📖 **完整使用指南**:[GUIDE.md](GUIDE.md)(中英对照 / bilingual) + +### 3.1 安装 + +```bash +pip install -e . +# 坐标+OCR 发送路线额外依赖: +pip install winsdk pypinyin +``` + +### 3.2 示例程序 + +```bash +python demo_db.py +``` + +### 3.3 代码示例 + +```python +from wechatauto import WeChatDB + +db = WeChatDB() # 自动检测账号与数据目录(微信需已登录) + +info = db.get_self_info() # 当前账号昵称 +for s in db.get_sessions(limit=10): # 会话列表 + print(db.get_nickname(s["username"]), s["unread"]) + +hits = db.search_contact("Ayi") # 搜索联系人 +who = hits[0]["username"] +for m in db.get_messages(who, limit=10): # 最近消息 + print(m["create_time"], m["sender_id"], m["type"], m["content"]) +``` + +### 3.4 媒体下载 + +```python +from wechatauto import WeChatDB, MediaDownloader + +db = WeChatDB() +md = MediaDownloader(db) # 可传 image_key="..." 注入图片密钥 +key = md.detect_image_key() # 内存扫描/缓存取 AES+XOR 密钥 +print(key) + +for m in db.get_messages("filehelper", limit=50): + out = md.download_media("filehelper", m["local_id"]) # 按类型自动分发 + if out: + print("已下载:", out) +``` + +### 3.5 朋友圈读取 + +```python +from wechatauto import WeChatDB, MomentDB + +md = MomentDB(WeChatDB()) +for feed in md.get_moments(limit=10): # 时间线(3382 条全量可读) + print(feed["nickname"], feed["text"]) + print(" 图片:", [i["md5"] for i in feed["images"]]) + print(" 赞:", [l["nickname"] for l in feed["likes"]]) + print(" 评论:", [(c["nickname"], c["content"]) for c in feed["comments"]]) + md.download_media(feed["images"][0]) # 本地缓存或 URL 拉取 +``` + +### 3.6 消息监听 + +```python +from wechatauto import WeChatDB +from wechatauto.db import Listener + +db = WeChatDB() +lst = Listener(db, interval=1.0) +lst.add_listener("filehelper", lambda msg, lst: print("新消息:", msg["content"])) +lst.start() +# ... 业务代码 ... +lst.stop() +``` + +- 回调在**独立工作线程**中执行(v1.0.2):每个被监听会话对应一条串行 + 工作线程,同一会话内消息按序处理、不同会话间并行;轮询线程只负责读取 + 数据库并分派任务,不会被慢回调(AI 调用 / 图片识别等)阻塞。 + +### 3.7 历史导出 + +```python +db.export_history(r"D:\backup\chat.json", fmt="json") # 全部会话 +db.export_history(r"D:\backup\chat.db", fmt="sqlite") +db.export_history(r"D:\backup\one.json", fmt="json", + users=["filehelper"], limit_per_chat=1000) +``` + +### 3.8 多账号 + +```python +from wechatauto import list_accounts, WeChatDB +for a in list_accounts(): + print(a["account"], a["wxid"]) +db2 = WeChatDB(account="wxid_xxx_abcd") # 显式指定账号(缓存按账号隔离) +``` + +### 3.9 表情消息与截图 + +微信 4.x 的"动画表情"消息在本地数据库中 content 为加密数据,无法直接还原成 +图片。v1.0.2 起监听回调中的表情消息为独立的 `EmojiMessage` 类型 +(`type='emotion'`,`FriendEmojiMessage` / `SelfEmojiMessage` 按收发方向区分), +并支持对屏幕上的表情气泡自动截图: + +```python +# 在 Listener 回调内,把消息 dict 转成消息对象后再截图: +def on_msg(msg, listener): + if msg["type"] == "动画表情": + from wechatauto.wx import _db_row_to_message + m = _db_row_to_message(msg, chat) # chat: 当前会话 + path = m.capture() # 返回 PNG 路径,供 AI 视觉识别 +``` + +`capture(save_dir=None)` 流程:打开会话(已打开则跳过,避免刷新消息列表导致 +控件失效)→ 滚动到底 → 截取消息区 → 按消息方向定位最后一条消息气泡: + +- **自己发的消息**(`attr='self'`,右侧无头像):用「消息分隔空白」定位 + 消息顶部,空白阈值按截图高度自适应(约消息区高度的 2.5%), + 跨分辨率/DPI 保持一致; +- **对方发的消息**(`attr='friend'`,左侧有头像):优先检测头像圆形彩色块 + 的顶部作为消息顶部(特征跨分辨率稳定),失败时回退消息分隔空白。 + +返回图片路径(失败返回 None)。独立示例:`python demo_emoji_capture.py`。 +调试时可保留 `~/pane_diag_raw.png`(每次截图保存的消息区原图)与 +`[CAP]` 日志行(截图尺寸、消息方向、裁剪路径、结果尺寸)用于排查。 + +--- + +## 四、API 参考 + +### `WeChatDB(db_dir=None, keys_file=None, workdir=None, account=None)` + +| 方法 | 说明 | +| ---- | ---- | +| `get_self_info() -> dict` | 当前账号(username / nick_name / remark) | +| `get_sessions(limit=100)` | 会话列表:username / unread / summary / last_time | +| `search_contact(keyword)` | 按昵称/备注/微信号搜索 | +| `get_messages(user, limit, offset)` | 读取指定会话消息 | +| `get_message_row(user, local_id)` | 单条原始消息(含 server_id / packed_info,媒体用) | +| `get_new_messages(user, since_seq)` | `sort_seq > since_seq` 的增量消息(升序) | +| `get_nickname(user)` | 微信号 → 显示昵称 | +| `list_message_chats()` | 所有含消息的会话(md5 / 昵称 / 消息数) | +| `export_history(out_path, fmt, ...)` | 全量导出 JSON / SQLite | +| `extract_keys()` | 手动触发密钥提取 | +| `wxid` / `account` / `account_dir` | 当前账号信息 | +| `list_accounts()`(模块级) | 扫描本机所有微信账号 | +| `auto_detect_db_dir()`(模块级) | 自动定位数据目录(配置文件 → 注册表 → 常见默认目录) | + +### `MediaDownloader(db, save_dir=None, image_key=None)` + +| 方法 | 说明 | +| ---- | ---- | +| `detect_image_key(refresh)` | 取 (AES 密钥, XOR 密钥),命中后持久化 | +| `decrypt_image(dat_path)` | 解密单个 `.dat`(自动识别 v1/v2) | +| `download_media(user, local_id)` | 按类型分发下载 | +| `download_image / _voice / _video / _file` | 各类媒体下载 | +| `copy_files_to_clipboard(paths)` | CF_HDROP 写剪贴板(发送附件用) | + +### `MomentDB(db)` + +| 方法 | 说明 | +| ---- | ---- | +| `get_moments(limit, offset, username)` | 朋友圈时间线(最新在前) | +| `get_moment(tid)` / `get_my_moments(limit)` | 单条 / 我的动态 | +| `find_local_media(md5, kind)` | 本地缓存查找(Sns\Img / Sns\Video) | +| `download_media(media, save_dir)` | 缓存优先,否则 URL 拉取 | + +### `Listener(db, interval, watermark)` + +`add_listener(user, cb)` / `remove_listener` / `start` / `stop` / `watermark`。 + +### `WeChatGUI`(发送,锁屏不可用) + +| 方法 | 说明 | +| ---- | ---- | +| `send_msg(text, who, verify)` | 文本发送(OCR 定位 + 剪贴板粘贴) | +| `send_file(path, who, verify)` | 文件(CF_HDROP 粘贴 + 回车) | +| `send_image(path, who, verify)` | 图片(同上) | +| `reply_msg(text, who, verify)` | 回复最近消息(悬停 + OCR 回复入口) | +| `at_member(member, text, who, verify)` | 群聊 @ 成员 | +| `open_chat / focus_input / bring_to_front` | 基础操作 | + +一行式:`quick_send` / `quick_send_file` / `quick_send_image` / `quick_reply`。 + +--- + +## 五、已知限制 + +1. **需要微信登录**:数据库密钥存于进程内存,首次使用需微信运行中 + (提取后本地缓存);重新登录后密钥变化需重新提取(自动校验失败重扫); +2. **图片 AES 密钥瞬态**:仅在微信查看图片时驻留内存;`MediaDownloader` + 扫描命中后会持久化(`image_keys.json`),也可用 `image_key=` 显式传入; +3. **发送为 GUI 操作**:锁屏/会话断开时 `desktop_available()` 返回 False, + 发送接口返回明确失败;文件/图片/回复/艾特代码已完成但需桌面解锁后实测; +4. **视频文件未落盘时不可下载**:视频 mp4 仅在本地存在(`msg/video`)时 + 返回,否则返回 None; +5. **发朋友圈功能已舍弃**:4.x 的发表为自绘界面操作,不可靠自动化; + 本库仅保留朋友圈读取/点赞/评论能力。 + +--- + +## 六、发送消息(坐标 + OCR) + +微信 4.1.12+ 聊天界面自绘渲染、无无障碍节点,发送走 +「屏幕坐标 + 本地 OCR」(`wechatauto/guia.py`): + +1. **多特征兜底定位**主窗口(类名 `Qt51514QWindowIcon` 只是「软条件」, + 联合标题 / 进程名 `weixin.exe` / 可见 / 大尺寸评分,Qt 升级改名也不 + 失效),再按前缀 `MMUIRenderSubWindow` 找渲染子窗口(兼容 + `MMUIRenderSubWindowHW` / `MMUIRenderSubWindow` 等不同版本类名; + 找不到时回退用主窗口矩形计算坐标); +2. 布局用渲染子窗口相对坐标描述,运行时换算为屏幕绝对坐标;首次运行自动 + 校准(OCR 检测「搜索/发送」锚点实测比例),保存到 + `~/.wechatauto/layout-<机器>.json`,之后自动加载、布局漂移自动重校准; +3. OCR 识别会话列表点击目标(失败走搜索框;生僻字/小字号会话名自动放大 + 3 倍 + 多轮投票重扫,搜索回退只点联系人、自动排除群聊与群成员预览行); +4. 扫描输入框白色区定位并聚焦; +5. 文字以「剪贴板 + Ctrl+V」输入(避免中文输入法拦截),失败回退拼音组合; +6. OCR 定位「发送」按钮(找不到回退回车键); +7. `verify=True` 时用 `WeChatDB` 读回确认。 + +文件/图片通过 **CF_HDROP 剪贴板 + Ctrl+V** 插入草稿再回车发送,绕开自绘 +「+ 菜单」定位;回复/艾特分别走悬停 OCR 工具栏与成员弹层 OCR。 + +```python +from wechatauto.guia import quick_send, quick_send_file +quick_send('你好', '文件传输助手', verify=True) +quick_send_file(r'D:\资料\报告.pdf', '文件传输助手') +``` + +> 注意:OCR 需要系统语言包含中文(`Windows.Media.Ocr`)。 + +--- + +## 七、后续路线 + +1. **发送功能实测**:桌面解锁后校准 guia 各坐标常量,验证文件/图片/回复/艾特; +2. **视频消息下载增强**:微信 4.x 聊天视频存储位置仍需确认(本机无样本); +3. **性能优化**:导出/首扫并行化,内存扫描增量缓存。 + +--- + +## 八、目录结构 + +``` +├── wechatauto/ +│ ├── wx.py UIA 自动化入口(4.x 受限) +│ ├── guia.py ★ 坐标+OCR 发送模块(文本/文件/图片/回复/艾特) +│ ├── db.py ★ 数据库读取(密钥提取 + 解密 + WAL 合并 + 导出 + 监听) +│ ├── media.py ★ 媒体下载(图片 v2 解密 / 语音 / 视频 / 文件) +│ ├── moment.py ★ 朋友圈(MomentDB 数据库路线 + 旧 UIA 兼容) +│ ├── ui/ UI 控件层 +│ ├── msgs/ 消息模型 +│ └── ... +├── demo.py UI 自动化示例(微信 4.1 上受限) +├── demo_db.py ★ 数据库读取示例(推荐) +├── demo_guia.py ★ 坐标+OCR 发送示例 +├── demo_listen.py ★ 实时消息监听示例 +├── demo_reply_at.py ★ 回复/@ 成员实测示例 +├── demo_emoji_capture.py ★ 表情消息截图示例 +├── docs/技术文档.md ★ 完整技术文档(架构/原理/API/扩展) +└── pyproject.toml +``` + +## 九、免责声明 + +本项目仅用于个人学习与自动化研究,请遵守微信软件许可协议及当地法律法规, +勿用于任何违反规定的用途。 + + +注:本库完全由AI(opencode+deepseek-v4-flash)生成 + +--- + +## 十、联系方式 + +- 邮箱:fanyuantaier@163.com diff --git a/README_pypi.md b/README_pypi.md new file mode 100644 index 0000000..773ae50 --- /dev/null +++ b/README_pypi.md @@ -0,0 +1,868 @@ +> [!NOTE] +> **📢 维护状态 / Maintenance Notice** +> 本人因今年升高一,明天(8月23日)报到。开学后几乎没有时间继续更新本项目(如果有时间,争取周日更新)。遇到问题请自行在 Issues 区讨论,或询问 AI 协助解决。感谢支持! +> +> I'm starting senior high school and will register tomorrow (Aug 23). After school starts I'll have almost no time to keep updating (Sundays if possible). Please discuss issues in the Issues section or ask an AI. Thanks for your support! + +# wechatauto-replica — 微信 4.x Windows 自动化 / WeChat 4.x Automation + +> **中文版** 在下方 · **English version below** + +--- + +## 🇨🇳 中文版 + +### wechatauto —— 微信 4.x Windows 客户端自动化(wxauto 复刻版) + +![PyPI version](https://img.shields.io/pypi/v/wechatauto-replica) +![PyPI downloads](https://img.shields.io/pypi/dw/wechatauto-replica) +![Python](https://img.shields.io/pypi/pyversions/wechatauto-replica) +![License](https://img.shields.io/github/license/fanyuantaier/wechatauto-replica) +![GitHub stars](https://img.shields.io/github/stars/fanyuantaier/wechatauto-replica) + + +本项目复刻上游 wxauto 项目,目标是实现对当前微信 4.x Windows 客户端的自动化 +(读取消息、发送消息、媒体下载、朋友圈),非网页版,直接操作本机客户端。 + +> 当前版本:1.1.7 +> +> **兼容范围**:Windows 10/11 | Python 3.9+(已在 3.12 验证)| 微信 **4.1.12+** +> (数据库读取路线对微信版本不敏感;坐标+OCR 发送路线依赖 4.1.12+ 自绘渲染 +> 布局,其它 4.x 小版本可能需校准 `guia.py` 布局常量)。 + +![解密读取微信 4.x 加密数据库](docs/demo_db_files.gif) + +*直接解密读取 `xwechat_files/.../db_storage/` 下的 `contact.db` / `message_*.db` / `sns.db` 加密库——纯本地,无 Web API。* + +--- + +## 🤝 致谢 + +> 感谢 [vesio](https://github.com/vesio) 在 [issue #1](https://github.com/fanyuantaier/wechatauto-replica/issues/1) 提供微信 4.1.12 的 UIA 控件树代码与思路,促成了 v1.0.8 的 UIA 混合驱动。 +> +> 感谢 [nanshanjack](https://github.com/nanshanjack) 发现 UI 锁的可重入问题(v1.1.2 修复)。 +> +> 感谢 [maozhitao12450](https://github.com/maozhitao12450) 报告 WXAM (wxgf) 图片下载问题(v1.1.3 修复)。 +> +> 感谢 [uiharukazari0105](https://github.com/uiharukazari0105) 发现语音数据分片存储(`media_1.db` 等)从未被搜索的问题(v1.1.4 修复)。 +Thanks to [NothingFumo](https://github.com/NothingFumo) for the master-key extraction design (cfg + PBKDF2-derived per-DB keys, v1.1.7). +感谢 [NothingFumo](https://github.com/NothingFumo) 提出主密钥提取方案(cfg + PBKDF2 派生逐库密钥,v1.1.7)。 + +--- + +## 版本记录 + +### v1.1.7(2026-08-22) + +- **基于主密钥的密钥提取(PR #10,感谢 [NothingFumo](https://github.com/NothingFumo))**:不再依赖进程内存中逐个库的 `Config.Cipher` 字面量扫描(微信 4.1.12.26+ 已失效),改为从 `cfg` 结构提取**单一主密钥**(`cfg+0x2B8` 密文 ⊕ DLL 中 4×movabs 常量),再通过 `PBKDF2-HMAC-SHA512(主密钥, 库salt, 256000)` **离线派生各库独立密钥**——27/27 个 SQLCipher4 数据库实测验证通过。解决 4.1.12.26+ 密钥提取失效(issue #3 / #7)。 +- **图片密钥统一流程**:模板收集(`*_t.dat`,按 mtime 取前 16)→ 尾字节众数统计 XOR(替代原单文件探测误回退 `0x88` 的缺陷)→ 优先 `cfgDword` 派生(确定性、离线),注入/缓存/内存扫描 AES 兜底。3000/3000 真实密文探针验证通过。 +- **cfg 同步返回账号字段**:`WeChatDB` 现在随主密钥一起返回 `name` / `number` / `phone`,与主流密钥工具输出格式逐字段对齐。 +- 新参数 `master_key` / `cfg_dword` 全部可选、完全向后兼容——不传则走原路径。核心解密函数零改动。 + +### v1.1.6.3(2026-08-21) + +- **修复导入卡死**:`import wechatauto` 不再在部分系统上永久阻塞(如微信或其他 Qt 应用占用 COM 导致 `uiautomation` / COM 初始化挂起)。`uiautomation` 和 `comtypes` 现在延迟导入——首次访问 UIA 功能时才加载,不在 `import wechatauto` 时触发。 +- **修复 OCR 挂起**:`ScreenOCR.recognize` 现在用 `asyncio.wait_for(..., 8s)` 包裹 WinRT 异步调用——在中文等部分系统上 `Windows.Media.Ocr` 异步可能永不完成,此前会导致 `quick_send` 永久阻塞;现在会超时并退化为返回空 OCR 结果。 +- **修复首次校准卡死**:`calibrate_layout` 的每个 OCR 检测步骤现在用守护线程 + 5 秒超时。此前首次运行(无布局配置文件)时 WinRT OCR 若挂起,整个 `WeChatGUI.__init__` 会永久阻塞;现在超时后回退使用默认布局比例。 +- **支持明文头(key+salt)库解密**:密钥提取现支持 SQLCipher 4「Raw Key with Explicit Salt」形式(`x'<96hex>'` = 32B key + 16B 显式 salt,配合 `cipher_plaintext_header_size`)。48 字节 key(32B key + 16B salt)按明文头布局验证/解密(第 1 页保留明文头);32 字节 key 保持标准文件头 salt 路径。可解锁部分新版本微信(如 4.1.12.26 环境)下旧偏移指向类名表而非 Cipher 实例导致的解密失败。 +- **修复 `wxid_*` 硬编码**:账号发现不再假设目录以 `wxid_` 开头——只要 `db_dir` 下某子目录含 `db_storage/` 子目录即识别为账号,支持自定义微信号(用户自选的非 `wxid_` 前缀用户名)。 +- **全局消息监听**:`WeChat.AddListenAll(callback)` 现在一次监听所有会话(好友、群聊、文件传输助手等),支持自动发现新会话。`WeChat.RemoveListenAll()` 停止全局监听。回调签名为 `(Message, Chat)`,其中 `Chat.who` 为会话原始 username。 + +### v1.1.6.1(2026-08-20) + +- **PyPI 描述修复**:1.1.6 发布时漏同步 `README_pypi.md`(描述停留在 1.1.5.1),本补丁版补全 v1.1.6 更新记录并同步版本号。 + +### v1.1.6(2026-08-20) + +- **缺密钥报错自动诊断**:`数据库无可用密钥` 报错前会自动检测三项最常见根因——Python 位数(32 位读不了 64 位微信内存)、逐个微信进程的 `OpenProcess`/`ReadProcessMemory` 读取权限、多账号目录与所选账号对比(提示用 `WeChatDB(account=...)` 显式指定),无需先手动运行 `diagnose_keys`。 +- **新增诊断工具**:`wechatauto/diagnose_keys.py`(微信登录后运行 `python -m wechatauto.diagnose_keys`)输出库版本、Python 位数、微信进程 PID 及逐个进程的读取权限检测、磁盘全部账号与所选账号对比、已缓存密钥、进程内存重新提取结果与密钥校验情况——报密钥提取问题时把输出完整发给维护者即可定位。 +- **跳过 `migrate\unspportmsg.db`**:该库是微信保留的「未支持消息」库,进程内存中无对应密钥、代码也从不会访问;此前它会让每次初始化都触发一次全进程内存扫描。 + +### v1.1.5.1(2026-08-18)— 测试版 / beta + +- **修复实时监听不触发**:`WeChatDB.get_new_messages()` 引用了未定义的 `found`(NameError 被 `Listener._poll_once` 吞掉),导致消息回调从未触发——包括从未聊过天的联系人的首条消息。 +- **动态消息分片**:`_message_dbs()` 现在会重新扫描磁盘,微信运行中新建的分片(如 `message_5.db`)会被自动发现并提取密钥。 + +### v1.1.5(2026-08-18) + +- **版本号规范化**:语音跨库下载修复后整理补丁版本号(1.1.4.2 → 1.1.5)。 + +### v1.1.4.2(2026-08-18) + +- **PyPI 描述清理**:移除 v1.1.4 版本记录中关于 demo 默认群改动的条目。 + +### v1.1.4.1(2026-08-18) + +- **PyPI 页面中英双语**:PyPI 描述合并中文(`README.zh-CN.md`)与英文(`README.md`)两个版本,中文版在包页面可见。 + +### v1.1.4(2026-08-18) + +- **跨全部媒体库下载语音**:`download_voice()` 现在搜索所有 `media_*.db`(不再只查 `media_0.db`)——微信把语音分片存到多个媒体库;此前存在 `media_1.db` 等的语音无法找到(感谢 uiharukazari0105)。 +- **群聊图片缩略图回退**:群聊的图片原图只有被点开(查看)后才会落盘本地;原图未点开不下发时,`download_image` 自动回退到缩略图(`_t.dat`),保存为带 `_thumb` 后缀的文件。 +- **`WeChatDB._find_media_rows(user, types)`**:新增批量查媒体接口——返回某会话指定 `local_type` 集合的全部媒体 `local_id`(用于批量下载)。 +- **`demo_media.py --images N`**:按 `local_type` 直接从数据库下载某会话最近 N 张图片,绕过总消息数 `--limit` 的限制——群聊消息上万条时不再「只列出几张图」。 + +### v1.1.3(2026-08-17) + +- **WXAM (wxgf) 图片解码**:微信 4.x 现在把**普通图片**(不仅是动图贴纸)也存进 WXAM 容器 + (内部为 HEVC 比特流)。`MediaDownloader.download_image` 新增 wxgf 处理:提取 HEVC + Annex-B 流,用 ffmpeg 转码为 JPG(优先用 `imageio-ffmpeg` 内置二进制,其次 PATH 上的 + ffmpeg);ffmpeg 不可用时不再丢弃数据,改为保存原始解密数据为 `.wxgf` 兜底。 +- 新增依赖:`imageio-ffmpeg>=0.4.9`。 + +### v1.1.2(2026-08-16) + +- **UIA 驱动线程安全**:`WeChatUIA` 实例化时在当前线程初始化 COM(`CoInitializeEx`,幂等)——修复后台线程/宿主进程(如 WeChatBot)实例化报「尚未调用 CoInitialize / 无法加载 UIAutomationCore.dll」。 +- **主窗口过滤**:只认加载了 `Weixin.dll` 的主进程窗口,过滤无 DLL 的辅助进程窗口(其热激活必然失败,不再刷噪音警告)。 +- **转发语音修复**:`Chat.ForwardVoiceMessage` 未指定目标时用 `self`(原 `_cur()` 可能误取会话)。 +- **UI 锁可重入**:`LockManager` 同线程可重入——`@uilock` 函数互相调用(如 `ForwardVoiceMessage` → `VoiceMessage.forward_to`)不再死锁。 + +### v1.1.1(2026-08-16) + +- **撤回消息**(`Chat.RecallLastMessage` / `uia_driver.recall_last_message`):右键最新一条自己发的消息 → UIA 优先 + (主窗口树内 `mmui::XMenuView` 菜单项定位「撤回」,Invoke/Select 或鼠标点击),OCR 兜底(全屏识别「撤回」 + 文字定位点击);菜单只剩「删除」(超过 2 分钟撤回时限)时返回失败。 +- **UIA 健壮性**:菜单项查找限定在主窗口子树内(避免触发 Windows UIA 根遍历的系统挂起 bug);移除脆弱的 + `WindowControl(ClassName=...)` 兜底定位。 +- **媒体修复**:视频 id bytes→str 解码(`MediaDownloader`),修复视频文件定位。 +- `demo_media.py` `--photos` 默认 3 → 10。 + +### v1.1.0(2026-08-15) + +- **图片 AES 密钥自动监控捕获**(`media.py`):微信 4.x 的 V2 图片 AES 密钥仅在 + 查看图片大图时短暂驻留进程内存(实测约 5 分钟后释放)。`_scan_aes_key()` 新增 + `monitor` 模式——首次扫描未命中时自动持续轮询并提示去微信点开一张图片看大图, + 密钥进入内存后自动捕获并持久化到 `image_keys.json`,之后免扫描直接解密。 + 首次用户无需手工找密钥,看图一次即可完成配置。 +- **修复进程排序扫描 bug**:移除 `_scan_aes_key` 中按内存占用排序进程的逻辑 + (`GetProcessMemoryInfo` 结构体大小传错导致工作集全为 0,`reverse` 排序反而把 + 主进程排到最后,错过密钥驻留窗口),恢复按微信进程原顺序扫描(主进程优先命中)。 +- **语音/视频/文件不受影响**:仅图片 `.dat` 为 V2 AES 加密需密钥;语音(SILK)、 + 视频(MP4)、文件均为明文直接读取。 + +### v1.0.9(2026-08-14) + +- **open_chat 账号/微信号搜索修复**(`uia_driver.py`):微信搜索框不认 wxid + (系统账号),`open_chat` 传入 username 时自动通过本地 DB 映射为昵称/备注/ + 微信号再搜索(`_resolve_search_keyword`),并清空搜索框残留重试; + 实测 `open_chat('wxid_sb9or2x9zxj012')` 成功。 +- **UIA 表情包精确读取**(`msgs/mtype.py` + `uia_driver.py`):热激活后消息 + 列表暴露 `mmui::RecyclerListView`,新增 `find_in_message_list()` 用鼠标滚轮 + 驱动虚拟化列表滚动,按 ClassName/Name 定位表情行并取 BoundingRectangle + 精确坐标;`EmojiMessage.capture()` 优先走 UIA 定位 + 方向感知气泡裁剪 + (`_crop_bubble_from_row`),实测 1.1s 裁出 271×271 表情,替代原先 + 「截图全消息区 + 连通域猜气泡」的脆弱方案;失败自动回退原连通域逻辑。 +- **语音通话**(`uia_driver.voice_call` + `Chat.VoiceCall`):标题栏暴露 + `mmui::ChatVoIPView.voip_button`(Name=语音通话),控件树动态重建需重试 + 定位;video=True 尝试找视频通话按钮(当前版本未暴露,通常失败)。 +- **拍一拍**(`uia_driver.poke` + `Chat.Poke`):微信 4.x 拍一拍只能通过 + 右键对方头像触发,菜单为自绘不暴露 UIA;实现为「内容重心定位 friend + 消息行 → 右键头像 → 全屏 OCR 定位「拍一拍」→ 点击」,实测 3.2s 发出 + (网络正常时对方收到,网络异常时微信显示失败提示,链路本身正确)。 +- `EmojiMessage.capture()` / `voice_call` / `poke` 失败均自动回退或返回 + WxResponse 失败,不影响既有 OCR 发送路径。 + +### v1.0.8(2026-08-13) +- 🎉 **特别感谢 [vesio](https://github.com/vesio)**:在 issue #1 中提供了微信 4.1.12 可出 UIA 控件树的代码与调试思路,本版 UIA 混合驱动由此而来; +- **UIA 混合驱动**(`uia_driver.py`,微信 4.1.12.26 实测): + - 新增 `WeChatUIA` 引擎:冷启动时 `Qt51514QWindowIcon` 只是空壳(Qt + 无障碍门未激活),通过写 Weixin.dll 内的 Qt accessibility gate + (RVA 扫描定位)**热激活**后,锚点变为 `mmui::MainWindow`,搜索框 + `mmui::XValidatorTextEdit` / 搜索下拉 `search_list` / 输入框 + `chat_input_field` 全部可用; + - 发送链路全部走 UIA:搜索下拉选人(`search_item_*`)打开会话 → + `chat_input_field` 直接输入 + 回车发送,`current_chat` 校验防误配, + 无 OCR 抖动;Windows 冷状态热激活后 UIA 树保持可用; + - `guia.py` 集成混合路径:`_get_uia()` 惰性启用,`open_chat` / + `send_msg` **UIA 优先、OCR 兜底**——UIA 树不可用(版本变更新增 RVA) + 或失败时自动降级到坐标 + 放大 OCR 方案,首次失败本次会话内不再重试。 + - 实测:`send_msg('文件传输助手')` 10.2s、`send_msg('卢立竺')` 13.2s + 均走 UIA 并数据库确认成功(含 verify);UIA 对生僻字会话名不再依赖 + OCR 识别。 +- 新增依赖:`uiautomation`(UIA 客户端库)。 + +### v1.0.7(2026-08-13) + +- **OCR 识别可靠性提升**(`guia.py`,针对生僻字/小字号会话名识别失败): + - 新增 `ocr_zoomed()`:对区域放大 N 倍后再 OCR,坐标按 1/N 还原;实测 + 微信小字号中文在放大 3 倍时识别率最高(放大 6 倍图像过大反而整块 + 返回空),超过 5 倍即回落; + - `_chat_is_open` 标题检测改用放大 3 倍 + y 范围扩到 0-185(微信 4.x + 标题实际渲染在 y≈80-180,原 15-100 的区间会漏检已打开的会话); + - `_search_chat` 搜索回退排除「群聊」节标题以下行、含「包含」的群成员 + 预览行(如「00,包含:卢立竺」)与群名结尾行,只点联系人,修复 + 「搜索选中群聊而非联系人」的问题; + - `_chat_open_confirmed` 改为**优先标题命中**,标题读不到才退而用面板 + 非空白作为已打开判据,修复「点错会话也误判成功」; + - `open_chat` 首查 `_chat_is_open && _pane_has_content`,右侧面板已打开 + 目标会话时直接成功(不再滚动/搜索),已打开场景耗时 45s → 2.7s。 +- **OCR 多轮投票**(`find_session._scan_vote`):WinRT OCR 对生僻字存在 + 抖动(同一行不同轮次可能读出「卢立竺」或「亠人五」)。对侧栏放大 3x + 扫描 4 轮,命中行按 y 聚类(≤30px 视为同行),票数 ≥2 才返回,显著 + 降低误配;普通会话仍走单轮快速路径,无性能损失。 +- 实测:`find_session('卢立竺')` 连续 5 轮 4/4 票一致、稳定命中; + `open_chat` + `send_msg` 全链路成功。 + +### v1.0.6(2026-08-11) + +- **元数据与门面优化**:README 增加徽章(PyPI 版本/下载量/Python 版本/License/Stars)、PyPI description/keywords/classifiers SEO 优化、Homepage 修正为项目 GitHub 地址。 + +### v1.0.5(2026-08-10) + +- **表情截图跨机器修复**:`EmojiMessage.capture()` 表情气泡自动裁剪全面重构: + - 主路径改用**连通域分析**(`_crop_last_bubble`),按消息方向(左=对方/右=自己) + 精确定位最后一条消息气泡,自动过滤细长竖条(滚动条/面板边框)、剔除头像类 + 小元素,从根源解决右缘滚动条/边框被当成内容导致的右侧大片空白; + - 圆形表情顶部/底部在缩放采样时因 LANCZOS 模糊丢失边缘像素:加大裁剪边距 + (`pad = max(10, scale*5)`)并在全分辨率下**逐像素边缘扩展**找回丢失内容, + 且扩展遇**连续空白行**(消息间分隔)即停,避免吃进相邻消息; + - 时间戳等居中小文字(水平居中约 50% 宽度)不再被误当成消息:方向判定加 + 阈值(左侧 <45% 宽度、右侧 >55%),居中元素两边都不匹配; + - 最终尺寸校验:`min(crop) < 50` 视为时间戳/文字误判,自动回退到 + 「消息分隔空白」「头像锚点」等备用定位,仍过小则判定失败返回 None; + - 本机与高 DPI 机器均已实测通过(完整表情、无空白、无切顶、不截时间戳)。 + +### v1.0.4(2026-08-10) + +- **多特征兜底窗口定位**:主窗口定位不再只依赖类名 `Qt51514QWindowIcon` + (类名降级为软条件),联合 进程名 `weixin.exe` / 窗口可见 / 大尺寸 + (≥800px)/ 标题关键词(微信/Weixin/WeChat)评分定位——Qt 升级改名 + (`Qt51514` → `Qt6xxx`)也不失效;渲染子窗口按前缀 `MMUIRenderSubWindow` + 匹配(兼容 `MMUIRenderSubWindowHW` / `MMUIRenderSubWindow` 等变体), + 找不到时退回用主窗口矩形计算坐标。 +- **布局自动校准**:首次运行自动校准——OCR 检测「搜索」「发送」锚点实测 + 布局比例,保存到 `~/.wechatauto/layout-<机器标识>.json`,之后自动加载; + 布局漂移(DPI/窗口尺寸/缩放变化)时自动重新校准。 +- **最大化状态保持**:激活窗口时先 `GetWindowPlacement` 记录状态,原为 + 最大化则用 `SW_SHOWMAXIMIZED` 恢复(原 `SW_RESTORE` 会把最大化窗口 + 缩成普通大小),最小化恢复不再破坏用户窗口布局。 +- **发送模块窗口兜底**:`find_main_window` 类名查找失败后按标题「微信」 + 兜底,适配类名不同的机器。 + +### v1.0.3(2026-08-08) + +- **文本消息还原**:微信 4.x 部分文本消息 content 为「容器头 + UTF-8 明文 + + 尾部填充」结构,此前显示为 `[文本]`/空。新增 `_extract_text_from_blob` + 还原明文,数据库读取与 bot 均可见真实内容(含群消息 `wxid_xxx:` 前缀)。 +- **表情截图方向感知与兼容性**:`_db_row_to_message` 写入 `msg.attr` + (`self`/`friend`),`EmojiMessage.capture()` 按方向定位气泡(自己发的用 + 消息分隔空白、对方发的用头像锚点),避免截图前自己又发了一条消息时误截到 + 自己的气泡;裁剪阈值自适应截图尺寸,跨分辨率/DPI 可用。微信 4.x 主窗口为 + Qt 自绘渲染,不暴露 UIA 子树,故截图定位全部基于屏幕像素分析。 +- **发送会话复用**:`send_msg` 记录 `_current_chat`,目标会话已打开时跳过 + `open_chat`(重扫侧栏+点击),逐条连续发送不再反复点击对话框,效率提升。 +- **搜索联系人选第一条**:`_search_chat` 按视觉顺序排序并过滤「搜索网络结果/ + 搜一搜」节标题,点选第一条联系人而非网络搜索。 +- **动画表情不再落盘伪 `.gif`**:`download_image` 识别到 `wxgf` 容器(微信 + 动画表情私有格式)时返回 `None`,不再生成打不开的假图片。 +- **`Listener.stop()` 崩溃修复**:`db.py` 补 `import sys`(`_run/_poll_once` + 使用 `sys.stderr` 却未导入)。 + +### v1.0.2(2026-08-08) + +- **表情消息支持**:新增 `EmojiMessage` 消息类型(`type='emotion'`), + "动画表情"不再被归为 `OtherMessage`,并按收发方向提供 + `FriendEmojiMessage` / `SelfEmojiMessage`。微信 4.x 表情消息在本地数据库中的 + content 为加密数据,无法直接还原成图片,因此新增 `EmojiMessage.capture()`: + 采用「打开会话 → 滚动到底 → 截取消息区 → 自动裁剪最后一条消息气泡」 + 的屏幕截图方案,返回图片路径,可直接供 AI 视觉识别使用 + (示例见 `demo_emoji_capture.py`)。 +- **监听器并发工作线程**:`Listener` 回调移到独立工作线程执行,每个被监听 + 会话对应一条**串行**工作线程——同一会话内消息按序处理、不同会话间并行; + 轮询线程只负责读取数据库并分派任务,不再被慢回调(AI 调用 / 图片识别等) + 阻塞,`stop()` 优雅关闭所有工作线程。 +- **数据库消息兼容增强**:`_db_row_to_message` 支持 bytes 类型 content + (自动解码还原文本)、`local_type` 缺失时自动推导消息类型, + `_extract_group_sender` 兼容 bytes 内容。 + +--- + +## 一、项目状态 + +| 能力 | 状态 | 实现方式 | +| ---- | ---- | -------- | +| 读取消息 | ✅ 已完成并验证 | 本地数据库解密(`wechatauto/db.py`) | +| 消息监听(轮询) | ✅ 已完成并验证 | `Listener` + `get_new_messages` 增量回调 | +| 表情消息识别与截图 | ✅ 已完成并验证(v1.0.3 方向感知) | `EmojiMessage` + `capture()`(屏幕截图自动裁剪) | +| WAL 增量合并 | ✅ 已修复并验证 | 帧盐校验合并 `-wal`(见 §2.4) | +| 历史消息全量导出 | ✅ 已完成并验证 | `export_history`(JSON / SQLite) | +| 媒体下载(图片/语音/文件) | ✅ 已完成并验证 | `wechatauto/media.py`(图片 V2 解密) | +| 朋友圈读取 | ✅ 已完成并验证 | `MomentDB` 直接读 `sns.db` | +| 多账号管理 | ✅ 已完成并验证 | `list_accounts()` + `account=` 参数 | +| 读取会话列表 | ✅ 已完成并验证 | 同上 | +| 搜索联系人 | ✅ 已完成并验证 | 同上 | +| 发送消息 | ✅ 已完成并验证 | UIA + 坐标+OCR 混合(`wechatauto/guia.py`) | +| 发送文件/图片/回复/艾特 | ✅ 已完成并验证 | 剪贴板 CF_HDROP + OCR | +| 语音通话 / 拍一拍 | ✅ 已完成并验证 | UIA 按钮 + OCR 菜单(`Chat.VoiceCall` / `Chat.Poke`) | +| UI 自动化(UIAutomation) | ✅ 热激活后可用 | 写 Weixin.dll Qt accessibility gate,物化 `mmui::*` 树 | + +**结论**:微信 4.1.x 聊天界面使用自绘渲染(`MMUIRenderSubWindow*`),冷启动 +对 UIAutomation 只暴露 `Qt51514QWindowIcon` 空壳(原 wxauto 的 UI 方案因此 +失效)。本项目通过**热激活 Qt accessibility gate**(写 Weixin.dll 内读屏 +标志位,从 `qt.accessibility.core` 引用扫描 RVA)物化 `mmui::*` UIA 树, +实现发送/语音通话/拍一拍等操作(UIA 优先、坐标+OCR 兜底);消息读取仍走 +「**本地数据库解密**」(已全链路验证)。 + +--- + +## 二、读取原理 + +微信 4.x 的数据存放在本地 SQLCipher 4 加密的 SQLite 数据库中: + +``` +D:\微信文件\xwechat_files\_xxxx\db_storage\ +├── contact\contact.db 联系人(昵称、备注) +├── session\session.db 会话列表(未读数、摘要) +├── message\message_0..4.db 聊天消息(按会话分表 Msg_,跨分库分片) +├── message\media_0.db 语音(VoiceInfo.voice_data,SILK 二进制) +├── message\message_resource.db 文件原名(MessageResourceDetail.packed_info) +├── sns\sns.db 朋友圈(SnsTimeLine,SnsDataItem XML) +└── ... +``` + +### 2.1 密钥提取(进程内存只读扫描) + +每个数据库有**独立的 32 字节密钥**,保存在微信进程内存中的 +`com.Tencent.WCDB.Config.Cipher` 配置对象里: + +1. 在 Weixin.exe 所有可读内存区域中查找该字符串; +2. 由字符串地址定位配置对象(`[ptr][len]` 结构回溯); +3. 数据块与固定掩码异或后得到 `x'<64位hex密钥><32位hex盐>'` 明文配置; +4. 用 SQLCipher 4 HMAC 校验规则验证每个候选密钥; +5. 验证通过的密钥保存到 `%TEMP%\wechatauto_db\<账号>\keys.json` 缓存。 + +### 2.2 数据库解密 + +- SQLCipher 4,页大小 4096,`PBKDF2-HMAC-SHA512`(加密密钥 256000 次迭代); +- 解密结果按页写入临时目录,校验源 mtime/size 复用缓存; +- 首次解密 contact.db 约 6s,之后全部秒级。 + +### 2.3 消息查询 + +- 会话名 → `Md5(会话微信号)` → 表名 `Msg_`(同一会话可能分片在多个 + `message_*.db`,按 `sort_seq` 合并排序); +- 关键列:`local_type`、`real_sender_id`(2=自己,其他为数字 id,可通过 + `message_resource.SenderName2Id` 反查微信号)、`server_id`、 + `packed_info_data`(图片/视频 md5)、`sort_seq`。 + +### 2.4 WAL 增量合并(已修复) + +微信 `-wal` 是预分配文件:checkpoint 时 WAL 头 salt+1 并清零写游标,但 +**旧世代帧仍留在文件中**。若合并时不过滤帧盐,会把过期页覆盖进主库导致 +`database disk image is malformed`。修复方案: + +- `_merge_wal` 读取 WAL 头后**仅合并 salt 与当前 WAL 头一致的帧**, + 旧世代帧直接跳过; +- 缓存 stamp 加入版本号 `STAMP_VERSION=2`,旧损坏缓存自动强制全量重建; +- 合并结果用 `PRAGMA integrity_check` 校验,失败自动重试全量重建。 + +验证:contact.db 合并后 integrity OK,2354 个联系人全部可查。 + +### 2.5 媒体存储与解密(图片 v2 格式) + +- 图片:`msg\attach\<会话md5>\\Img\.dat`(加密); +- 语音:`media_0.db` → `VoiceInfo.voice_data`(SILK 明文 BLOB); +- 文件:`msg\file\\<原文件名>`(原名来自 message_resource); +- 视频:`msg\video\\.mp4`(未落盘时返回 None)。 + +图片 `.dat` 为 **v2 格式**:`[6B sig 070856320807][4B aes_size LE][4B xor_size LE]` ++ AES-ECB 密文 + 明文段 + 异或段: + +- **AES 密钥**:16 字节 ASCII,账户级稳定密钥,但仅在微信查看图片时驻留 + 进程内存。`MediaDownloader` 通过内存扫描反测(AES 解首块后校验 JPEG/PNG + 魔数)获取,**命中后持久化到 `image_keys.json`**;也支持 `image_key=` 参数 + 显式注入。本机实测:单一密钥稳定解密 35/40 张随机图片(其余为微信动画 + 表情容器 `wxgf`)。 +- **XOR 密钥**:单字节,从同图缩略图 `_t.dat` 尾部 JPEG 结束标记 + `FF D9` 反推(`key = tail[0] ^ 0xFF`)。 + +--- + +## 三、快速开始 + +### 3.1 安装 + +```bash +pip install -e . +# 坐标+OCR 发送路线额外依赖: +pip install winsdk pypinyin +``` + +### 3.2 示例程序 + +```bash +python demo_db.py +``` + +### 3.3 代码示例 + +```python +from wechatauto import WeChatDB + +db = WeChatDB() # 自动检测账号与数据目录(微信需已登录) + +info = db.get_self_info() # 当前账号昵称 +for s in db.get_sessions(limit=10): # 会话列表 + print(db.get_nickname(s["username"]), s["unread"]) + +hits = db.search_contact("Ayi") # 搜索联系人 +who = hits[0]["username"] +for m in db.get_messages(who, limit=10): # 最近消息 + print(m["create_time"], m["sender_id"], m["type"], m["content"]) +``` + +### 3.4 媒体下载 + +```python +from wechatauto import WeChatDB, MediaDownloader + +db = WeChatDB() +md = MediaDownloader(db) # 可传 image_key="..." 注入图片密钥 +key = md.detect_image_key() # 内存扫描/缓存取 AES+XOR 密钥 +print(key) + +for m in db.get_messages("filehelper", limit=50): + out = md.download_media("filehelper", m["local_id"]) # 按类型自动分发 + if out: + print("已下载:", out) +``` + +### 3.5 朋友圈读取 + +```python +from wechatauto import WeChatDB, MomentDB + +md = MomentDB(WeChatDB()) +for feed in md.get_moments(limit=10): # 时间线(3382 条全量可读) + print(feed["nickname"], feed["text"]) + print(" 图片:", [i["md5"] for i in feed["images"]]) + print(" 赞:", [l["nickname"] for l in feed["likes"]]) + print(" 评论:", [(c["nickname"], c["content"]) for c in feed["comments"]]) + md.download_media(feed["images"][0]) # 本地缓存或 URL 拉取 +``` + +### 3.6 消息监听 + +```python +from wechatauto import WeChatDB +from wechatauto.db import Listener + +db = WeChatDB() +lst = Listener(db, interval=1.0) +lst.add_listener("filehelper", lambda msg, lst: print("新消息:", msg["content"])) +lst.start() +# ... 业务代码 ... +lst.stop() +``` + +- 回调在**独立工作线程**中执行(v1.0.2):每个被监听会话对应一条串行 + 工作线程,同一会话内消息按序处理、不同会话间并行;轮询线程只负责读取 + 数据库并分派任务,不会被慢回调(AI 调用 / 图片识别等)阻塞。 + +### 3.7 历史导出 + +```python +db.export_history(r"D:\backup\chat.json", fmt="json") # 全部会话 +db.export_history(r"D:\backup\chat.db", fmt="sqlite") +db.export_history(r"D:\backup\one.json", fmt="json", + users=["filehelper"], limit_per_chat=1000) +``` + +### 3.8 多账号 + +```python +from wechatauto import list_accounts, WeChatDB +for a in list_accounts(): + print(a["account"], a["wxid"]) +db2 = WeChatDB(account="wxid_xxx_abcd") # 显式指定账号(缓存按账号隔离) +``` + +### 3.9 表情消息与截图 + +微信 4.x 的"动画表情"消息在本地数据库中 content 为加密数据,无法直接还原成 +图片。v1.0.2 起监听回调中的表情消息为独立的 `EmojiMessage` 类型 +(`type='emotion'`,`FriendEmojiMessage` / `SelfEmojiMessage` 按收发方向区分), +并支持对屏幕上的表情气泡自动截图: + +```python +# 在 Listener 回调内,把消息 dict 转成消息对象后再截图: +def on_msg(msg, listener): + if msg["type"] == "动画表情": + from wechatauto.wx import _db_row_to_message + m = _db_row_to_message(msg, chat) # chat: 当前会话 + path = m.capture() # 返回 PNG 路径,供 AI 视觉识别 +``` + +`capture(save_dir=None)` 流程:打开会话(已打开则跳过,避免刷新消息列表导致 +控件失效)→ 滚动到底 → 截取消息区 → 按消息方向定位最后一条消息气泡: + +- **自己发的消息**(`attr='self'`,右侧无头像):用「消息分隔空白」定位 + 消息顶部,空白阈值按截图高度自适应(约消息区高度的 2.5%), + 跨分辨率/DPI 保持一致; +- **对方发的消息**(`attr='friend'`,左侧有头像):优先检测头像圆形彩色块 + 的顶部作为消息顶部(特征跨分辨率稳定),失败时回退消息分隔空白。 + +返回图片路径(失败返回 None)。独立示例:`python demo_emoji_capture.py`。 +调试时可保留 `~/pane_diag_raw.png`(每次截图保存的消息区原图)与 +`[CAP]` 日志行(截图尺寸、消息方向、裁剪路径、结果尺寸)用于排查。 + +--- + +## 四、API 参考 + +### `WeChatDB(db_dir=None, keys_file=None, workdir=None, account=None)` + +| 方法 | 说明 | +| ---- | ---- | +| `get_self_info() -> dict` | 当前账号(username / nick_name / remark) | +| `get_sessions(limit=100)` | 会话列表:username / unread / summary / last_time | +| `search_contact(keyword)` | 按昵称/备注/微信号搜索 | +| `get_messages(user, limit, offset)` | 读取指定会话消息 | +| `get_message_row(user, local_id)` | 单条原始消息(含 server_id / packed_info,媒体用) | +| `get_new_messages(user, since_seq)` | `sort_seq > since_seq` 的增量消息(升序) | +| `get_nickname(user)` | 微信号 → 显示昵称 | +| `list_message_chats()` | 所有含消息的会话(md5 / 昵称 / 消息数) | +| `export_history(out_path, fmt, ...)` | 全量导出 JSON / SQLite | +| `extract_keys()` | 手动触发密钥提取 | +| `wxid` / `account` / `account_dir` | 当前账号信息 | +| `list_accounts()`(模块级) | 扫描本机所有微信账号 | +| `auto_detect_db_dir()`(模块级) | 自动定位数据目录(配置文件 → 注册表 → 常见默认目录) | + +### `MediaDownloader(db, save_dir=None, image_key=None)` + +| 方法 | 说明 | +| ---- | ---- | +| `detect_image_key(refresh)` | 取 (AES 密钥, XOR 密钥),命中后持久化 | +| `decrypt_image(dat_path)` | 解密单个 `.dat`(自动识别 v1/v2) | +| `download_media(user, local_id)` | 按类型分发下载 | +| `download_image / _voice / _video / _file` | 各类媒体下载 | +| `copy_files_to_clipboard(paths)` | CF_HDROP 写剪贴板(发送附件用) | + +### `MomentDB(db)` + +| 方法 | 说明 | +| ---- | ---- | +| `get_moments(limit, offset, username)` | 朋友圈时间线(最新在前) | +| `get_moment(tid)` / `get_my_moments(limit)` | 单条 / 我的动态 | +| `find_local_media(md5, kind)` | 本地缓存查找(Sns\Img / Sns\Video) | +| `download_media(media, save_dir)` | 缓存优先,否则 URL 拉取 | + +### `Listener(db, interval, watermark)` + +`add_listener(user, cb)` / `remove_listener` / `start` / `stop` / `watermark`。 + +### `WeChatGUI`(发送,锁屏不可用) + +| 方法 | 说明 | +| ---- | ---- | +| `send_msg(text, who, verify)` | 文本发送(OCR 定位 + 剪贴板粘贴) | +| `send_file(path, who, verify)` | 文件(CF_HDROP 粘贴 + 回车) | +| `send_image(path, who, verify)` | 图片(同上) | +| `reply_msg(text, who, verify)` | 回复最近消息(悬停 + OCR 回复入口) | +| `at_member(member, text, who, verify)` | 群聊 @ 成员 | +| `open_chat / focus_input / bring_to_front` | 基础操作 | + +一行式:`quick_send` / `quick_send_file` / `quick_send_image` / `quick_reply`。 + +--- + +## 五、已知限制 + +1. **需要微信登录**:数据库密钥存于进程内存,首次使用需微信运行中 + (提取后本地缓存);重新登录后密钥变化需重新提取(自动校验失败重扫); +2. **图片 AES 密钥瞬态**:仅在微信查看图片时驻留内存;`MediaDownloader` + 扫描命中后会持久化(`image_keys.json`),也可用 `image_key=` 显式传入; +3. **发送为 GUI 操作**:锁屏/会话断开时 `desktop_available()` 返回 False, + 发送接口返回明确失败;文件/图片/回复/艾特代码已完成但需桌面解锁后实测; +4. **视频文件未落盘时不可下载**:视频 mp4 仅在本地存在(`msg/video`)时 + 返回,否则返回 None; +5. **发朋友圈功能已舍弃**:4.x 的发表为自绘界面操作,不可靠自动化; + 本库仅保留朋友圈读取/点赞/评论能力。 + +--- + +## 六、发送消息(坐标 + OCR) + +微信 4.1.12+ 聊天界面自绘渲染、无无障碍节点,发送走 +「屏幕坐标 + 本地 OCR」(`wechatauto/guia.py`): + +1. **多特征兜底定位**主窗口(类名 `Qt51514QWindowIcon` 只是「软条件」, + 联合标题 / 进程名 `weixin.exe` / 可见 / 大尺寸评分,Qt 升级改名也不 + 失效),再按前缀 `MMUIRenderSubWindow` 找渲染子窗口(兼容 + `MMUIRenderSubWindowHW` / `MMUIRenderSubWindow` 等不同版本类名; + 找不到时回退用主窗口矩形计算坐标); +2. 布局用渲染子窗口相对坐标描述,运行时换算为屏幕绝对坐标;首次运行自动 + 校准(OCR 检测「搜索/发送」锚点实测比例),保存到 + `~/.wechatauto/layout-<机器>.json`,之后自动加载、布局漂移自动重校准; +3. OCR 识别会话列表点击目标(失败走搜索框;生僻字/小字号会话名自动放大 + 3 倍 + 多轮投票重扫,搜索回退只点联系人、自动排除群聊与群成员预览行); +4. 扫描输入框白色区定位并聚焦; +5. 文字以「剪贴板 + Ctrl+V」输入(避免中文输入法拦截),失败回退拼音组合; +6. OCR 定位「发送」按钮(找不到回退回车键); +7. `verify=True` 时用 `WeChatDB` 读回确认。 + +文件/图片通过 **CF_HDROP 剪贴板 + Ctrl+V** 插入草稿再回车发送,绕开自绘 +「+ 菜单」定位;回复/艾特分别走悬停 OCR 工具栏与成员弹层 OCR。 + +```python +from wechatauto.guia import quick_send, quick_send_file +quick_send('你好', '文件传输助手', verify=True) +quick_send_file(r'D:\资料\报告.pdf', '文件传输助手') +``` + +> 注意:OCR 需要系统语言包含中文(`Windows.Media.Ocr`)。 + +--- + +## 七、后续路线 + +1. **发送功能实测**:桌面解锁后校准 guia 各坐标常量,验证文件/图片/回复/艾特; +2. **视频消息下载增强**:微信 4.x 聊天视频存储位置仍需确认(本机无样本); +3. **性能优化**:导出/首扫并行化,内存扫描增量缓存。 + +--- + +## 八、目录结构 + +``` +├── wechatauto/ +│ ├── wx.py UIA 自动化入口(4.x 受限) +│ ├── guia.py ★ 坐标+OCR 发送模块(文本/文件/图片/回复/艾特) +│ ├── db.py ★ 数据库读取(密钥提取 + 解密 + WAL 合并 + 导出 + 监听) +│ ├── media.py ★ 媒体下载(图片 v2 解密 / 语音 / 视频 / 文件) +│ ├── moment.py ★ 朋友圈(MomentDB 数据库路线 + 旧 UIA 兼容) +│ ├── ui/ UI 控件层 +│ ├── msgs/ 消息模型 +│ └── ... +├── demo.py UI 自动化示例(微信 4.1 上受限) +├── demo_db.py ★ 数据库读取示例(推荐) +├── demo_guia.py ★ 坐标+OCR 发送示例 +├── demo_listen.py ★ 实时消息监听示例 +├── demo_reply_at.py ★ 回复/@ 成员实测示例 +├── demo_emoji_capture.py ★ 表情消息截图示例 +├── docs/技术文档.md ★ 完整技术文档(架构/原理/API/扩展) +└── pyproject.toml +``` + +## 九、免责声明 + +本项目仅用于个人学习与自动化研究,请遵守微信软件许可协议及当地法律法规, +勿用于任何违反规定的用途。 + + +注:本库完全由AI(opencode+deepseek-v4-flash)生成 + +--- + +## 十、联系方式 + +- 邮箱:fanyuantaier@163.com + +--- + +## 🇬🇧 English + +### wechatauto-replica — WeChat 4.x Windows Automation (wxauto-compatible) + +![PyPI version](https://img.shields.io/pypi/v/wechatauto-replica) +![PyPI downloads](https://img.shields.io/pypi/dw/wechatauto-replica) +![Python](https://img.shields.io/pypi/pyversions/wechatauto-replica) +![License](https://img.shields.io/github/license/fanyuantaier/wechatauto-replica) +![GitHub stars](https://img.shields.io/github/stars/fanyuantaier/wechatauto-replica) + +Automate the **WeChat 4.x Windows desktop client** (not the web version): read messages, listen in real time, download media, export full history, read Moments (朋友圈), and send messages — by driving the local client directly. + +> **Current version:** 1.1.7 · Windows 10/11 · Python 3.9+ (verified on 3.12) · WeChat **4.1.12+** +> +> **Why this project exists:** the classic [wxauto](https://github.com/cluic/wxauto) relies on the UI Automation tree, which WeChat 4.x broke with self-drawn rendering (no accessibility nodes). wechatauto-replica is a drop-in-style replacement: messages are read through **local database decryption** (SQLCipher 4), and sending uses a **UIA + OCR hybrid** driver that auto-falls back between engines. + +![Reading encrypted WeChat 4.x databases](docs/demo_db_files.gif) + +*Reading the encrypted `contact.db` / `message_*.db` / `sns.db` files directly from `xwechat_files/.../db_storage/` — no web API, all local.* + +## ✨ Features + +| Capability | Status | How | +|---|---|---| +| Read messages | ✅ verified | Local SQLCipher 4 DB decryption (`wechatauto/db.py`) | +| Real-time message listening | ✅ verified | `Listener` incremental polling, per-chat worker threads | +| Emoji message capture | ✅ verified | Screen capture + direction-aware bubble auto-cropping | +| Full history export | ✅ verified | JSON / SQLite | +| Media download (image / voice / file) | ✅ verified | `MediaDownloader`: image v2 AES decryption, SILK voice, files | +| Moments (朋友圈) read | ✅ verified | Direct `sns.db` reads (3382 feeds verified) | +| Multi-account | ✅ verified | `list_accounts()` + `account=` | +| Send text / file / image / reply / @member | ✅ verified | UIA-first, coordinate + OCR fallback | +| Voice call / Poke (拍一拍) | ✅ verified | UIA buttons + OCR menus | +| UIAutomation tree | ✅ after hot-activation | Writes the Qt accessibility gate inside Weixin.dll | + +## 🚀 Quick Start + +```bash +pip install -e . +# extra deps for the OCR sending path: +pip install winsdk pypinyin +``` + +### Read messages + +```python +from wechatauto import WeChatDB + +db = WeChatDB() # auto-detects account & data dir (WeChat must be logged in) + +info = db.get_self_info() # current account +for s in db.get_sessions(limit=10): # session list + print(db.get_nickname(s["username"]), s["unread"]) + +hits = db.search_contact("Ayi") # search contacts +for m in db.get_messages("filehelper", limit=10): # recent messages + print(m["create_time"], m["sender_id"], m["type"], m["content"]) +``` + +### Send a message + +```python +from wechatauto.guia import quick_send, quick_send_file + +quick_send("Hello", "filehelper", verify=True) # verify=True reads back from DB +quick_send_file(r"D:\report.pdf", "filehelper") +``` + +### Real-time listening + +```python +from wechatauto import WeChatDB +from wechatauto.db import Listener + +db = WeChatDB() +lst = Listener(db, interval=1.0) +lst.add_listener("filehelper", lambda msg, lst: print("new:", msg["content"])) +lst.start() +# ... your code ... +lst.stop() +``` + +Callbacks run on dedicated per-chat worker threads: messages in one chat are processed in order, different chats in parallel; slow callbacks (AI calls, image recognition) never block the poller. + +### Media & Moments + +```python +from wechatauto import WeChatDB, MediaDownloader, MomentDB + +db = WeChatDB() +md = MediaDownloader(db) +md.detect_image_key() # scan process memory for the image AES key (persisted after first hit) +for m in db.get_messages("filehelper", limit=50): + out = md.download_media("filehelper", m["local_id"]) + if out: + print("downloaded:", out) + +moments = MomentDB(db) +for feed in moments.get_moments(limit=10): + print(feed["nickname"], feed["text"]) + print(" images:", [i["md5"] for i in feed["images"]]) + print(" likes:", [l["nickname"] for l in feed["likes"]]) + print(" comments:", [(c["nickname"], c["content"]) for c in feed["comments"]]) +``` + +## 🧠 How It Works + +- **Reading** — WeChat 4.x stores everything in SQLCipher 4 encrypted SQLite databases under `xwechat_files//db_storage/` (`contact.db`, `message_*.db`, `media_0.db`, `sns.db`, …). Each DB has its own 32-byte key living in the Weixin.exe process memory (`com.Tencent.WCDB.Config.Cipher` config objects). The library locates them with a **read-only memory scan**, validates candidates with SQLCipher HMAC rules, decrypts pages to a temp dir and caches the result (first decrypt ~6s, then instant). WAL incremental merging with frame-salt filtering prevents `database disk image is malformed` corruption. +- **Sending** — WeChat 4.x chat UI is self-drawn (no accessibility nodes), so sending uses a hybrid driver: hot-activate the **Qt accessibility gate** inside Weixin.dll (RVA scan, writes the screen-reader flag) to materialize the `mmui::*` UIA tree — search box, `chat_input_field`, etc. Sending is **UIA-first, coordinate + OCR fallback**: auto-calibrating layout (`~/.wechatauto/layout-.json`), zoomed OCR (3x) with multi-round voting for rare Chinese characters, clipboard + Ctrl+V input to dodge IME interception. +- **Media** — image `.dat` files are `[6B sig][4B aes_size][4B xor_size] + AES-ECB + plaintext + xor` chunks. The account-level AES key is transient (only resident in memory while viewing an image); `MediaDownloader` scans for it, validates via JPEG/PNG magic, and **persists it to `image_keys.json`** so later runs need no scanning (or pass `image_key=` explicitly). Voice is plain SILK read from `media_0.db`; files are read from `msg/file/` with original names resolved from `message_resource.db`. + +## ⚖️ vs wxauto + +| | wxauto | wechatauto-replica | +|---|---|---| +| WeChat 4.x | ❌ UIA tree gone → broken | ✅ DB decryption + UIA hot-activation | +| Message reading | via UI tree | via local DB (full history, faster) | +| Sending | UIA clicks | UIA-first + OCR fallback | +| Media | limited | image AES decrypt, SILK voice, files | +| Moments | read | read (posting dropped: self-drawn UI) | + +## ⚠️ Known Limitations + +1. **WeChat must be logged in** — DB keys live in process memory; cached after first extraction, re-extracted automatically after re-login. +2. **Image AES key is transient** — only resident while viewing an image; persisted to `image_keys.json` once found, or inject via `image_key=`. +3. **Sending is a GUI operation** — fails cleanly when the desktop is locked (`desktop_available()` returns False). +4. **Videos** are downloadable only when the mp4 already exists on disk (`msg/video/`). +5. **Group-chat image originals** are stored locally only after being opened (viewed) in WeChat; until then only the thumbnail (`_t.dat`) exists — `download_image` falls back to the thumbnail (marked `_thumb` in the filename). +6. **Moments posting is dropped** (4.x self-drawn UI, unreliable); reading/likes/comments are supported. + +## 🗺️ Roadmap + +- Calibrate and verify file/image/reply/@ sending on unlocked desktops +- Video message download (4.x storage location TBD) +- Performance: parallel export / first-scan, incremental memory-scan cache + +## 📝 Changelog + +### v1.1.7 (2026-08-22) +- **Master-key based key extraction (PR #10, thanks [NothingFumo](https://github.com/NothingFumo))**: instead of scanning process memory for per-DB `Config.Cipher` literals (which fails on WeChat 4.1.12.26+), we now extract the **single master key** from the `cfg` structure (`cfg+0x2B8` cipher XORed with 4×movabs constants from the DLL) and **derive each DB key offline** via `PBKDF2-HMAC-SHA512(master_key, db_salt, 256000)` — 27/27 SQLCipher4 DBs verified. This fixes key extraction on 4.1.12.26+ (issues #3 / #7). +- **Unified image-key pipeline**: template collection (`*_t.dat`, top 16 by mtime) → tail-byte majority XOR (replaces the old single-file probe that could wrongly fall back to `0x88`) → `cfgDword` derivation (deterministic, offline) preferred, with injected/cached/memory-scan AES fallbacks. Probe-verified on 3000/3000 real ciphertexts. +- **Account fields from cfg**: `WeChatDB` now also returns `name` / `number` / `phone` alongside the master key, matching the output format of mainstream key tools. +- New optional params `master_key` / `cfg_dword` are fully backward compatible — if not passed, the original path is used. Core decryption functions unchanged. + +### v1.1.6.1 (2026-08-20) +- **PyPI description fix**: v1.1.6 was uploaded without the synced `README_pypi.md` (description still showed 1.1.5.1); this patch restores the full v1.1.6 changelog and bumps the version marker. + +### v1.1.6 (2026-08-20) +- **Auto-diagnosis on missing key**: `数据库无可用密钥` now runs a built-in check before raising — Python bitness (32-bit can't read 64-bit Weixin memory), per-PID `OpenProcess`/`ReadProcessMemory` permission, and multi-account mismatch (all `wxid_*` dirs vs. picked account, suggesting `WeChatDB(account=...)`). No need to run `diagnose_keys` first. +- **New diagnostic tool**: `wechatauto/diagnose_keys.py` (`python -m wechatauto.diagnose_keys`, WeChat logged in) dumps lib version, Python bitness, Weixin PIDs with per-process read-permission checks, all accounts vs. picked account, cached keys, fresh in-memory extraction, and key verification — paste the output when reporting key-extraction failures. +- **Skip `migrate\unspportmsg.db`**: WeChat's reserved "unsupported message" DB has no in-memory key and is never queried; it was forcing a full process-memory scan on every init. + +### v1.1.5.1 (2026-08-18) — beta +- **Fix real-time listening**: `WeChatDB.get_new_messages()` referenced an undefined `found` (NameError swallowed by `Listener._poll_once`), so **no** message callbacks ever fired — including first messages from contacts you had never chatted with. +- **Dynamic message shards**: `_message_dbs()` now re-scans the disk so shards WeChat creates at runtime (e.g. `message_5.db`) are picked up and their keys extracted automatically. + +### v1.1.5 (2026-08-18) +- **Version cleanup**: normalized the patch version (1.1.4.2 → 1.1.5) after the `media_*.db` voice fix. + +### v1.1.4.2 (2026-08-18) +- **PyPI description cleanup**: removed the demo default-group changelog line from the PyPI description. + +### v1.1.4.1 (2026-08-18) +- **PyPI readme bilingual**: merged the Chinese (`README.zh-CN.md`) and English (`README.md`) into one PyPI description so the Chinese version is visible on the package page. + +### v1.1.4 (2026-08-18) +- **Voice download across all media databases**: `download_voice()` now searches every `media_*.db` (not just `media_0.db`) — WeChat shards voice data across multiple media DBs; previously voices stored in `media_1.db` etc. could not be found (thanks uiharukazari0105). +- **`demo_media.py --images N`**: download the latest N images of a chat directly from the DB (by local_type), bypassing the total-message `--limit` — no more "only a few images listed" when a group has thousands of messages. +- **`WeChatDB._find_media_rows(user, types)`**: new helper returning all media local_ids of a chat for a set of local_types (batch download). +- **Group-chat image thumbnail fallback**: original images in group chats are only downloaded after being opened in WeChat; `download_image` now falls back to the thumbnail (`_t.dat`) when the original is missing, saving it with a `_thumb` suffix. + +### v1.1.3 (2026-08-17) + +### v1.1.2 (2026-08-16) +- **UIA driver thread-safety**: `WeChatUIA` now initializes COM on the current thread (`CoInitializeEx`, idempotent) — fixes crashes when instantiated from background threads / host apps (e.g. WeChatBot) with "CoInitialize not called / cannot load UIAutomationCore.dll" errors. +- **Main-window filtering**: only windows whose process loaded `Weixin.dll` are considered — auxiliary processes without the DLL (whose hot-activation always fails) no longer produce noise warnings. +- **Forward-voice fix**: `Chat.ForwardVoiceMessage` uses `self` when no target is given (the previous `_cur()` could resolve the wrong chat). +- **Re-entrant UI lock**: `LockManager` is now re-entrant per thread — `@uilock` functions calling each other (e.g. `ForwardVoiceMessage` → `VoiceMessage.forward_to`) no longer deadlock. + +### v1.1.1 (2026-08-16) +- **Recall last message** (`Chat.RecallLastMessage` / `uia_driver.recall_last_message`): right-click the latest own message → UIA-first menu-item click (`mmui::XMenuView` found inside the main-window subtree), OCR fallback; fails cleanly when the 2-minute recall window has passed (menu only shows "Delete"). +- UIA robustness: menu-item lookup scoped to the main-window subtree (avoids the Windows UIA root-traversal hang), removed the fragile `WindowControl(ClassName=...)` fallback. +- Media fix: video id bytes→str decoding in `MediaDownloader`. +- `demo_media.py --photos` default 3 → 10. + +### v1.1.0 (2026-08-15) +- **Image AES key auto-capture** (`media.py`): the V2 image key is only resident in memory while viewing an image (~5 min). `_scan_aes_key()` gained a `monitor` mode — polls continuously and persists the key to `image_keys.json` once found; users just open one image to finish setup. +- Fixed the process-ordering scan bug (removed the memory-usage sort that pushed the main process last). +- **Forward voice messages**: SILK extraction from `media_0.db` + file-message send (`demo_forward_voice.py`). +- New demos: `demo_group_messages.py` (group + red-packet ZSTD parsing), `demo_robust.py`. + +## 🤝 Acknowledgments + +Thanks to [vesio](https://github.com/vesio) for sharing the WeChat 4.1.12 UIA control-tree approach and debugging ideas in [issue #1](https://github.com/fanyuantaier/wechatauto-replica/issues/1) — it made the UIA hybrid driver (v1.0.8) possible. + +Thanks to [nanshanjack](https://github.com/nanshanjack) for finding the UI-lock re-entrancy problem (fixed in v1.1.2). + +Thanks to [maozhitao12450](https://github.com/maozhitao12450) for reporting the WXAM (wxgf) image download issue (fixed in v1.1.3). + +Thanks to [uiharukazari0105](https://github.com/uiharukazari0105) for finding that voice data stored in `media_1.db` (and later) was never searched (fixed in v1.1.4). + +## 📄 License & Disclaimer + +Apache-2.0. This project is for personal learning and automation research only — please respect the WeChat software license agreement and applicable laws. + +Contact: fanyuantaier@163.com diff --git a/diagnose.py b/diagnose.py new file mode 100644 index 0000000..46640c1 --- /dev/null +++ b/diagnose.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +"""诊断:自己的 wxid、会话类型、最近消息 sender_id 结构""" +import sys, os, time +os.chdir(os.path.dirname(os.path.abspath(__file__))) +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) +try: + os.system("chcp 65001 >nul 2>&1") + sys.stdout.reconfigure(encoding="utf-8", errors="replace") +except Exception: + pass + +from wechatauto.db import WeChatDB + +db = WeChatDB() +info = db.get_self_info() +print("=== 自己 ===") +print("username:", info.get("username")) +print("nick_name:", info.get("nick_name")) + +print("\n=== 会话列表(前 40 个,标注类型)===") +sessions = db.get_sessions(limit=40) +for s in sessions: + u = s["username"] + kind = "群聊" if u.endswith("@chatroom") else ("文件助手" if u == "filehelper" else "好友/其他") + print(f"[{kind}] {u} 未读={s['unread']} 摘要={ (s['summary'] or '')[:20]}") + +print("\n=== 找 1 个好友会话,看最近 5 条消息的 sender_id 结构 ===") +for s in sessions: + u = s["username"] + if u.endswith("@chatroom") or u == "filehelper": + continue + msgs = db.get_messages(u, limit=5) + if not msgs: + continue + nick = db.get_nickname(u) + print(f"\n好友会话: {u} (昵称/备注={nick})") + for m in reversed(msgs): + sid = m["sender_id"] + me = "★自己" if (str(sid) == "2" or str(sid) == str(info.get("username"))) else "对方" + print(f" sender_id={sid!r} {me} | {m['type']} | {str(m['content'])[:30]}") + break diff --git a/diagnose_sender.py b/diagnose_sender.py new file mode 100644 index 0000000..7a01da5 --- /dev/null +++ b/diagnose_sender.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +"""实测 sender_id:get_messages 与 Listener 回调两条路径的真实值""" +import sys, os, tempfile, time, threading +BASE = r"C:\Users\Administrator\wechatauto-replica" +os.chdir(BASE) +sys.path.insert(0, BASE) +try: + sys.stdout.reconfigure(encoding="utf-8", errors="replace") +except AttributeError: + pass + +from wechatauto.db import WeChatDB, Listener + +wd = tempfile.mkdtemp(prefix="diag_sid_") +db = WeChatDB(workdir=wd) +info = db.get_self_info() +self_wxid = info.get("username") +print("SELF wxid:", self_wxid, "| nick:", info.get("nick_name")) + +# 路径1:get_messages 的 sender_id +who = "wxid_yxnyrj5sul1g22" +try: + msgs = db.get_messages(who, limit=12) + print("\n[get_messages] 好友", who, "最近", len(msgs), "条:") + for m in reversed(msgs): + sid = str(m.get("sender_id")) + me = "★自己" if (sid == "1" or sid == self_wxid) else "对方" + print(f" sender_id={sid!r} {me} | {m.get('type')} | {str(m.get('content'))[:28]}") +except Exception as e: + print("get_messages ERR:", repr(e)) + +# 路径2:Listener 回调的 sender_id(真实监听一条,看回调字段) +print("\n[Listener] 用 add_listener 监听该好友,等 3s 观察 watermark 初始化…") +seen = {} +lst = Listener(db, interval=1.0) + +def on_msg(m, l): + sid = str(m.get("sender_id")) + print(" Listener 回调 sender_id=%r | content=%r" % (sid, str(m.get("content"))[:30])) + +lst.add_listener(who, on_msg) +lst.start() +time.sleep(3) +lst.stop() +print("[Listener] 结束(若无新消息则无回调输出,属正常)") diff --git a/docs/demo_db_files.gif b/docs/demo_db_files.gif new file mode 100644 index 0000000000000000000000000000000000000000..54930fe8e89c544de0a631b036dc825e0f75371f GIT binary patch literal 546546 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�ji?P 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

Y49@TZjN@Md^u)a0dR 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 literal 0 HcmV?d00001 diff --git a/docs/技术文档.md b/docs/技术文档.md new file mode 100644 index 0000000..dbe591c --- /dev/null +++ b/docs/技术文档.md @@ -0,0 +1,514 @@ +# wechatauto 技术文档 + +> 版本:1.0.6 | 适用:微信 4.x Windows 客户端 | 语言:Python 3.9+ +> 本文档描述 wechatauto 的设计原理、内部实现与扩展方式,面向二次开发与排障。 + +--- + +## 1. 项目概述 + +wechatauto 是上游 [wxauto](https://wxauto.org) 的复刻版,面向**微信 4.x +Windows 客户端**的自动化库。它**不是网页版**,直接操作本机客户端。 + +与老版本微信(3.x,暴露 UIAutomation 无障碍树)不同,微信 4.1.12+ 的聊天 +区域采用**自绘渲染**(`MMUIRenderSubWindow*`,不同版本后缀不同,如 +`MMUIRenderSubWindowHW` / `MMUIRenderSubWindow`),对 UIAutomation / MSAA 完全 +不暴露内容。因此本项目拆成两条技术路线: + +| 路线 | 模块 | 用途 | +| ---- | ---- | ---- | +| 本地数据库解密 | `wechatauto/db.py` | 读取消息、监听、历史导出、会话/联系人 | +| 坐标 + OCR | `wechatauto/guia.py` | 发送文本/文件/图片、回复、@成员 | + +外加两个独立子系统:媒体下载(`media.py`)、朋友圈读取(`moment.py`)。 + +--- + +## 2. 总体架构 + +``` + ┌────────────────────────────────────────────┐ + │ wechatauto │ + ├──────────────┬─────────────┬───────────────┤ + 读取/监听/导出 │ wechatauto │ wechatauto │ wechatauto │ 发送/回复/@ + ┌──────────────┐ │ db.py │ media.py │ guia.py │ ┌────────────┐ + │ Listener │ │ (SQLCipher4) │ (媒体解密) │ (坐标+OCR) │ │ WeChatGUI │ + │ MomentDB │ └──────────────┴─────────────┴───────────────┘ └────────────┘ + │ msgs/ ui/ │ │ │ │ + └──────┬───────┘ │ │ │ + ▼ ▼ ▼ ▼ + contact/session/message_*.db msg\attach\*.dat 屏幕截取 + Win32 微信主窗口 + sns.db(SQLCipher 4) media_0.db 用户输入(SendInput) (MMUIRender…) +``` + +### 2.1 模块职责 + +| 模块 | 职责 | +| ---- | ---- | +| `db.py` | 微信数据库密钥提取、SQLCipher 4 解密、WAL 增量合并、消息查询/监听/导出、会话/联系人 | +| `guia.py` | 坐标 + OCR 发送:窗口定位、会话点击、输入框探测、剪贴板粘贴、发送按钮、发送后 DB 验证 | +| `media.py` | 图片 v2 解密(AES+XOR)、语音/视频/文件下载、剪贴板 CF_HDROP | +| `moment.py` | 朋友圈时间线读取、媒体下载(`MomentDB` 数据库路线) | +| `wx.py` | 高层 API 入口(`WeChat`/`Chat`/`Listener`),内部按能力分派到 DB 或 GUI | +| `msgs/` | 消息对象模型(文本/图片/语音/引用/系统消息等) | +| `ui/` | 老版 UIAutomation 控件层(微信 3.x 遗留,4.x 受限,保留兼容) | +| `utils/` | `win32.py`(窗口/剪贴板/进程)、`lock.py`(全局 UI 锁)、`tools.py` | +| `param.py` | `WxParam`/`WxResponse`/`PROJECT_NAME` 等公共参数与返回类型 | + +--- + +## 3. 数据库读取子系统(`wechatauto/db.py`) + +### 3.1 数据存储布局 + +微信 4.x 数据位于登录目录下。**不同电脑/账号的目录位置不同**,由 +`auto_detect_db_dir()` 自动定位,探测链(`db.py`): + +1. **微信配置文件**:扫描 `%APPDATA%`/`%LOCALAPPDATA%` 下 + `Tencent\xwechat`、`Tencent\WeChat` 等配置目录内的**所有文件**,内容支持 + JSON(`dataDir`/`fileSavePath` 等字段)、纯路径、或任意文本中提取第一个 + Windows 路径(`_extract_path_from_config`); +2. **注册表**:读 `HKCU\Software\Tencent\xwechat` 等键下含 + path/dir/save 的值(用户自定义保存位置时的补充来源); +3. **常见默认目录**:`Documents`、用户主目录兜底。 + +定位结果统一经 `_locate_account_root()` 归一化:兼容 +`/xwechat_files/_xxxx/db_storage` 与 +`/_xxxx/db_storage` 两种布局,返回包含 `wxid_*` 账号目录的 +父目录(即 `WeChatDB.db_dir`)。仍找不到时可手动传入 `db_dir=` 指定。 + +典型布局: + +``` +D:\微信文件\xwechat_files\_xxxx\db_storage\ +├── contact\contact.db 联系人(昵称、备注、别名) +├── session\session.db 会话列表(未读数、摘要、排序时间戳) +├── message\message_0..4.db 聊天消息(按会话分表 Msg_,跨库分片) +├── message\media_0.db 语音(VoiceInfo.voice_data,SILK 二进制) +├── message\message_resource.db 文件原名(MessageResourceDetail.packed_info) +├── sns\sns.db 朋友圈(SnsTimeLine、SnsDataItem XML) +└── ... +``` + +每个数据库都是 **SQLCipher 4** 加密的 SQLite:页大小 4096、 +`PBKDF2-HMAC-SHA512`(加密密钥迭代 256000 次),每页 IV(16) + HMAC(80)。 + +### 3.2 密钥提取(进程内存只读扫描) + +每个数据库有**独立的 32 字节密钥**,运行时保存在微信进程 +`com.Tencent.WCDB.Config.Cipher` 配置对象中。`extract_keys()` 流程: + +1. 用 `psutil` 枚举 `Weixin.exe` 进程,取可读内存区域; +2. 定位字符串 `com.Tencent.WCDB.Config.Cipher` 的内存地址; +3. 从字符串地址回溯配置对象(`[ptr][len]` 结构),读取数据块; +4. 数据块与固定掩码(`CONFIG_XOR_MASK`)逐字节异或,得到明文配置: + `x'<64位hex密钥><32位hex盐>'`; +5. 用 SQLCipher 4 的 HMAC 校验规则验证候选密钥(取某库首页试解); +6. 通过后写入 `%TEMP%\wechatauto_db\<账号>\keys.json` 缓存, + 之后进程内复用(`_cached_db`),无需每次重新扫描。 + +### 3.3 数据库解密 + +- SQLCipher 4,`PAGE_SZ=4096`,页尾 `RESERVE_SZ=80` 保留字节 + (IV 16 + HMAC 64); +- 解密结果按页写入临时工作目录;通过比对源文件 mtime/size 的 stamp + (`STAMP_VERSION=2`,含缓存格式版本号)判定是否可复用缓存; +- 首次解密 contact.db 约 6s,之后全部秒级; +- 每次打开连接前用 `PRAGMA integrity_check` 兜底,损坏时自动全量重建。 + +### 3.4 WAL 增量合并(帧盐校验) + +微信 `-wal` 是**预分配文件**:checkpoint 时 WAL 头 salt+1 并清零写游标, +但**旧世代帧仍留在文件中**。若合并时不过滤帧盐,会把过期页覆盖进主库, +导致 `database disk image is malformed`。修复方案(`_merge_wal`): + +1. 读取 WAL 头 `salt1/salt2`; +2. 仅合并 **salt 与当前 WAL 头一致**的帧,旧世代帧直接跳过; +3. 合并结果 `PRAGMA integrity_check` 校验,失败自动回退全量重建; +4. 缓存 stamp 版本升级到 2,旧格式缓存强制重建。 + +### 3.5 消息分片与查询 + +- 会话名 → `Md5(会话微信号)` → 表名 `Msg_`; +- 同一会话可能分片在多个 `message_*.db`,查询时按 `sort_seq` 合并排序; +- 关键列: + - `local_type` → 消息类型(见 `MSG_TYPE_NAMES`); + - `real_sender_id`:`2` 表示自己,其他为数字 id,可经 + `message_resource.SenderName2Id` 反查微信号; + - `server_id`:服务端消息 id; + - `packed_info_data`:图片/视频 md5 等二进制载荷; + - `sort_seq`:会话内单调递增序号(增量游标用); +- `get_messages(user, limit, offset)` 倒序取最近消息; +- `get_message_row(user, local_id)` 取含 `packed_info` 的原始行(媒体用); +- `get_new_messages(user, since_seq)` 返回 `sort_seq > since_seq` 的增量, + 升序排列。 + +### 3.6 增量消息与水印 + +`Listener` 每个被监听会话维护一个 `watermark`(最近一次 `sort_seq`)。 +轮询时以水印为游标取增量,成功后把水印推进到 `msgs[-1]["sort_seq"]`, +保证不重不漏。回调签名 `callback(msg: dict, listener)`。 + +### 3.7 会话 / 联系人 / 导出 + +- `get_sessions(limit)`:读 `session.db` 的 `SessionTable` + (`username/unread/summary/last_time/last_sender`); +- `search_contact(keyword)`:对 contact.db 按 昵称/备注/微信号/别名 模糊匹配; +- `get_nickname(user)`:微信号 → 显示昵称(内部维护昵称/发送者索引); +- `export_history(out, fmt, users, limit_per_chat)`:全量导出 + JSON / SQLite,支持指定会话与条数上限。 + +--- + +## 4. 媒体下载子系统(`wechatauto/media.py`) + +### 4.1 媒体存储 + +| 媒体 | 位置 | 说明 | +| ---- | ---- | ---- | +| 图片 | `msg\attach\<会话md5>\\Img\.dat` | v2 加密 | +| 语音 | `media_0.db` → `VoiceInfo.voice_data` | SILK 明文 BLOB | +| 文件 | `msg\file\\<原文件名>` | 原名来自 message_resource | +| 视频 | `msg\video\\.mp4` | 仅本地落盘时可用 | + +### 4.2 图片 v2 格式 + +``` +[6B 签名 07 08 56 32 08 07] [4B aes_size LE] [4B xor_size LE] ++ AES-ECB 密文段 + 明文段 + 异或段 +``` + +### 4.3 AES 密钥内存反测 + +图片 AES 密钥是 16 字节 ASCII、账户级稳定,但**仅在微信查看图片时驻留进程 +内存**。`detect_image_key()` 的流程: + +1. 优先读缓存 `image_keys.json`; +2. 否则对 `Weixin.exe` 内存做定向扫描,对每个候选 16 字节串用 AES-ECB + 解密图片首块,校验 JPEG/PNG 魔数,命中即认为有效; +3. 命中后持久化;也可用 `image_key=` 显式注入。 + +### 4.4 XOR 密钥推导 + +异或段密钥是单字节,从同图缩略图 `_t.dat` 尾部 JPEG 结束标记 +`FF D9` 反推:`key = tail[0] ^ 0xFF`。 + +### 4.5 下载分发 + +`download_media(user, local_id)` 按 `local_type` 自动分发到 +`download_image/_voice/_video/_file`,输出到 `DEFAULT_SAVE_PATH` +(`~/Documents/wechatauto_media`)或自定义 `save_dir`。 + +--- + +## 5. 朋友圈子系统(`wechatauto/moment.py`) + +`MomentDB` 直接读 `sns.db`: + +- `get_moments(limit, offset, username)`:时间线(最新在前,3382 条全量可读); +- `get_moment(tid)` / `get_my_moments(limit)`:单条 / 我的动态; +- 文本、图片 md5、点赞、评论均由 `SnsDataItem` XML 解析得到; +- `find_local_media(md5, kind)` / `download_media(media, save_dir)`: + 本地缓存(`Sns\Img` / `Sns\Video`)优先,否则 URL 拉取。 + +> 发表朋友圈已舍弃(4.x 自绘界面不可靠);点赞/评论仅在旧 UIA 类中 +> 保留,4.x 下不可用。 + +--- + +## 6. 发送子系统(`wechatauto/guia.py`) + +发送走「屏幕坐标 + 本地 OCR」,全部坐标基于**渲染子窗口相对坐标**, +运行时换算为屏幕绝对坐标,保证跨 DPI / 分辨率 / 窗口尺寸一致。 + +### 6.1 窗口定位与布局 + +- 主窗口:**多特征兜底定位**(防 Qt 升级改名)。类名前缀 + `Qt51514QWindowIcon` 只是「软条件」之一,`_find_main_window()` 对全部 + 可见顶层窗口按「标题含微信 / 类名前缀 / 进程名 `weixin.exe` / 可见 / + 尺寸 ≥ 800px」加权评分,取最高分;完全找不到时退回按标题精确查找。 +- 渲染子窗口:类名前缀 `MMUIRenderSubWindow`(自绘内容所在;不同版本 + 后缀不同,如 `MMUIRenderSubWindowHW` / `MMUIRenderSubWindow`, + `_find_render_window()` 按前缀匹配并取面积最大者);找不到渲染子窗口 + 时(Qt 改版等)直接**回退用主窗口矩形计算坐标**,不中断使用。 +- `_update_render_rect()` 读 `GetWindowRect` 得到渲染区,`_update_layout()` + 按比例换算各布局常量: + - `SIDEBAR_RATIO=0.22` → 侧栏宽度 / 渲染区宽度(默认基线); + - `SEARCH_BOX_RATIO` → 左侧搜索框; + - `SEND_BUTTON_RATIO` → 右下角发送按钮检索区; + - 所有像素坐标均改为比例计算,避免硬编码失效。 + +### 6.1.1 布局动态校准(防 DPI/布局漂移) + +不同机器(DPI 缩放 / 窗口尺寸 / 微信版本)下,固定比例常量可能漂移。 +`WeChatGUI` 提供「跑一次永久兼容」的校准机制: + +1. **锚点实测**:`calibrate_layout()` 用 OCR 检测「搜索」占位文本 + (文本中心 ≈ 侧栏宽 0.28)反推侧栏宽度;在右下角 OCR 找「发送」 + 按钮反推其检索区比例。结果都钳制在合理范围(侧栏比例限 + `[0.14, 0.30]`),**检测失败一律回退默认常量**,宁可不动不误配; +2. **按机器缓存**:结果写入 `~/.wechatauto/layout-<主机名>_<分辨率>.json` + (含当时的 `render_w/h`);再次运行时 `_load_layout()` 自动加载, + 与当前窗口尺寸差异 >15% 视为不匹配,自动重新校准; +3. **异常自动重校准**:`get_input_box()` 探测连续 6 次失败时,自动触发 + `calibrate_layout()` 并再次探测(每会话一次),应对运行中途布局漂移; +4. **显式强制**:`WeChatGUI(calibrate=True)` 强制重新校准;也可在任何 + 时候调用 `wx.calibrate_layout()`。 + +> 说明:微信 4.x 侧栏背景与消息区同为纯白,**像素色差检测不可靠** +> (实测边界两侧均为 255,唯一稳定锚点是搜索框 OCR 文本)。 + +### 6.2 会话定位与点击(防 toggle 关闭) + +`open_chat()` 优先点侧栏(最可靠),失败走搜索框回退。流程: + +1. `find_session(name)`:OCR 侧栏,按名称匹配返回会话行位置; +2. **活动行检测** `_row_is_active(rel_y)`:微信活动会话行背景为绿色 + `(21,172,112)`,普通行浅灰 `(238,238,240)`。采样行内横向条带统计 + "g 显著大于 r/b" 的绿色像素数,超过阈值判定为已打开; +3. 若行已是活动行(会话已打开),**跳过点击**——因为再点一次会 + toggle 关闭会话(这是二次发送失败的历史根因); +4. 否则点击并 `_chat_open_confirmed()`:轮询标题 OCR 命中,或 + `_pane_has_content()` 判定消息区已渲染非空白; +5. 侧栏确认失败 → `_search_chat(name)` 搜索框兜底,命中独立聊天窗则 + `use_window` 切换 GUI 目标。 + +### 6.3 输入框定位与文本输入 + +- `get_input_box()`:在输入区按比例扫描白色矩形带(`_probe_input_box`); +- `focus_input()`:点击输入框聚焦; +- `input_text()`:文字以 **剪贴板 + Ctrl+V** 注入(绕过中文输入法拦截), + 失败时回退拼音组合(`pypinyin` + SendInput 大写字母键)。 + +### 6.4 发送与验证 + +- `click_send()`:OCR 定位发送按钮(`发送`/`Enter` 图标)点击, + 找不到则直接回车; +- `verify=True` 时用 `WeChatDB` 读回确认:`send_msg` 轮询 + `_verify_sent()`(新消息类型 + 内容匹配),`send_file/send_image` 用 + `_verify_attachment_sent()`(`sort_seq` 基线 + 类型/文件名/`packed_info` + 匹配,图片按类型+时序)。 +- DB 实例经 `_get_db()` 缓存复用,避免每次发送验证都重新解析数据库 + (这是历史慢 2.5 分钟问题的根因之一)。 + +### 6.5 文件 / 图片发送(CF_HDROP) + +文件/图片通过 **剪贴板 CF_HDROP + Ctrl+V** 插入草稿再回车发送,绕开自绘 +「+ 菜单」定位。`copy_files_to_clipboard(paths)` 写入文件列表剪贴板, +粘贴后 `click_send()`。 + +### 6.6 回复与艾特 + +- `reply_msg(text, who, target_text, verify)`:悬停最近一条消息 + (`_last_message_y` 估算)→ OCR 悬停工具栏找「回复」→ 点击 → + `input_text` → 发送;找不到工具栏回退右键菜单; +- `at_member(member, text, who, verify)`:聚焦输入框 → 键入 `@` → + OCR 成员选择弹层定位成员名 → 点击 → 输入正文 → 发送; +- 两者均可用 `verify=True` 走 DB 确认。 + +### 6.7 关键工程修复记录 + +| 问题 | 根因 | 修复 | +| ---- | ---- | ---- | +| 二次发送失败/2.5min 卡死 | 点击已打开会话被 toggle 关闭 | `_row_is_active` 活动行高亮检测,跳过点击 | +| 发送验证每次重新解析 DB | `WeChatDB()` 每次新建、重复解库 | `_get_db()` 缓存实例 | +| 窗口尺寸变化布局失效 | 硬编码像素坐标 | 全量改按比例布局 | +| `Listener.stop()` 崩溃(v1.0.3) | `_run/_poll_once` 用 `sys.stderr` 却未 `import sys` | db.py 补 `import sys` | +| 部分文本消息显示为 `[文本]`/空(v1.0.3) | 微信 4.x 文本消息 content 为「容器头+明文+填充」结构,`_friendly_content` 无法解码 | 新增 `_extract_text_from_blob` 还原明文,数据库与 bot 均可见真实内容 | +| 动画表情被落盘为打不开的伪 `.gif`(v1.0.3) | 解密后为 `wxgf` 容器(微信动画表情私有格式),按魔数误判为 GIF | `download_image` 对 `wxgf` 直接返回 `None`,不落盘 | +| 搜索联系人点错「网络搜索」(v1.0.3) | OCR 未按视觉顺序排序,且未过滤「搜索网络结果」节标题 | `_search_chat` 按 y 排序并跳过网络搜索节标题,取第一条联系人 | +| 表情截图截到自己发的消息(v1.0.3) | `capture()` 固定取「最底部一条」,截图前自己发消息时底部是自己的气泡 | 按消息方向(`msg.attr`)裁剪:自己消息用消息分隔空白定位、对方消息用头像锚点定位,阈值自适应截图尺寸 | +| 逐条发送都要重新点击对话框(v1.0.3) | `send_msg` 每次对目标会话都走完整 `open_chat`(重扫侧栏+点击) | 记录 `_current_chat`,目标会话已打开时跳过 `open_chat` 直接输入发送 | + +--- + +## 7. 消息监听(`Listener`) + +```python +from wechatauto import WeChatDB +from wechatauto.db import Listener + +db = WeChatDB() +lst = Listener(db, interval=1.0) # 轮询间隔(秒) +lst.add_listener("filehelper", cb) # cb(msg: dict, listener) +lst.start() # 后台守护线程 +lst.stop() # 优雅停止 +``` + +- 每个会话独立水印,`watermark` 属性可读写(支持断点续跑); +- 单次轮询/回调异常不终止监听,写 `sys.stderr` 后继续; +- 数据来源是解密后的本地库,与客户端在线状态无关; +- **回调并发模型(v1.0.2)**:回调在独立工作线程中执行。每个被监听会话 + 对应一条**串行**工作线程:同一会话内消息按序处理、不同会话间并行; + 轮询线程只负责读取数据库并分派任务,不会被慢回调(AI 调用 / 图片识别等) + 阻塞。`stop()` 会向工作队列投递停止信号并等待线程退出。 + +--- + +## 8. 消息模型与 UIA 兼容层 + +- `msgs/`:`BaseMessage` 及子类(`TextMessage/ImageMessage/VideoMessage/ + VoiceMessage/FileMessage/QuoteMessage/LinkMessage/LocationMessage/ + PersonalCardMessage/EmojiMessage/SystemMessage`),`parse_msg()` 统一解析; +- `EmojiMessage`(`type='emotion'`,v1.0.2 新增):"动画表情"消息专属类型, + `FriendEmojiMessage` / `SelfEmojiMessage` 按收发方向区分。微信 4.x 表情 + content 在数据库中为加密数据,`capture()` 采用「打开会话 → 滚动到底 → + 截取消息区 → 自动裁剪最后一条消息气泡」的屏幕截图方案返回图片路径, + 供上层 AI 视觉识别使用(示例见 `demo_emoji_capture.py`)。 + + 定位实现(`msgs/mtype.py`): + - 微信 4.x 主窗口为 Qt 自绘渲染(`Qt51514QWindowIcon`),不暴露 UIA 子树, + 且 DB 模式消息的 control 是伪控件(`_DBMessageControl.BoundingRectangle` + 恒为 0),无法用控件坐标定位,因此**全部基于屏幕像素分析**; + - `_pane_capture_img()` 截取消息区全宽画面(渲染顶部到输入框); + - 自己发的消息(`attr='self'`):`_crop_bottom_message()` 用「消息分隔 + 空白」定位消息顶部,空白阈值自适应截图高度(约消息区高度的 2.5%), + 跨分辨率/DPI 保持一致; + - 对方发的消息(`attr='friend'`):`_crop_by_avatar()` 优先用左侧头像 + 圆形彩色块的顶部锚定消息顶部(特征跨分辨率稳定),失败回退 + `_crop_bottom_message()`; + - 结果再经 `_content_bbox_crop()` 裁掉空白边缘后保存; + - 会话已打开时跳过 `open_chat`(避免刷新消息列表/切换窗口),并记录 + `[CAP]` 诊断日志与 `~/pane_diag_raw.png` 原图便于跨电脑排查; +- `msgs/mtype.py`:`WxParam.MSG_TYPE_*` 常量到类型类的映射; +- `ui/`:`BaseUISubWnd/Component/Main/NavigationBox/SessionBox/ChatBox`, + 老版 UIA 控件层,微信 4.x 下受限,保留兼容; +- `wx.py`:`WeChat/Chat/Listener` 高层入口,内部按能力分派: + 聊天区读取/监听走 DB,发送走 GUI(`guia.WeChatGUI`)。 + +--- + +## 9. 工具层(`utils/`) + +- `win32.py`:`find_all_windows_from_root`(遍历子窗口)、 + `GetPathByHwnd`(进程路径)、`SetClipboardText`; +- `lock.py`:`LockManager` + `uilock` 全局互斥锁,避免多线程并发操作 + 同一微信窗口; +- `tools.py`:杂项工具函数。 + +--- + +## 10. API 参考 + +### `wechatauto/__init__.py` 顶层导出 + +`WeChat`、`Chat`、`Listener`、`WeChatDB`、`auto_detect_db_dir`、 +`list_accounts`、`MediaDownloader`、`WeChatGUI`、`quick_send`、 +`quick_send_file`、`quick_send_image`、`quick_reply`、`WinInput`、 +`ScreenOCR`、`WxParam`、`WxResponse`、`wxlog`、`Moment`、`MomentDB`、 +`LockManager`、`uilock`、异常类、消息模型、`parse_msg`、`PROJECT_NAME`。 + +### `WeChatDB` + +| 方法 | 说明 | +| ---- | ---- | +| `get_self_info()` | 当前账号(username / nick_name / remark) | +| `get_sessions(limit=100)` | 会话列表 | +| `search_contact(keyword)` | 搜索联系人 | +| `get_messages(user, limit, offset)` | 会话消息 | +| `get_message_row(user, local_id)` | 原始行(媒体用) | +| `get_new_messages(user, since_seq)` | 增量消息 | +| `get_nickname(user)` | 微信号 → 昵称 | +| `list_message_chats()` | 含消息的会话 | +| `export_history(out, fmt, ...)` | 导出 JSON/SQLite | +| `extract_keys()` | 手动密钥提取 | + +### `MediaDownloader` + +`detect_image_key(refresh)`、`decrypt_image(dat_path)`、 +`download_media(user, local_id)`、`download_image/_voice/_video/_file`、 +`copy_files_to_clipboard(paths)`。 + +### `MomentDB` + +`get_moments(limit, offset, username)`、`get_moment(tid)`、 +`get_my_moments(limit)`、`find_local_media(md5, kind)`、 +`download_media(media, save_dir)`。 + +### `WeChatGUI` + +`send_msg`、`send_file`、`send_image`、`reply_msg`、`at_member`、 +`open_chat`、`focus_input`、`bring_to_front`、`get_sessions`、 +`get_input_box`;一行式 `quick_send` 等。 + +--- + +## 11. 目录结构 + +``` +wechatauto/ +├── wechatauto/ +│ ├── __init__.py 公共导出 +│ ├── wx.py 高层 API(UIA 受限,分派 DB/GUI) +│ ├── guia.py ★ 坐标+OCR 发送模块 +│ ├── db.py ★ 数据库解密/监听/导出 +│ ├── media.py ★ 媒体下载(图片 v2 解密) +│ ├── moment.py ★ 朋友圈(MomentDB) +│ ├── param.py / logger.py / languages.py / exceptions.py +│ ├── ui/ msgs/ utils/ uia/ +│ └── py.typed +├── demo.py UI 自动化示例(4.x 受限) +├── demo_db.py ★ 数据库读取示例 +├── demo_guia.py ★ 坐标+OCR 发送示例 +├── demo_listen.py ★ 实时消息监听示例 +├── demo_reply_at.py ★ 回复/@ 成员实测示例 +├── demo_emoji_capture.py ★ 表情消息截图示例 +├── README.md +├── docs/技术文档.md 本文档 +└── pyproject.toml +``` + +--- + +## 12. 已知限制 + +1. **需要微信登录**:数据库密钥存于进程内存,首次需微信运行中(提取后缓存); + 重新登录密钥变化需重新提取(自动校验失败重扫); +2. **图片 AES 密钥瞬态**:仅在微信查看图片时驻留内存,命中后持久化 + `image_keys.json`,也可 `image_key=` 显式注入; +3. **发送依赖桌面**:锁屏/会话断开时 `desktop_available()` 返回 False; + 回复/艾特依赖 OCR 工具栏/弹层,弱网或弹层排版变化时可能失败; +4. **视频仅本地可用**:视频 mp4 未落盘时返回 None; +5. **发朋友圈已舍弃**;点赞/评论在 4.x 下不可用; +6. **UI 自动化受限**:4.1.12+ 聊天区自绘,UIA 路线不可用。 + +--- + +## 13. 扩展开发指南 + +### 新增一个发送类型 + +1. 在 `guia.py` 仿照 `send_file`/`send_image` 实现原语(定位 → 注入 → + 发送 → 可选验证); +2. 需要验证时,用 `_target_seq()` 取基线、`_verify_attachment_sent()` + 轮询 DB; +3. 在 `__init__.py` 导出,并加一行式 `quick_*` 封装。 + +### 新增一种媒体格式 + +1. 在 `media.py` 参照 `_decrypt_v2` 实现解码原语; +2. 在 `download_media()` 分发处按 `local_type` 接入; +3. 按需在 `_img_md5`/`_find_dat` 补充定位逻辑。 + +### 新增数据库表 + +在 `db.py` 的 `_collect_db_files()` 注册新库,用 `_open(rel)` 打开连接, +复用 `_check_merged` 的 WAL 合并与 integrity 兜底。 + +### 布局常量校准 + +微信更新导致 OCR 定位失效时,优先检查 `guia.py` 顶部 `*_RATIO` 常量与 +`_update_layout()`,而非改硬编码坐标。跨机器/DPI 的布局漂移走自动校准: +删掉 `~/.wechatauto/layout-<机器>.json` 后重启(或 +`WeChatGUI(calibrate=True)` / 调用 `calibrate_layout()`)会重新实测并 +缓存「搜索/发送」锚点比例。 + +--- + +## 14. 路线图 + +1. 回复/艾特的跨版本稳定性校准(当前依赖 OCR 工具栏/弹层位置); +2. 视频消息下载增强(确认 4.x 视频落盘位置); +3. 导出/首扫并行化,密钥内存扫描增量缓存; +4. 支持更多消息类型(小程序、转账、位置等)友好显示(表情消息已在 v1.0.2 + 支持)。 diff --git a/publish_moment_v10.py b/publish_moment_v10.py new file mode 100644 index 0000000..7a501ec --- /dev/null +++ b/publish_moment_v10.py @@ -0,0 +1,113 @@ +# -*- coding: utf-8 -*- +"""v10:纯图发布 + 长等待,正确相机坐标 (1244,84),验证图片上传。""" +import sys, os, time, json, ctypes +from ctypes import wintypes +sys.path.insert(0, r"C:\Users\Administrator\wechatauto-replica") +os.chdir(r"C:\Users\Administrator\wechatauto-replica") + +from wechatauto.guia import (LAYOUT_CONFIG_DIR, SIDEBAR_RATIO, SEND_BUTTON_RATIO, _machine_id, WeChatGUI, ScreenOCR) +from PIL import ImageGrab + +p = os.path.join(LAYOUT_CONFIG_DIR, f"layout-{_machine_id()}.json") +if not os.path.isfile(p): + os.makedirs(LAYOUT_CONFIG_DIR, exist_ok=True) + json.dump({"machine": _machine_id(), "sidebar_ratio": SIDEBAR_RATIO, + "send_button_ratio": list(SEND_BUTTON_RATIO), "render_w": 1298, "render_h": 950, + "date": time.strftime("%Y-%m-%d %H:%M:%S")}, open(p, "w", encoding="utf-8")) + +wx = WeChatGUI() +u = ctypes.windll.user32 + +def upd(): wx._update_render_rect() + +def find_dialog(): + found = [] + @ctypes.WINFUNCTYPE(wintypes.BOOL, wintypes.HWND, wintypes.LPARAM) + def cb(h, lp): + if u.IsWindowVisible(h): + b = ctypes.create_unicode_buffer(256) + u.GetClassNameW(h, b, 256) + if b.value == "#32770": + r = wintypes.RECT() + u.GetWindowRect(h, ctypes.byref(r)) + found.append((r.left, r.top, r.right, r.bottom)) + return True + u.EnumWindows(cb, 0) + return found[0] if found else None + +def click_abs(x, y, wait=1.0): + u.SetCursorPos(int(x), int(y)); time.sleep(0.12) + u.mouse_event(0x0002,0,0,0,0); u.mouse_event(0x0004,0,0,0,0); time.sleep(wait) + +def paste(t): + import pyperclip + pyperclip.copy(t); time.sleep(0.25) + u.keybd_event(0x11,0,0,0); u.keybd_event(0x56,0,0,0) + u.keybd_event(0x56,0,2,0); u.keybd_event(0x11,0,2,0); time.sleep(0.3) + +def ctrl_a(): + u.keybd_event(0x11,0,0,0); u.keybd_event(0x41,0,0,0) + u.keybd_event(0x41,0,2,0); u.keybd_event(0x11,0,2,0); time.sleep(0.15) + +upd() +RW, RH = wx.render_w, wx.render_h +ox, oy = wx.origin_x, wx.origin_y +img_path = r"C:\Users\Administrator\wechatauto-replica\_test_moment.jpg" + +# 1. 点相机(实测坐标 1244,84) +wx.wx_click(ox+1244, oy+84); time.sleep(2.5) +dlg = find_dialog() +if not dlg: + print("RESULT: NO_DIALOG"); sys.exit() +dx0, dy0, dx1, dy1 = dlg +DW, DH = dx1-dx0, dy1-dy0 +print(f"[v10] 对话框 {DW}x{DH}") + +# 2. 选图 +click_abs(dx0+int(DW*0.33), dy0+int(DH*0.90), wait=0.8) +ctrl_a(); paste(img_path); time.sleep(0.5) +click_abs(dx0+int(DW*0.84), dy0+int(DH*0.94), wait=2.0) +print("[v10] 已选图") + +# 3. 长等待 30s,观察图片状态 +for i in range(6): + time.sleep(5) + upd() + img = ImageGrab.grab(bbox=(ox, oy, ox+RW, oy+RH)) + lines = ScreenOCR.recognize(img) + has_pic = any("Unai" in t or "unai" in t.lower() for t,_,_,_,_ in lines) + has_cancel = any("取消" in t for t,_,_,_,_ in lines) + print(f" {i*5+5}s 图片在编辑框={has_pic} 取消按钮={has_cancel}") + +# 4. 绿色扫描发表按钮 +upd() +box = wx._rel_to_screen((int(RW*0.20), int(RH*0.40), RW, RH)) +im = ImageGrab.grab(bbox=box).convert("RGB") +px = im.load(); pts = [] +for y in range(0, im.size[1], 3): + for x in range(0, im.size[0], 3): + r,g,b = px[x,y][:3] + if abs(r)<45 and abs(g-195)<45 and abs(b-117)<45: + pts.append((x,y)) +if len(pts) < 6: + print("RESULT: NO_GREEN_BUTTON"); sys.exit() +xs=[q[0] for q in pts]; ys=[q[1] for q in pts] +bx = int(RW*0.20)+(min(xs)+max(xs))//2 +by = int(RH*0.40)+(min(ys)+max(ys))//2 +print(f"[v10] 发表按钮 ({bx},{by}) 绿色点{len(pts)}") + +# 5. 点发表 +wx.wx_click(ox+bx, oy+by); time.sleep(6.0) + +# 6. 验证 +from wechatauto.db import WeChatDB +from wechatauto.moment import MomentDB +md = MomentDB(WeChatDB()) +now = int(time.time()) +for f in md.get_my_moments(limit=3): + ct = f.get("create_time") or 0 + imgs = f.get("images") or [] + if abs(now-int(ct)) < 300: + print(f"[v10] 最新 ct={ct} 图={len(imgs)} 正文={f.get('text','')[:30]}") + print("RESULT: SUCCESS_WITH_IMAGE" if imgs else "RESULT: NO_IMAGE") + break diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..3945a8e --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,51 @@ +[build-system] +requires = ["setuptools>=61.0"] +build-backend = "setuptools.build_meta" + +[project] +name = "wechatauto-replica" +version = "1.1.7" +description = "微信 4.x Windows 客户端自动化库(wxauto 复刻版):SQLCipher 数据库解密读取 + UIA/坐标-OCR 混合发送,支持消息监听、媒体下载、朋友圈读取" +readme = "README_pypi.md" +requires-python = ">=3.9" +license = { text = "Apache-2.0" } +authors = [{ name = "wechatauto-replica" }] +keywords = ["wechat", "weixin", "wechat4", "wxauto", "wechatauto", "uiautomation", "sqlcipher", "ocr", "rpa", "automation", "wechat-automation"] +classifiers = [ + "Development Status :: 4 - Beta", + "Environment :: Win32 (MS Windows)", + "Natural Language :: Chinese (Simplified)", + "Operating System :: Microsoft :: Windows", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Topic :: Communications :: Chat", + "Topic :: Software Development :: Libraries :: Python Modules", +] +dependencies = [ + "uiautomation>=2.0.18", + "pywin32>=305", + "pyperclip>=1.8.2", + "Pillow>=9.0.0", + "psutil>=5.9.0", + "colorama>=0.4.6", + "cryptography>=41.0.0", + "winsdk>=1.0.0b10", + "imageio-ffmpeg>=0.4.9", +] + +[project.optional-dependencies] +guia = ["winsdk>=1.0.0b10", "pypinyin>=0.48.0"] + +[project.urls] +Homepage = "https://github.com/fanyuantaier/wechatauto-replica" +Repository = "https://github.com/fanyuantaier/wechatauto-replica" +Issues = "https://github.com/fanyuantaier/wechatauto-replica/issues" # 上游 wxauto 项目主页(wechatauto 为其复刻版) + +[tool.setuptools.packages.find] +include = ["wechatauto*"] + +[tool.setuptools.package-data] +wechatauto = ["py.typed"] diff --git a/start_ai_reply.bat b/start_ai_reply.bat new file mode 100644 index 0000000..e459484 --- /dev/null +++ b/start_ai_reply.bat @@ -0,0 +1,7 @@ +@echo off +rem 微信智能客服引擎启动脚本(schtasks 常驻用) +rem 用 unai-core 的 cpython(真 python,不 spawn 孪生进程),避免 launcher 双开竞争 +cd /d "C:\Users\Administrator\wechatauto-replica" +set PYTHONPATH= +set VIRTUAL_ENV= +"C:\Users\Administrator\AppData\Local\unai-core-os\unai-core-os\python\cpython-3.12.13-windows-x86_64-none\python.exe" wechat_ai_reply.py >> ai_reply.log 2>&1 diff --git a/start_engine.bat b/start_engine.bat new file mode 100644 index 0000000..dc6c66e --- /dev/null +++ b/start_engine.bat @@ -0,0 +1,3 @@ +@echo off +cd /d "C:\Users\Administrator\wechatauto-replica" +"C:\Users\Administrator\wechatauto-replica\.venv\Scripts\python.exe" wechat_ai_reply.py >> "C:\Users\Administrator\wechatauto-replica\engine.log" 2>&1 diff --git a/third_party/ffmpeg-master-latest-win64-gpl/LICENSE.txt b/third_party/ffmpeg-master-latest-win64-gpl/LICENSE.txt new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/third_party/ffmpeg-master-latest-win64-gpl/LICENSE.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/third_party/ffmpeg_path.txt b/third_party/ffmpeg_path.txt new file mode 100644 index 0000000..2c25c76 --- /dev/null +++ b/third_party/ffmpeg_path.txt @@ -0,0 +1 @@ +C:\wechatauto-replica\third_party\ffmpeg-master-latest-win64-gpl\bin\ffmpeg.exe \ No newline at end of file diff --git a/third_party/silk-v3-decoder/silk2mp3.exe b/third_party/silk-v3-decoder/silk2mp3.exe new file mode 100644 index 0000000000000000000000000000000000000000..1198533edfe61984147b690c0c2db9966fda0a74 GIT binary patch literal 660008 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 z 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 AfmFi=c(%IltiSo!ow4dJM~AO>vl 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 z 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

H;;IKA7^V9NUqa(f;Xd(ZIQN8xGI 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Μ`sirsuu1Yd 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%0Dw+=xd4#< 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 f+KIhy-Q1Hxgd+e820Q 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 X^k&9fDA-s?V@b=6#__oFz>oh2Y#tB& literal 0 HcmV?d00001 diff --git a/third_party/silk-v3-decoder/silk_v3_encoder.exe b/third_party/silk-v3-decoder/silk_v3_encoder.exe new file mode 100644 index 0000000000000000000000000000000000000000..f062282cc5a6ab023743d4845b9d761692abd375 GIT binary patch literal 318514 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 bool: + if not os.path.exists(DECODER_EXE): + return False + try: + r = subprocess.run( + [DECODER_EXE, silk_path, pcm_path, "-quiet"], + capture_output=True, timeout=60, + ) + return r.returncode == 0 and os.path.exists(pcm_path) and os.path.getsize(pcm_path) > 0 + except Exception: + return False + + +def _pcm_to_wav(pcm_path: str, wav_path: str, sample_rate: int = SAMPLE_RATE): + with open(pcm_path, "rb") as f: + data = f.read() + with wave.open(wav_path, "wb") as w: + w.setnchannels(1) + w.setsampwidth(2) + w.setframerate(sample_rate) + w.writeframes(data) + + +def transcribe_silk(silk_path: str, sample_rate: int = SAMPLE_RATE): + """把 .silk 语音文件转成文字;失败返回 None。""" + if not silk_path or not os.path.exists(silk_path): + return None + pcm_path = silk_path + ".pcm" + wav_path = silk_path + ".wav" + try: + if not _silk_to_pcm(silk_path, pcm_path): + return None + _pcm_to_wav(pcm_path, wav_path, sample_rate) + segments, _info = _get_model().transcribe( + wav_path, language="zh", beam_size=5, + ) + text = "".join(s.text for s in segments).strip() + return text or None + except Exception: + return None + finally: + for p in (pcm_path, wav_path): + try: + if os.path.exists(p): + os.remove(p) + except OSError: + pass + + +def transcribe_voice(username: str, local_id: int, db, save_dir: str = None): + """从微信库提取语音并转文字:db 为 WeChatDB 实例。""" + try: + from wechatauto.media import MediaDownloader + md = MediaDownloader(db, save_dir=save_dir) + silk = md.download_voice(username, local_id, save_dir=save_dir) + if not silk: + return None + return transcribe_silk(silk) + except Exception: + return None + + +class VoiceToText: + """可复用的语音转文字器(模型懒加载、线程安全)。""" + + def __init__(self, model: str = None): + global WHISPER_MODEL + if model: + WHISPER_MODEL = model + + def transcribe_silk(self, silk_path: str): + return transcribe_silk(silk_path) + + def transcribe_voice(self, username: str, local_id: int, db, save_dir: str = None): + return transcribe_voice(username, local_id, db, save_dir) + + +if __name__ == "__main__": + import sys + if len(sys.argv) < 2: + print("用法: python voice2text.py ") + sys.exit(1) + print(transcribe_silk(sys.argv[1])) diff --git a/wechat_ai_reply.py b/wechat_ai_reply.py new file mode 100644 index 0000000..6fb9546 --- /dev/null +++ b/wechat_ai_reply.py @@ -0,0 +1,491 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +"""微信智能客服引擎 v3(wechatauto-replica) + +在 v2 固定话术自动回复基础上升级为「大模型上下文对话 + 本机知识库」: + + 1. 每个客户(username)维护独立会话历史,持久化到磁盘,跨重启不丢, + 按「最近 N 轮 / 最近 N 秒」窗口取上下文喂给大模型。 + 2. 收到消息时检索本机 Obsidian 知识库(字符 n-gram 相似度),把最相关的 + 笔记片段注入 system prompt,让回复「结合知识库」。 + 3. 通过 OpenAI 兼容接口调用大模型生成自然回复(默认 DeepSeek,可换 + 智谱/Kimi/通义等,只要填 base_url + model + api_key)。 + 4. 无 api_key 时自动降级:关键词规则 → 知识库片段拼接 → 兜底话术, + 保证引擎不因缺 key 而停摆。 + +用法(项目目录下,独立 venv): + .venv\\Scripts\\python.exe wechat_ai_reply.py + +前置:微信 4.x 已登录、桌面未锁屏、管理员权限(提密钥)。 +配置:改 ai_config.json(重点是 llm.api_key)。 +""" +import json +import os +import re +import sys +import time +import threading +import urllib.request +import urllib.error +import msvcrt + +try: + os.system("chcp 65001 >nul 2>&1") +except Exception: + pass +try: + sys.stdout.reconfigure(encoding="utf-8", errors="replace") +except AttributeError: + pass + +from wechatauto.db import WeChatDB, Listener +from wechatauto.guia import WeChatGUI +import voice2text + +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +CONFIG_PATH = os.path.join(BASE_DIR, "ai_config.json") +WATERMARK_PATH = os.path.join(BASE_DIR, "data", "watermark.json") + + +def load_watermark() -> dict: + """加载监听水位(username -> 已推送的最大 sort_seq),重启不重复推送、不重复回复。""" + try: + if os.path.exists(WATERMARK_PATH): + data = json.loads(open(WATERMARK_PATH, "r", encoding="utf-8").read()) + if isinstance(data, dict): + return data + except (OSError, ValueError): + pass + return {} + + +def save_watermark(wm: dict) -> None: + """把监听水位落盘。""" + try: + os.makedirs(os.path.dirname(WATERMARK_PATH), exist_ok=True) + open(WATERMARK_PATH, "w", encoding="utf-8").write( + json.dumps(wm, ensure_ascii=False) + ) + except OSError: + pass + + +def load_config() -> dict: + with open(CONFIG_PATH, "r", encoding="utf-8") as f: + return json.load(f) + + +CFG = load_config() + +# ==================== 知识库检索(本地 n-gram 相似度) ==================== +class KnowledgeBase: + """读本机 Obsidian vault 的 .md 笔记,按字符 n-gram 重叠度检索。 + + 与 Unai 本机 vault 的 hashed n-gram 检索思路一致:靠字符重叠而非语义。 + 排除 .obsidian 等元数据目录,只读已发布的分类笔记。 + """ + + def __init__(self, vault_dir: str): + self.vault_dir = vault_dir + self._notes = [] # [(title, path, text)] + self._load() + + def _load(self): + if not self.vault_dir or not os.path.isdir(self.vault_dir): + print(f"[KB] 知识库目录不存在: {self.vault_dir}", flush=True) + return + for root, dirs, files in os.walk(self.vault_dir): + dirs[:] = [d for d in dirs if d not in (".obsidian", ".git")] + for name in files: + if not name.endswith(".md"): + continue + path = os.path.join(root, name) + try: + text = open(path, "r", encoding="utf-8", errors="ignore").read() + except OSError: + continue + if not text.strip(): + continue + self._notes.append((name[:-3], path, text)) + print(f"[KB] 已载入 {len(self._notes)} 篇笔记", flush=True) + + @staticmethod + def _ngrams(s: str, n: int = 3): + s = re.sub(r"\s+", "", s) + return {s[i:i + n] for i in range(len(s) - n + 1)} if len(s) >= n else {s} + + def search(self, query: str, top_k: int = 3, max_chars: int = 1500) -> str: + """返回拼接后的相关笔记片段;无结果返回空串。""" + if not self._notes or not query: + return "" + q_grams = self._ngrams(query) + scored = [] + for title, path, text in self._notes: + t_grams = self._ngrams(text, 3) + inter = len(q_grams & t_grams) + if inter == 0: + continue + # 重叠数 + 少量标题命中加权 + score = inter + if title and self._ngrams(title) & q_grams: + score += 10 + scored.append((score, title, text)) + if not scored: + return "" + scored.sort(reverse=True, key=lambda x: x[0]) + parts = [] + for score, title, text in scored[:top_k]: + excerpt = text.strip() + if len(excerpt) > max_chars: + excerpt = excerpt[:max_chars] + "…" + parts.append(f"【{title}】\n{excerpt}") + return "\n\n".join(parts) + + +# ==================== 每客户会话记忆 ==================== +class ConversationMemory: + """username -> 独立对话历史,内存缓存 + 磁盘持久化。""" + + def __init__(self, base_dir: str, max_turns: int): + self.base_dir = base_dir + self.max_turns = max_turns + self._cache = {} + os.makedirs(base_dir, exist_ok=True) + + def _safe_name(self, username: str) -> str: + return re.sub(r"[^0-9A-Za-z_@-]", "_", username) + ".json" + + def _path(self, username: str) -> str: + return os.path.join(self.base_dir, self._safe_name(username)) + + def load(self, username: str) -> list: + if username in self._cache: + return self._cache[username] + path = self._path(username) + hist = [] + if os.path.exists(path): + try: + hist = json.loads(open(path, "r", encoding="utf-8").read()) + except (OSError, ValueError): + hist = [] + self._cache[username] = hist + return hist + + def append(self, username: str, role: str, content: str): + hist = self.load(username) + hist.append({"role": role, "content": content, "time": int(time.time())}) + # 只保留最近 max_turns 轮(一轮 = 用户一条 + 助手一条) + hist = hist[-(self.max_turns * 2):] + self._cache[username] = hist + try: + open(self._path(username), "w", encoding="utf-8").write( + json.dumps(hist, ensure_ascii=False, indent=1) + ) + except OSError: + pass + + +# ==================== 大模型客户端(OpenAI 兼容,零第三方依赖) ==================== +class LLMClient: + def __init__(self, cfg: dict): + self.api_key = (cfg.get("api_key") or "").strip() + self.base_url = (cfg.get("base_url") or "").rstrip("/") + self.model = cfg.get("model") or "deepseek-chat" + self.timeout = cfg.get("timeout_sec") or 60 + self.max_retry = cfg.get("max_retry") or 2 + + @property + def available(self) -> bool: + return bool(self.api_key) + + def chat(self, messages: list) -> str: + """调用 chat/completions,返回助手文本;失败抛异常。""" + url = self.base_url + "/chat/completions" + payload = { + "model": self.model, + "messages": messages, + "temperature": 0.7, + "stream": False, + } + data = json.dumps(payload).encode("utf-8") + last_err = None + for attempt in range(self.max_retry + 1): + req = urllib.request.Request(url, data=data, method="POST") + req.add_header("Content-Type", "application/json") + req.add_header("Authorization", "Bearer " + self.api_key) + try: + with urllib.request.urlopen(req, timeout=self.timeout) as resp: + body = resp.read().decode("utf-8") + obj = json.loads(body) + return obj["choices"][0]["message"]["content"].strip() + except (urllib.error.URLError, urllib.error.HTTPError, KeyError, + IndexError, ValueError, OSError) as e: + last_err = e + if attempt < self.max_retry: + time.sleep(1 + attempt) + raise RuntimeError(f"LLM 调用失败: {last_err!r}") + + +# ==================== 引擎主逻辑 ==================== +_gui = None +_gui_lock = threading.Lock() +_send_lock = threading.Lock() +_last_reply = {} # username -> 上次回复时间戳 +_last_reply["_db"] = None +_self_wxid = None # 当前登录账号的 wxid,用于跳过自己发的消息 +_handled_seq = {} # username -> 已处理的最大 sort_seq(消息级去重,双保险) +_sent_recent = {} # username -> [(content, ts)]:引擎刚发出的回复回声,跳过"自己的消息被读回" +_SELF_SENDER_IDS = {"1"} # real_sender_id 里"自己"的取值(微信 4.1.13 实测 self=1) +_pending = {} # username -> {"texts": [..], "timer": Timer|None}:冷却期内累积的消息,到期合并回复 +_pending_lock = threading.Lock() + + +def _recent_sent(username: str, now: float, window: float = 120.0): + """返回该用户最近 window 秒内发出的回复内容列表,用于回声匹配。""" + items = [(c, t) for c, t in _sent_recent.get(username, []) if now - t <= window] + _sent_recent[username] = items + return [c for c, _ in items] + +_kb = KnowledgeBase(CFG["knowledge"].get("vault_dir", "")) +_llm = LLMClient(CFG["llm"]) +_mem = ConversationMemory( + CFG["storage"].get("conversation_dir", "data/conversations"), + CFG["reply"].get("history_turns", 10), +) + + +def get_gui(): + global _gui + with _gui_lock: + if _gui is None: + _gui = WeChatGUI() + return _gui + + +_BLOCK_PREFIXES = ("gh_",) # 公众号,不回复 +_SYSTEM_USERS = { + "filehelper", "brandsessionholder", "brandservicesessionholder", + "notifymessage", "fmessage", "floatbottle", "medianote", +} + + +def should_reply(username: str) -> bool: + r = CFG["reply"] + if not r.get("enabled", True): + return False + allowlist = r.get("allowlist") or [] + if allowlist: + # 白名单模式:只回复名单内的好友(测试期锁定单一联系人用) + return username in allowlist + if username in r.get("blocklist", []): + return False + if username in _SYSTEM_USERS: + return False + if "@" in username: # 群聊 @chatroom / 服务号 @openim / @weclaw / @placeholder 等 + return False + if username.startswith(_BLOCK_PREFIXES): + return False + return True + + +def _build_messages(username: str, incoming: str) -> tuple: + """构造发给大模型的 messages 列表,返回 (messages, kb_hit)。""" + sys_prompt = CFG["persona"].get("system_prompt", "") + kb_hit = "" + kb = _kb.search(incoming, top_k=CFG["knowledge"].get("top_k", 3), + max_chars=CFG["knowledge"].get("max_chars_per_note", 1500)) + if kb: + kb_hit = kb + sys_prompt += "\n\n【知识库资料】\n" + kb + + messages = [{"role": "system", "content": sys_prompt}] + + # 取该客户历史(按时间窗口过滤) + hist = _mem.load(username) + window = CFG["reply"].get("history_window_sec", 86400) + now = time.time() + recent = [h for h in hist if now - h.get("time", 0) <= window] + for h in recent[-(CFG["reply"].get("history_turns", 10) * 2):]: + if h.get("content"): + messages.append({"role": h["role"], "content": h["content"]}) + + messages.append({"role": "user", "content": incoming}) + return messages, kb_hit + + +def _fallback_reply(content: str, kb_hit: str) -> str: + """无 api_key 时的降级:关键词规则 → 知识库片段 → 兜底话术。""" + rules = CFG["reply"].get("keyword_rules") or {} + for kw, reply in rules.items(): + if kw and kw in content: + return reply + if kb_hit: + # 知识库命中但无大模型,只回片段开头的摘录 + 引导 + head = kb_hit.strip().split("\n", 1)[0].replace("【", "").replace("】", "") + return f"关于这个问题,您可以先参考这份资料({head}):需要我展开哪一点,我帮您细看。" + return CFG["reply"].get("fallback_reply", + "【自动回复】已收到您的消息,稍后回复您。") + + +def _do_reply(username: str, content: str, db): + """生成并发送一次回复(大模型优先,无 key 降级)。""" + nick = db.get_nickname(username) if db else username + try: + if _llm.available: + messages, kb_hit = _build_messages(username, content) + reply = _llm.chat(messages) + mode = "LLM" + ("+KB" if kb_hit else "") + else: + kb_hit = _kb.search(content, top_k=CFG["knowledge"].get("top_k", 3), + max_chars=CFG["knowledge"].get("max_chars_per_note", 1500)) + reply = _fallback_reply(content, kb_hit) + mode = "降级(无key)" + ("+KB" if kb_hit else "") + except Exception as e: # noqa: BLE001 + reply = CFG["reply"].get("fallback_reply", "【自动回复】已收到您的消息,稍后回复您。") + mode = f"异常回退:{e!r}" + + # 记录历史(用户 + 助手),再发送(加锁,避免 timer 线程与 worker 线程并发写) + with _send_lock: + _mem.append(username, "user", content) + _mem.append(username, "assistant", reply) + _sent_recent.setdefault(username, []).append((reply, time.time())) + try: + r = get_gui().send_msg(reply, who=username, verify=True) + print(f"[智能回复|{mode}] {username} ({nick}) <- {reply} | ok={r.is_success}", + flush=True) + except Exception as e: # noqa: BLE001 + print(f"[发送失败] {username}: {e!r}", flush=True) + + +def _flush_pending(username: str): + """冷却期结束后,把累积的多条消息合并成一次回复发出。""" + with _pending_lock: + p = _pending.get(username) + if not p or not p["texts"]: + return + texts = p["texts"] + p["texts"] = [] + p["timer"] = None + content = " ".join(texts).strip() + if not content: + return + db = _last_reply["_db"] + _last_reply[username] = time.time() + _do_reply(username, content, db) + + +def on_message(msg: dict, lst: Listener): + username = msg.get("username", "") + sender_id = str(msg.get("sender_id", "")) + content = str(msg.get("content", "")).strip() + sort_seq = msg.get("sort_seq", 0) + mtype = msg.get("type", "") + local_id = msg.get("local_id") + + # 跳过自己发的(避免回复自己的回复 → 死循环)。 + now = time.time() + + # ---- 跳过"自己"的消息(三层防护,杜绝自回复死循环)---- + # 1) sender_id 是真实 wxid 字符串时 + if _self_wxid and sender_id == str(_self_wxid): + return + # 2) real_sender_id 数值 == 自己(微信 4.1.13 实测 self=1) + if sender_id in _SELF_SENDER_IDS: + return + # 3) 内容回声:刚发出去的回复又被监听读回,直接丢弃(不依赖 sender_id 语义,最稳一层) + if content and content in _recent_sent(username, now): + return + + if not should_reply(username) or not content: + return + + # 消息级去重:sort_seq 不前进则说明是同一条消息被重复回调,直接丢弃 + last_seq = _handled_seq.get(username, -1) + if sort_seq and sort_seq <= last_seq: + return + _handled_seq[username] = sort_seq + + db = _last_reply["_db"] + + # 语音消息:先转文字再回复(语音 content 是 "[语音]" 占位,真实内容在音频里) + if mtype == "语音" and local_id: + text = voice2text.transcribe_voice(username, local_id, db) + if text: + content = text + print(f"[语音转文字] {username} -> {text}", flush=True) + else: + print(f"[语音转文字] {username} 转写失败,跳过", flush=True) + return + + # 冷却合并:冷却期内的新消息不丢弃,累积后统一回复(修复"只回第一句、后面不回")。 + cooldown = CFG["reply"].get("cooldown_sec", 5) + if now - _last_reply.get(username, 0) < cooldown: + with _pending_lock: + p = _pending.setdefault(username, {"texts": [], "timer": None}) + p["texts"].append(content) + if p["timer"] is not None: + p["timer"].cancel() + p["timer"] = threading.Timer(cooldown, _flush_pending, args=(username,)) + p["timer"].daemon = True + p["timer"].start() + return + + _last_reply[username] = now + _do_reply(username, content, db) + + +def main(): + global _self_wxid + # 单实例锁:防止多个引擎进程并发读写同一个解密缓存导致 database malformed + _lock_path = os.path.join(BASE_DIR, "engine.lock") + _lock_fh = open(_lock_path, "wb") + try: + msvcrt.locking(_lock_fh.fileno(), msvcrt.LK_NBLCK, 1) + except OSError: + print("已有引擎实例在运行,本进程退出(避免并发写坏数据库缓存)。", flush=True) + _lock_fh.close() + sys.exit(0) + + db = WeChatDB() + info = db.get_self_info() + nick = info.get("nick_name") or info.get("username") + _last_reply["_db"] = db + _self_wxid = info.get("username") or getattr(db, "wxid", None) + print(f"已接管微信: {nick} ({info.get('username')})", flush=True) + print(f"自身 wxid: {_self_wxid}(跳过自己发的消息,防自回复循环)", flush=True) + print(f"大模型: {'已配置 ' + _llm.model if _llm.available else '未配置(降级模式)'} " + f"| base_url={_llm.base_url}", flush=True) + print(f"知识库: {CFG['knowledge'].get('vault_dir','')} (已载入 {len(_kb._notes)} 篇)", + flush=True) + _allow = CFG['reply'].get('allowlist') or [] + _scope = f"白名单 {len(_allow)} 人" if _allow else "所有好友(排除公众号/群聊/服务号)" + print(f"自动回复: {'开' if CFG['reply'].get('enabled') else '关'} | " + f"回复范围: {_scope} | " + f"防抖 {CFG['reply'].get('cooldown_sec')}s", flush=True) + + lst = Listener(db, interval=3.0, watermark=load_watermark()) + # 监听所有会话(add_all + discover 自动发现新会话)。should_reply 里排除 + # 公众号/群聊/服务号/系统账号;若配置 allowlist 则只回名单内好友。 + lst.add_all(on_message, discover=True) + print(f"智能客服监听已启动({_scope}),Ctrl+C 退出...", + flush=True) + + lst.start() + _save_every = 0 + try: + while True: + time.sleep(5) + _save_every += 5 + if _save_every >= 30: + _save_every = 0 + save_watermark(lst.watermark) + except KeyboardInterrupt: + pass + finally: + save_watermark(lst.watermark) + lst.stop() + print("已停止监听。", flush=True) + + +if __name__ == "__main__": + main() diff --git a/wechat_daemon.py b/wechat_daemon.py new file mode 100644 index 0000000..08318fc --- /dev/null +++ b/wechat_daemon.py @@ -0,0 +1,147 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +"""微信自动回复接管脚本 v2(wechatauto-replica) + +功能:监听微信新消息,当【真实好友】发来私聊消息时,自动回复。 +规则: + - 只回复 wxid_ 开头的真实好友(公众号 gh_、群聊 @chatroom、 + 文件传输助手 filehelper、特殊号 @openim/@placeholder/brandsessionholder 一律不碰) + - 跳过自己发出去的消息(sender_id == 2) + - 同一好友 COOLDOWN_SEC 秒内只回一次(防刷屏) + - GUI 发送全局串行(多个好友同时来消息不会抢窗口) + +用法(项目目录下,独立 venv): + .venv\\Scripts\\python.exe wechat_daemon.py + +前置:微信 4.x 已登录、桌面未锁屏、管理员权限(提密钥)。 +""" +import sys +import os +import time +import threading + +try: + os.system("chcp 65001 >nul 2>&1") +except Exception: + pass +try: + sys.stdout.reconfigure(encoding="utf-8", errors="replace") +except AttributeError: + pass + +from wechatauto.db import WeChatDB, Listener +from wechatauto.guia import WeChatGUI + +# ==================== 自动回复配置(改这里) ==================== +AUTO_REPLY = True # 总开关 +DEFAULT_REPLY = "【自动回复】已收到您的消息,稍后回复您。" + +# 关键词规则:消息命中关键词时用对应话术回复;未命中则用 DEFAULT_REPLY +KEYWORD_RULES = { + # "你好": "你好呀,请问有什么可以帮您?", + # "价格": "具体价格您可以看下我发给您的报价单。", +} + +# 只回复这些前缀的会话(真实好友)。留空 = 不限制前缀 +REPLY_ONLY_PREFIX = ("wxid_",) + +# 防抖:同一会话内多少秒内不重复自动回复 +COOLDOWN_SEC = 30 + +# 黑名单会话(精确匹配 username,绝不自动回复) +BLOCKLIST = {"filehelper"} +# ============================================================== + +_gui = None +_gui_lock = threading.Lock() +_last_reply = {} # username -> 上次回复时间戳 +_send_lock = threading.Lock() + + +def get_gui(): + global _gui + with _gui_lock: + if _gui is None: + _gui = WeChatGUI() + return _gui + + +def should_reply(username: str) -> bool: + """是否对某会话启用自动回复。""" + if not AUTO_REPLY: + return False + if username in BLOCKLIST: + return False + if username.endswith("@chatroom"): + return False + if not REPLY_ONLY_PREFIX: + return True + return username.startswith(REPLY_ONLY_PREFIX) + + +def pick_reply(content: str) -> str: + for kw, reply in KEYWORD_RULES.items(): + if kw in content: + return reply + return DEFAULT_REPLY + + +def on_message(msg: dict, lst: Listener): + username = msg.get("username", "") + sender_id = msg.get("sender_id", "") + content = str(msg.get("content", "")) + + # 跳过自己发出去的消息(避免回复自己的回复 → 死循环) + if str(sender_id) == "2": + return + + if not should_reply(username): + return + + # 防抖 + now = time.time() + last = _last_reply.get(username, 0) + if now - last < COOLDOWN_SEC: + return + _last_reply[username] = now + + reply = pick_reply(content) + nick = _last_reply.get("_db") and _last_reply["_db"].get_nickname(username) or username + # 全局串行发送,避免多个会话并发抢同一微信窗口 + with _send_lock: + try: + r = get_gui().send_msg(reply, who=username, verify=True) + print(f"[自动回复] {username} ({nick}) <- {reply} | ok={r.is_success} {r['message']}", + flush=True) + except Exception as e: # noqa: BLE001 + print(f"[自动回复失败] {username}: {e!r}", flush=True) + + +def main(): + db = WeChatDB() + info = db.get_self_info() + nick = info.get("nick_name") or info.get("username") + _last_reply["_db"] = db + print(f"已接管微信: {nick} ({info.get('username')})", flush=True) + print(f"自动回复: {'开' if AUTO_REPLY else '关'} | 默认话术: {DEFAULT_REPLY} | " + f"只回前缀: {REPLY_ONLY_PREFIX} | 防抖 {COOLDOWN_SEC}s", flush=True) + + lst = Listener(db, interval=1.0) + # add_all:监听所有已有会话 + 自动发现新会话 + lst.add_all(on_message) + print("自动回复监听已启动(真实好友发消息即自动回复,公众号/群聊不碰),Ctrl+C 退出...", + flush=True) + + lst.start() + try: + while True: + time.sleep(1) + except KeyboardInterrupt: + pass + finally: + lst.stop() + print("已停止监听。", flush=True) + + +if __name__ == "__main__": + main() diff --git a/wechatauto/__init__.py b/wechatauto/__init__.py new file mode 100644 index 0000000..3a7f509 --- /dev/null +++ b/wechatauto/__init__.py @@ -0,0 +1,100 @@ +"""wechatauto —— Windows版本微信客户端(非网页版)自动化。 + +基于 UIAutomation 技术驱动当前微信4.x客户端,可实现简单的发送、 +接收微信消息,编写简单的微信机器人。 +""" + +from __future__ import annotations + +from .wx import WeChat, Chat, Listener +from .param import WxParam, WxResponse, PROJECT_NAME +from .logger import wxlog +from .moment import Moment, MomentDB +from .db import WeChatDB, auto_detect_db_dir, list_accounts +from .media import MediaDownloader +from .guia import ( + WeChatGUI, + quick_send, + quick_send_file, + quick_send_image, + quick_reply, + WinInput, + ScreenOCR, +) +from .exceptions import ( + NetWorkError, + WechatautoError, + WechatautoNoteLoadTimeoutError, + WechatautoUINotFoundError, + WechatautoNotLoggedInError, +) +from .utils.lock import LockManager, uilock +from .msgs import ( + Message, + BaseMessage, + HumanMessage, + TextMessage, + ImageMessage, + VideoMessage, + VoiceMessage, + FileMessage, + QuoteMessage, + LinkMessage, + LocationMessage, + PersonalCardMessage, + OtherMessage, + SystemMessage, + FriendMessage, + SelfMessage, + parse_msg, +) + +__version__ = "1.1.7" + +__all__ = [ + "WeChat", + "Chat", + "Listener", + "WeChatDB", + "auto_detect_db_dir", + "list_accounts", + "MediaDownloader", + "WeChatGUI", + "quick_send", + "quick_send_file", + "quick_send_image", + "quick_reply", + "WinInput", + "ScreenOCR", + "WxParam", + "WxResponse", + "wxlog", + "Moment", + "MomentDB", + "LockManager", + "uilock", + "WechatautoError", + "NetWorkError", + "WechatautoUINotFoundError", + "WechatautoNoteLoadTimeoutError", + "WechatautoNotLoggedInError", + "Message", + "BaseMessage", + "HumanMessage", + "TextMessage", + "ImageMessage", + "VideoMessage", + "VoiceMessage", + "FileMessage", + "QuoteMessage", + "LinkMessage", + "LocationMessage", + "PersonalCardMessage", + "OtherMessage", + "SystemMessage", + "FriendMessage", + "SelfMessage", + "parse_msg", + "PROJECT_NAME", + "__version__", +] diff --git a/wechatauto/__main__.py b/wechatauto/__main__.py new file mode 100644 index 0000000..a3157c4 --- /dev/null +++ b/wechatauto/__main__.py @@ -0,0 +1,15 @@ +import argparse +from wechatauto import __version__ + + +def main(): + parser = argparse.ArgumentParser(description="wechatauto 命令行工具") + parser.add_argument('--version', '-v', action='store_true', help='显示版本信息') + args = parser.parse_args() + + if args.version: + print(f"wechatauto {__version__}") + + +if __name__ == '__main__': + main() diff --git a/wechatauto/db.py b/wechatauto/db.py new file mode 100644 index 0000000..8b87adf --- /dev/null +++ b/wechatauto/db.py @@ -0,0 +1,1915 @@ +# -*- coding: utf-8 -*- +"""wechatauto 数据库读取模块(微信 4.x) + +通过读取微信本地 SQLCipher 加密数据库实现消息读取,不依赖 UI 自动化。 + +原理: + 1. 从微信配置文件(%APPDATA%/Tencent/xwechat/config/*.ini)定位数据目录; + 2. 从 Weixin.exe 进程内存中只读扫描 ``com.Tencent.WCDB.Config.Cipher`` + 配置对象,提取每个数据库独立的 32 字节密钥(SQLCipher 4 格式, + PBKDF2-HMAC-SHA512, 256000 迭代); + 3. 按页解密数据库到临时目录(带缓存),再用标准 sqlite3 查询。 + +限制: + - 微信必须处于登录状态(密钥存在于进程内存中,首次提取后本地缓存); + - 合并 -wal 时若微信正在 checkpoint,可能触发一次全量重建重试; + - 仅支持读取,不支持发送。 +""" + +from __future__ import annotations + +import ctypes +import glob +import hashlib +import hmac as hmac_mod +import json +import os +import queue +import re +import shutil +import sqlite3 +import struct +import sys +import tempfile +import threading +import time +from ctypes import wintypes +from typing import Dict, List, Optional, Tuple + +from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes + +PAGE_SZ = 4096 +RESERVE_SZ = 80 # IV(16) + HMAC(64) +STAMP_VERSION = 2 # 解密缓存 stamp 格式版本,改合并逻辑时递增以强制重建 +CONFIG_CIPHER_NAME = b"com.Tencent.WCDB.Config.Cipher" +CONFIG_XOR_MASK = bytes.fromhex( + "d2c7442458020000004889442450488b" + "450048844c2448488944254048584c24" +) +HEX_LITERAL_RE = re.compile(rb"[xX]'([0-9a-fA-F]{64,192})'") + +# 主密钥 cfg 提取(ReadWeixinKey-rev 同源, 每版本需重采锚点): +# weixin.dll 特征码(sub_1803308D0 机器码前缀, 其后 4×movabs 立即数 = XOR 材料) +MASTER_DLL_PATTERN = bytes.fromhex( + "83ec404889d64889cb0f57c00f1142100f11024c8bb1c8020000" + "4883b9d0020000107209488b9bb8020000eb074881c3b8020000" + "4d85f60f880a0200004983fe10736d4c89761048c746180f0000" + "000f10030f110648b8" +) +MASTER_DLL_VERIFY = (b"488944242048b8", b"488944242848b8", b"488944243048b8") +CFG_LANDMARK = b"global_config" # cfg 对象地标字符串(SSO 内联) +CFG_PTR_BACK = 0x138 # 地标前指针链回退偏移(版本敏感: 4.1.10.31=0x130) +CFG_OFFSET = 0x68 # v18 → cfg 指针偏移(版本敏感) +CFG_DWORD_OFF = 0x40 # cfgDword(图片密钥派生源) +CFG_WXID_OFF = 0x48 # wxId std::string +CFG_CIPHER_OFF = 0x2B8 # dbKey 密文 std::string + +MSG_TYPE_NAMES = { + 1: "文本", + 3: "图片", + 34: "语音", + 43: "视频", + 47: "动画表情", + 48: "位置", + 49: "文件/链接/卡片", + 10000: "系统消息", +} + + +class _MBI(ctypes.Structure): + _fields_ = [ + ("BaseAddress", ctypes.c_void_p), + ("AllocationBase", ctypes.c_void_p), + ("AllocationProtect", wintypes.DWORD), + ("__alignment1", wintypes.DWORD), + ("RegionSize", ctypes.c_size_t), + ("State", wintypes.DWORD), + ("Protect", wintypes.DWORD), + ("Type", wintypes.DWORD), + ("__alignment2", wintypes.DWORD), + ] + + +class _MODULEENTRY32W(ctypes.Structure): + _fields_ = [ + ("dwSize", wintypes.DWORD), + ("th32ModuleID", wintypes.DWORD), + ("th32ProcessID", wintypes.DWORD), + ("GlblcntUsage", wintypes.DWORD), + ("ProccntUsage", wintypes.DWORD), + ("modBaseAddr", ctypes.c_void_p), + ("modBaseSize", wintypes.DWORD), + ("hModule", wintypes.HMODULE), + ("szModule", ctypes.c_wchar * 256), + ("szExePath", ctypes.c_wchar * 260), + ] + + +_k32 = ctypes.WinDLL("kernel32", use_last_error=True) +_k32.OpenProcess.restype = wintypes.HANDLE +_k32.OpenProcess.argtypes = [wintypes.DWORD, wintypes.BOOL, wintypes.DWORD] +_k32.VirtualQueryEx.argtypes = [ + wintypes.HANDLE, ctypes.c_void_p, ctypes.POINTER(_MBI), ctypes.c_size_t, +] +_k32.VirtualQueryEx.restype = ctypes.c_size_t +_k32.ReadProcessMemory.argtypes = [ + wintypes.HANDLE, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t, + ctypes.POINTER(ctypes.c_size_t), +] + + +def _md5_hex(data: bytes) -> str: + return hashlib.md5(data).hexdigest() + + +def _pbkdf2(passwd: bytes, salt: bytes, iters: int) -> bytes: + return hashlib.pbkdf2_hmac("sha512", passwd, salt, iters, dklen=32) + + +def _aes_cbc_decrypt(key: bytes, iv: bytes, data: bytes) -> bytes: + dec = Cipher(algorithms.AES(key), modes.CBC(iv)).decryptor() + return dec.update(data) + dec.finalize() + + +def _split_key(key: bytes) -> Tuple[bytes, Optional[bytes]]: + """拆分密钥形态:32 字节 = 标准裸 key(salt 用文件头前 16 字节); + 48 字节 = SQLCipher 4 "Raw Key with Explicit Salt"(前 32B key + 后 16B salt, + 用于 cipher_plaintext_header_size 明文头模式)。返回 (enc_key, salt_or_None)。""" + if len(key) == 48: + return key[:32], key[32:] + return key, None + + +def _verify_enc_key(enc_key: bytes, page1: bytes, salt: Optional[bytes] = None) -> bool: + """验证 enc_key 是否为 page1 的 SQLCipher 4 密钥。 + + - enc_key 为 32 字节裸 key:默认用文件头前 16 字节作 salt(标准形式); + - enc_key 为 48 字节 key+salt:显式 salt 优先于文件头(明文头模式); + - 也允许单独传 salt 参数覆盖(供提取逻辑按 96hex 拆分尝试)。 + """ + if len(page1) < PAGE_SZ: + return False + if len(enc_key) == 48 and salt is None: + enc_key, salt = enc_key[:32], enc_key[32:] + if salt is None: + salt = page1[:16] + elif len(salt) != 16: + return False + mac_salt = bytes(b ^ 0x3A for b in salt) + mac_key = _pbkdf2(enc_key, mac_salt, 2) + hmac_data = page1[16: PAGE_SZ - RESERVE_SZ + 16] + stored_hmac = page1[PAGE_SZ - 64: PAGE_SZ] + hm = hmac_mod.new(mac_key, hmac_data, hashlib.sha512) + hm.update(struct.pack(" Optional[Tuple[int, int, str]]: + """返回 (模块基址, 模块大小, 路径); weixin.dll 为微信 4.x 主模块""" + k32 = ctypes.WinDLL("kernel32", use_last_error=True) + k32.CreateToolhelp32Snapshot.restype = ctypes.c_void_p + k32.CreateToolhelp32Snapshot.argtypes = [wintypes.DWORD, wintypes.DWORD] + k32.CloseHandle.argtypes = [ctypes.c_void_p] + k32.Module32FirstW.argtypes = [ctypes.c_void_p, ctypes.POINTER(_MODULEENTRY32W)] + k32.Module32NextW.argtypes = [ctypes.c_void_p, ctypes.POINTER(_MODULEENTRY32W)] + snap = k32.CreateToolhelp32Snapshot(0x08 | 0x10, pid) + if not snap or snap == -1 or snap == (1 << 64) - 1: + return None + try: + me = _MODULEENTRY32W() + me.dwSize = ctypes.sizeof(me) + ok = k32.Module32FirstW(snap, ctypes.byref(me)) + while ok: + if me.szModule and me.szModule.lower() == "weixin.dll": + return (me.modBaseAddr or 0), me.modBaseSize, me.szExePath + me.dwSize = ctypes.sizeof(me) + ok = k32.Module32NextW(snap, ctypes.byref(me)) + finally: + k32.CloseHandle(snap) + return None + + +def _extract_movabs_xor_key(dll_path: str) -> Optional[bytes]: + """从 weixin.dll 特征码后提取 4×movabs 立即数拼接成 32 字节 XOR 材料。 + + 特征码(sub_1803308D0 前缀)后紧跟 4 个 '48 b8 ' movabs 指令, + 立即数即主密钥的 XOR 材料。小版本通常不改此代码段, 大版本需重采。 + """ + try: + with open(dll_path, "rb") as f: + data = f.read() + except OSError: + return None + hit = data.find(MASTER_DLL_PATTERN) + if hit < 0: + return None + take = min(200, len(data) - hit) + hex_txt = data[hit:hit + take].hex() + hex_txt = hex_txt[len(MASTER_DLL_PATTERN) * 2:] # 丢弃特征码自身 + key = "" + for vf in MASTER_DLL_VERIFY: + if len(hex_txt) < 30 or hex_txt[16:30] != vf.decode(): + return None + key += hex_txt[0:16] + hex_txt = hex_txt[30:] + if len(hex_txt) < 16: + return None + key += hex_txt[0:16] + try: + return bytes.fromhex(key) + except ValueError: + return None + + +def _read_remote_string(h, read, addr: int) -> str: + """跨进程读 MSVC x64 std::string(SSO: size<=15 内联, 否则堆指针)""" + sz_buf = read(addr + 16, 8) + if not sz_buf: + return "" + size = struct.unpack_from(" 0x7FFFFFFF: + return "" + if size <= 15: + data = read(addr, size) + else: + p_buf = read(addr, 8) + if not p_buf: + return "" + data = read(struct.unpack_from(" Optional[bytes]: + """跨进程读字节缓冲(std::string 布局: data@+0, size@+16, cap@+24)""" + sz_buf = read(addr + 16, 8) + if not sz_buf: + return None + size = struct.unpack_from(" 0x400: + return None + cap_buf = read(addr + 24, 4) + cap = struct.unpack_from(" Optional[Tuple[str, int, str]]: + """从 Weixin.exe 进程提取 (主密钥hex, cfgDword, wxId)。 + + 流程(ReadWeixinKey-rev 同源): 整块读 weixin.dll 映像 → 扫 global_config + SSO 地标 → 指针链 cfg → 读 cfg+0x2B8 密文与 cfg+0x40 cfgDword → + 密文 XOR DLL movabs 材料得主密钥。锚点(CFG_PTR_BACK/CFG_OFFSET/特征码) + 每版本重采; 提取失败返回 None。 + """ + base, mod_size, dll_path = _find_weixin_module(pid) or (0, 0, "") + if not base or not dll_path or mod_size <= 0 or mod_size >= 0x40000000: + return None + h = _k32.OpenProcess(0x0010 | 0x0400, False, pid) + if not h: + return None + try: + def read(addr: int, n: int): + buf = ctypes.create_string_buffer(n) + br = ctypes.c_size_t(0) + if _k32.ReadProcessMemory(h, ctypes.c_void_p(addr), buf, n, ctypes.byref(br)) and br.value: + return buf.raw[: br.value] + return None + + image = read(base, mod_size) + if not image or len(image) != mod_size: + return None + # 扫 global_config SSO 地标(size==13@+16, cap==15@+24, 内容内联@+0) + pos = -1 + for i in range(len(image) - 8, 0, -8): + if struct.unpack_from("= 0: + if image[i - 16:i - 16 + len(CFG_LANDMARK)] == CFG_LANDMARK: + pos = i + break + if pos < 0: + return None + # 指针链: v18 = *(base + pos - CFG_PTR_BACK); cfg = *(v18 + CFG_OFFSET) + v18_buf = read(base + pos - CFG_PTR_BACK, 8) + if not v18_buf: + return None + v18 = struct.unpack_from(" bytes: + iv = page[PAGE_SZ - RESERVE_SZ: PAGE_SZ - RESERVE_SZ + 16] + if pgno == 1: + # 48 字节 key(key+salt)= cipher_plaintext_header_size 明文头模式: + # 页 1 前 16 字节是明文头(非加密 salt),加密数据从 offset 16 开始; + # 解密后拼接明文头 + 明文数据 + reserve。 + if len(enc_key) == 48: + enc = page[16: PAGE_SZ - RESERVE_SZ] + return page[:16] + _aes_cbc_decrypt(enc_key[:32], iv, enc) + b"\x00" * RESERVE_SZ + enc = page[16: PAGE_SZ - RESERVE_SZ] + return b"SQLite format 3\x00" + _aes_cbc_decrypt(enc_key, iv, enc) + b"\x00" * RESERVE_SZ + enc = page[: PAGE_SZ - RESERVE_SZ] + return _aes_cbc_decrypt(enc_key[:32] if len(enc_key) == 48 else enc_key, iv, enc) + b"\x00" * RESERVE_SZ + + +def _extract_text_from_blob(content: bytes) -> Optional[str]: + """从微信消息容器头中还原 UTF-8 明文文本。 + + 微信 4.x 部分文本消息的 message_content 为「容器头(0x28 b5 2f fd...) + + UTF-8 明文 + 尾部填充(\x01\x00...)」,多数消息明文从第 10 字节开始; + 长消息可能加密,无法还原返回 None。 + """ + def _try_off(off: int) -> Optional[str]: + if off >= len(content): + return None + chunk = content[off:] + if b"\x01\x00" in chunk: + chunk = chunk.split(b"\x01\x00")[0] + try: + t = chunk.decode("utf-8") + except UnicodeDecodeError: + return None + t = re.sub(r"[\x00-\x1f\x7f]+", "", t).strip() + if not t: + return None + if not re.search(r"[\u4e00-\u9fff\u3000-\u303f\uff00-\uffef]", t): + return None + printable = sum(1 for ch in t if ch.isprintable()) + if printable / len(t) < 0.6: + return None + return t + + t = _try_off(10) + if t: + return t + for off in range(0, min(16, len(content))): + if off == 10: + continue + t = _try_off(off) + if t: + return t + return None + + +def _find_account_dirs(db_dir: str) -> List[str]: + """列出 db_dir 下所有含 db_storage 子目录的账号目录。 + + 微信号目录不一定以 wxid_ 开头(如自定义微信号),这里只依赖 + db_storage 子目录的存在性判断。 + """ + out = [] + try: + for name in os.listdir(db_dir): + p = os.path.join(db_dir, name, "db_storage") + if os.path.isdir(p): + out.append(os.path.join(db_dir, name)) + except OSError: + pass + return sorted(out) + + +class WeChatDB: + """微信 4.x 本地数据库读取器""" + + def __init__( + self, + db_dir: Optional[str] = None, + keys_file: Optional[str] = None, + workdir: Optional[str] = None, + account: Optional[str] = None, + master_key: Optional[str] = None, + ): + self.db_dir = db_dir or auto_detect_db_dir() + if not self.db_dir: + raise RuntimeError("未找到微信数据库目录,请通过 db_dir 参数手动指定") + self.account = account or self._pick_account() + self.account_dir = os.path.join(self.db_dir, self.account) + self.workdir = workdir or os.path.join( + tempfile.gettempdir(), "wechatauto_db", self.account + ) + self.keys_file = keys_file or os.path.join(self.workdir, "keys.json") + self._keys: Dict[str, bytes] = {} + self._db_files = self._collect_db_files() + self.master_key: Optional[str] = None + self.cfg_dword: Optional[int] = None + self._load_or_extract_keys(master_key=master_key) + + # ------------------------------------------------------------------ + # 账号与数据库文件 + # ------------------------------------------------------------------ + def _pick_account(self) -> str: + candidates = [] + for d in _find_account_dirs(self.db_dir): + if os.path.isdir(os.path.join(d, "db_storage")): + recent = max( + ( + os.path.getmtime(os.path.join(root, f)) + for root, _, files in os.walk(os.path.join(d, "db_storage")) + for f in files + if f.endswith(".db") and not f.endswith("-wal") + ), + default=0, + ) + candidates.append((recent, os.path.basename(d))) + if not candidates: + raise RuntimeError("未找到任何已登录账号的数据库") + candidates.sort(reverse=True) + return candidates[0][1] + + def _collect_db_files(self) -> List[Tuple[str, str, int]]: + files = [] + base = os.path.join(self.account_dir, "db_storage") + for root, _, names in os.walk(base): + # migrate 目录下的 unspportmsg.db 是微信保留的未支持消息库, + # 进程内存中不存在对应密钥、代码从不访问,排除以免误触发密钥提取 + if os.path.normcase(os.path.relpath(root, base)).startswith("migrate"): + continue + for name in names: + if not name.endswith(".db") or name.endswith("-wal") or name.endswith("-shm"): + continue + path = os.path.join(root, name) + files.append((os.path.relpath(path, base), path, os.path.getsize(path))) + return files + + @property + def wxid(self) -> str: + """当前账号的微信号(去掉目录名末尾的 4 位哈希后缀)""" + return re.sub(r"_\w{4}$", "", self.account) + + def get_self_info(self) -> dict: + """当前登录账号的昵称等信息""" + for rel, path, _ in self._db_files: + if os.path.basename(path) != "contact.db": + continue + conn = self._open(rel) + row = conn.execute( + "SELECT username, nick_name, remark FROM contact WHERE username=? LIMIT 1", + (self.wxid,), + ).fetchone() + if row: + return {"username": row[0], "nick_name": row[1], "remark": row[2]} + return {"username": self.wxid, "nick_name": "", "remark": ""} + + # ------------------------------------------------------------------ + # 密钥提取 + # ------------------------------------------------------------------ + KDF_ITER = 256000 # 主密钥→库密钥 PBKDF2 迭代(微信魔改 WCDB, 实测确认) + + def _load_or_extract_keys(self, master_key: Optional[str] = None) -> None: + """加载/提取密钥, 四层优先级: + + 1. 显式 master_key(构造参数) → 主密钥派生; + 2. cfg 自动提取(进程内存, 免手动注入); + 3. 本地缓存 keys.json; + 4. Config.Cipher 内存扫描(最终回退)。 + + 派生/扫描结果均经 SQLCipher4 页1 HMAC 强校验, 零误报。 + """ + if master_key: + self._keys.update(self.derive_keys_from_master(master_key)) + self.master_key = master_key + self.cfg_dword = None + self._save_keys() + else: + auto = self.extract_master_key() + derived = {} + if auto: + master, cfg_dword, _ = auto + derived = self.derive_keys_from_master(master) + if derived: + self.master_key = master + self.cfg_dword = cfg_dword + self._keys.update(derived) + self._save_keys() + if not derived: + # 主密钥派生全部未通过(微信版本漂移导致 master key 错误) → 回退缓存 + Config.Cipher 扫描 + self.master_key = None + self.cfg_dword = None + if os.path.exists(self.keys_file): + try: + with open(self.keys_file, "r", encoding="utf-8") as f: + saved = json.load(f) + for rel, hexkey in saved.items(): + try: + self._keys[rel] = bytes.fromhex(hexkey) + except ValueError: + pass + except (json.JSONDecodeError, OSError): + pass + missing = [ + rel for rel, path, _ in self._db_files + if rel not in self._keys or not self._key_works(rel) + ] + if missing: + extracted = self.extract_keys() + self._keys.update(extracted) + self._save_keys() + still = [ + rel for rel, _, _ in self._db_files if not self._key_works(rel) + ] + if still: + import sys as _sys + print( + "[wechatauto] 警告: 以下库无可用密钥,无法解密: %s" + % ", ".join(still), + file=_sys.stderr, + ) + print( + "[wechatauto] 已加载 %d/%d 个密钥 (缓存: %s)。请确认微信已登录," + "可运行 python -m wechatauto.diagnose_keys 排查" + % (len(self._keys) - len(still), len(self._db_files), self.keys_file), + file=_sys.stderr, + ) + self.unkeyed = still + + def derive_keys_from_master(self, master_hex: str) -> Dict[str, bytes]: + """主密钥派生逐库密钥: PBKDF2-HMAC-SHA512(主密钥, 库头salt, KDF_ITER)。 + + 微信 4.x 为单一主密钥 + 每库随机 salt 派生独立库密钥(SQLCipher4 + passphrase 语义)。仅返回通过页1 HMAC 校验的派生密钥。 + """ + try: + master = bytes.fromhex(master_hex) + except ValueError: + raise ValueError("主密钥必须为 64 位 hex 字符串") + if len(master) != 32: + raise ValueError("主密钥必须为 32 字节(64 位 hex)") + keys: Dict[str, bytes] = {} + for rel, path, _ in self._db_files: + try: + with open(path, "rb") as f: + page1 = f.read(PAGE_SZ) + except OSError: + continue + if len(page1) < PAGE_SZ: + continue + derived = _pbkdf2(master, page1[:16], self.KDF_ITER) + if _verify_enc_key(derived, page1): + keys[rel] = derived + return keys + + def extract_master_key(self) -> Optional[Tuple[str, int, str]]: + """从 Weixin.exe 进程 cfg 自动提取 (主密钥hex, cfgDword, wxId)。 + + 遍历微信进程调 extract_master_key_from_cfg; 主密钥可离线派生全部库。 + 微信未运行或锚点漂移(版本变更)时返回 None, 由调用方回退。 + """ + pids = self._find_weixin_pids() + for pid in pids: + got = extract_master_key_from_cfg(pid) + if got: + return got + return None + + def _key_works(self, rel: str) -> bool: + key = self._keys.get(rel) + if not key: + return False + path = self._db_path(rel) + try: + with open(path, "rb") as f: + page1 = f.read(PAGE_SZ) + except OSError: + return False + return _verify_enc_key(key, page1) + + def _db_path(self, rel: str) -> str: + for r, path, _ in self._db_files: + if r == rel: + return path + raise KeyError(rel) + + def extract_keys(self) -> Dict[str, bytes]: + """从 Weixin.exe 进程内存扫描 Config.Cipher 对象,提取各库密钥""" + pids = self._find_weixin_pids() + if not pids: + raise RuntimeError("未检测到 Weixin.exe,请先登录微信再运行") + keys: Dict[str, bytes] = {} + tested: set = set() + for pid in pids: + keys.update(self._extract_keys_pid(pid, tested)) + if len(keys) >= len(self._db_files): + break + return keys + + def _find_weixin_pids(self) -> List[int]: + import subprocess + + try: + r = subprocess.run( + ["tasklist", "/FI", "IMAGENAME eq Weixin.exe", "/FO", "CSV", "/NH"], + capture_output=True, text=True, + creationflags=getattr(subprocess, "CREATE_NO_WINDOW", 0), + ) + except OSError: + return [] + pids = [] + for line in r.stdout.strip().splitlines(): + parts = line.strip('"').split('","') + if len(parts) >= 2 and parts[1].isdigit(): + pids.append(int(parts[1])) + return pids + + def _extract_keys_pid(self, pid: int, tested: set) -> Dict[str, bytes]: + h = _k32.OpenProcess(0x0010 | 0x0400, False, pid) + if not h: + return {} + try: + def read(addr: int, n: int): + buf = ctypes.create_string_buffer(n) + br = ctypes.c_size_t(0) + if _k32.ReadProcessMemory(h, ctypes.c_void_p(addr), buf, n, ctypes.byref(br)) and br.value: + return buf.raw[: br.value] + return None + + needles = self._find_bytes(h, read, CONFIG_CIPHER_NAME) + pairs = [ + struct.pack(" 96: + starts += list(range(0, len(run) - 63, 32)) + starts.append(len(run) - 64) + for s in dict.fromkeys(starts): + if s + 64 > len(run): + continue + cand = bytes.fromhex(run[s:s + 64]) + if cand in tested or not self._probable_key(cand): + continue + tested.add(cand) + # 96hex 形式:后 32 hex 是显式 salt(Raw Key with + # Explicit Salt),与文件头 salt 都要尝试 + explicit = None + if s + 96 <= len(run): + explicit = bytes.fromhex(run[s + 64: s + 96]) + salt_choices = [None] + if explicit: + salt_choices.append(explicit) + for salt_opt in salt_choices: + for rel, path, _ in self._db_files: + if rel in keys: + continue + with open(path, "rb") as f: + page1 = f.read(PAGE_SZ) + if _verify_enc_key(cand, page1, salt=salt_opt): + # 显式 salt 通过 → 存 key+salt(明文头模式); + # 文件头 salt 通过 → 存裸 key + keys[rel] = cand + (salt_opt or b"") + break + finally: + _k32.CloseHandle(h) + return keys + + @staticmethod + def _probable_key(b: bytes) -> bool: + return ( + len(b) == 32 + and len(set(b)) >= 15 + and b not in {b"\x00" * 32, b"\xff" * 32} + ) + + @staticmethod + def _find_bytes(h, read, needle: bytes) -> List[int]: + hits = [] + addr = 0 + while True: + mbi = _MBI() + r = _k32.VirtualQueryEx(h, ctypes.c_void_p(addr), ctypes.byref(mbi), ctypes.sizeof(mbi)) + if r == 0: + break + if ( + mbi.State == 0x1000 + and (mbi.Protect & 0xFF) & 0xE6 + and not (mbi.Protect & 0x100) + and 0 < mbi.RegionSize < 0x10000000 + ): + buf = read(mbi.BaseAddress or 0, mbi.RegionSize) + if buf: + base = mbi.BaseAddress or 0 + pos = 0 + while True: + pos = buf.find(needle, pos) + if pos < 0: + break + hits.append(base + pos) + pos += 1 + addr = (mbi.BaseAddress or 0) + mbi.RegionSize + return hits + + def _save_keys(self) -> None: + os.makedirs(os.path.dirname(self.keys_file), exist_ok=True) + with open(self.keys_file, "w", encoding="utf-8") as f: + json.dump({k: v.hex() for k, v in self._keys.items()}, f, indent=2) + + # ------------------------------------------------------------------ + # 解密与查询 + # ------------------------------------------------------------------ + WAL_HEADER_SZ = 32 # WCDB WAL 文件头 + WAL_FRAME_SZ = 4120 # 帧头 24 字节(大端 pgno + 校验等) + 4096 加密页 + + def _auto_diagnose_key_failure(self, rel: str) -> None: + """密钥缺失报错时的自动诊断,向 stderr 输出三项最常见根因: + 1) Python 位数(32 位 Python 读不了 64 位微信进程内存); + 2) 微信进程读取权限(管理员权限不匹配 → OpenProcess 失败 → 0 密钥); + 3) 多账号目录与所选账号对比(选错账号 → 密钥验证不过)。 + """ + print("[wechatauto] 密钥诊断: '%s' 无可用密钥" % rel, file=sys.stderr) + bits = 64 if sys.maxsize > 2**32 else 32 + if bits != 64: + print("[wechatauto] >> 当前 Python 是 %d 位,而微信 4.x 是 64 位进程。" + "请改用 64 位 Python(python -c \"import struct; print(struct.calcsize('P')*8)\" 应输出 64)" + % bits, file=sys.stderr) + import subprocess as _sp + try: + r = _sp.run( + ["tasklist", "/FI", "IMAGENAME eq Weixin.exe", "/FO", "CSV", "/NH"], + capture_output=True, text=True, + creationflags=getattr(_sp, "CREATE_NO_WINDOW", 0), + ) + except OSError: + return + pids = [] + for line in r.stdout.strip().splitlines(): + parts = line.strip('"').split('","') + if len(parts) >= 2 and parts[1].isdigit(): + pids.append(int(parts[1])) + if not pids: + print("[wechatauto] >> 未检测到 Weixin.exe 进程,请先登录微信并保持窗口打开", + file=sys.stderr) + return + perms = [] + for pid in pids: + h = _k32.OpenProcess(0x0010 | 0x0400, False, pid) + if not h: + err = ctypes.get_last_error() + perms.append((pid, False, err)) + else: + _k32.CloseHandle(h) + perms.append((pid, True, 0)) + blocked = [p for p, ok, err in perms if not ok] + if blocked: + print("[wechatauto] >> 部分微信进程无法读取内存 (PID %s,错误码 %s):" + "请用管理员身份运行 Python(若微信本身以管理员运行)," + "或取消微信的\"以管理员身份运行\"后重新登录" + % (", ".join(str(p) for p, _, _ in blocked), + ", ".join(str(e) for _, _, e in blocked)), + file=sys.stderr) + accounts = [ + os.path.basename(d) + for d in _find_account_dirs(self.db_dir) + ] + if len(accounts) > 1: + print("[wechatauto] >> 检测到多个微信账号目录: %s;当前自动选择: %s。" + "若报错,请用 WeChatDB(account=\"当前登录账号\") 显式指定" + % (", ".join(sorted(accounts)), self.account), + file=sys.stderr) + print("[wechatauto] 密钥诊断完成,以上为自动检测结果。完整排查请运行 " + "python -m wechatauto.diagnose_keys", file=sys.stderr) + + def _open(self, rel: str) -> sqlite3.Connection: + """打开解密(并合并 -wal 增量)后的只读库。 + + 解密结果缓存到 workdir;主库或 WAL 有变化时: + - 主库被 checkpoint 改写(mtime/size 变化)或 WAL 被重置 → 全量重建; + - 仅 WAL 追加了新帧 → 增量合并新帧(秒级)。 + """ + if rel not in self._keys: + self._auto_diagnose_key_failure(rel) + raise RuntimeError( + "数据库无可用密钥: %s。请确认微信已登录且保持窗口打开;" + "若仍复现,运行 python -m wechatauto.diagnose_keys 并把完整输出发给维护者。" + "也可删除密钥缓存强制重新提取后重试: %s" + % (rel, self.keys_file) + ) + src = self._db_path(rel) + dst = os.path.join(self.workdir, rel.replace(os.sep, "__")) + key = self._keys[rel] + src_mtime = os.path.getmtime(src) + src_size = os.path.getsize(src) + wal_path = self._wal_path(rel) + wal_mtime = os.path.getmtime(wal_path) if wal_path else 0.0 + wal_size = os.path.getsize(wal_path) if wal_path else 0 + stamp = dst + ".stamp" + old = None + if os.path.exists(stamp): + try: + with open(stamp, "r") as f: + parts = f.read().split(",") + old = { + "ver": int(parts[0]), + "mtime": float(parts[1]), + "size": int(parts[2]), + "wal_mtime": float(parts[3]), + "wal_size": int(parts[4]), + "applied": int(parts[5]), + } + if old["ver"] != STAMP_VERSION: + old = None + except (ValueError, OSError, IndexError): + old = None + build = (not old or old["mtime"] != src_mtime or old["size"] != src_size + or old["wal_mtime"] != wal_mtime or old["wal_size"] != wal_size) + if not build and (not os.path.exists(dst) or not self._check_merged(dst)): + # 复用缓存路径也校验完整性:缓存可能被其他进程并发写坏, + # 或上次进程被强杀时写了一半。损坏则强制全量重建。 + build = True + old = None + attempt = 0 + while build: + attempt += 1 + full = (not old or old["mtime"] != src_mtime or old["size"] != src_size + or wal_size < old["wal_size"] or wal_size == 0) + if full: + self._decrypt_file(src, dst, key) + applied = 0 + else: + applied = old["applied"] + if wal_path and wal_size > self.WAL_HEADER_SZ: + applied = self._merge_wal(dst, wal_path, key, applied) + else: + applied = 0 + if self._check_merged(dst): + build = False + os.makedirs(os.path.dirname(stamp), exist_ok=True) + with open(stamp, "w") as f: + f.write("%d,%f,%d,%f,%d,%d" + % (STAMP_VERSION, src_mtime, src_size, wal_mtime, wal_size, applied)) + elif attempt >= 3: + raise RuntimeError("数据库合并失败(文件被微信并发改写): %s" % rel) + else: + old = None # 合并结果损坏 → 全量重建重试 + conn = sqlite3.connect(f"file:{dst}?mode=ro&immutable=1", uri=True) + conn.row_factory = sqlite3.Row + conn.text_factory = _sqlite_text_factory + return conn + + @staticmethod + def _check_merged(dst: str) -> bool: + try: + conn = sqlite3.connect(f"file:{dst}?mode=ro&immutable=1", uri=True) + try: + row = conn.execute("PRAGMA integrity_check").fetchone() + if not row or row[0] != "ok": + return False + finally: + conn.close() + return True + except sqlite3.DatabaseError: + return False + + def _wal_path(self, rel: str) -> Optional[str]: + wal = self._db_path(rel) + "-wal" + return wal if os.path.exists(wal) else None + + def _merge_wal(self, dst: str, wal_path: str, key: bytes, from_frame: int) -> int: + """把 -wal 中的加密帧按页号覆盖进已解密的主库文件,返回已应用帧数。 + + 帧结构(WCDB,全部大端):[0:4] 页号, [4:8] 提交标记, [8:16] salt, [16:24] 校验。 + 帧内页面与主库页相同加密格式,直接用库密钥解密。 + 页 1 帧用页 1 专用布局(数据区 [16:4016],IV 在 [4016:4032])解密。 + + 只合并 salt 与当前 WAL 头一致的帧:微信 checkpoint 会重置 WAL(salt+1 并 + 清零写游标),旧世代帧若被合并会用过期页覆盖新数据,造成库损坏。 + """ + if not os.path.exists(dst): + return 0 + out = open(dst, "r+b") + try: + db_pages = (os.path.getsize(dst) + 4095) // PAGE_SZ + max_pgno = 0 + last = from_frame + with open(wal_path, "rb") as wal: + wal_hdr = wal.read(self.WAL_HEADER_SZ) + wal_salt = wal_hdr[16:24] + wal_size = os.path.getsize(wal_path) + n = (wal_size - self.WAL_HEADER_SZ) // self.WAL_FRAME_SZ + for i in range(from_frame, n): + wal.seek(self.WAL_HEADER_SZ + i * self.WAL_FRAME_SZ) + hdr = wal.read(24) + page = wal.read(PAGE_SZ) + if len(page) < PAGE_SZ: + break + pgno = struct.unpack(">I", hdr[:4])[0] + last = i + 1 + if hdr[8:16] != wal_salt: + continue + pt = _decrypt_page(key, page, pgno) + if pgno == 1: + # 明文头模式(48B key)页 1 解密后保留明文头, + # 头部 magic 可能不是标准 SQLite;用版本字节兜底校验。 + if len(key) == 48: + if len(pt) < PAGE_SZ or pt[16:18] != b"\x01\x01": + continue + elif pt[:16] != b"SQLite format 3\x00": + continue + elif pt[0] not in (0, 2, 5, 10, 13): + continue + out.seek((pgno - 1) * PAGE_SZ) + out.write(pt) + max_pgno = max(max_pgno, pgno) + out.flush() + db_pages = (os.path.getsize(dst) + 4095) // PAGE_SZ + out.seek(0) + page1 = out.read(PAGE_SZ) + hdr_pages = struct.unpack(">I", page1[28:32])[0] + new_pages = max(hdr_pages, max_pgno, db_pages) + if new_pages != hdr_pages: + page1 = page1[:28] + struct.pack(">I", new_pages) + page1[32:] + out.seek(0) + out.write(page1) + out.flush() + finally: + out.close() + return last + + def _decrypt_file(self, src: str, dst: str, key: bytes) -> None: + size = os.path.getsize(src) + pages = size // PAGE_SZ + (1 if size % PAGE_SZ else 0) + os.makedirs(os.path.dirname(dst), exist_ok=True) + with open(src, "rb") as fin, open(dst, "wb") as fout: + for pgno in range(1, pages + 1): + page = fin.read(PAGE_SZ) + if not page: + break + if len(page) < PAGE_SZ: + page = page + b"\x00" * (PAGE_SZ - len(page)) + fout.write(_decrypt_page(key, page, pgno)) + + def _message_dbs(self) -> List[str]: + """返回当前所有消息分片库。微信运行中可能新建分片(如 message_5.db), + 因此每次动态重扫磁盘并补齐新库密钥,而不是用 __init__ 时的静态缓存。 + """ + self._refresh_db_files() + return sorted( + rel for rel, path, _ in self._db_files + if re.match(r"^message[\\/]message_\d+\.db$", rel.replace(os.sep, "/")) + ) + + def _refresh_db_files(self) -> None: + """重扫磁盘上的 db 文件;发现新文件时补提取其密钥,避免旧缓存漏掉新分片。 + + 性能:仅当 message 目录下的文件清单有变化(新增 message_5.db 等)或首次 + 调用时才做全量重扫,否则直接复用 __init__ 时的扫描结果。 + """ + msg_dir = os.path.join(self.account_dir, "db_storage", "message") + try: + cur = sorted( + n for n in os.listdir(msg_dir) + if n.endswith(".db") and not n.endswith("-wal") and not n.endswith("-shm") + ) + except OSError: + return + prev = sorted( + os.path.basename(path) + for rel, path, _ in self._db_files + if re.match(r"^message[\\/].*\.db$", rel.replace(os.sep, "/")) + ) + if cur == prev: + return + current = self._collect_db_files() + if current == self._db_files: + return + self._db_files = current + new_rels = [ + rel for rel, path, _ in current + if rel not in self._keys or not self._key_works(rel) + ] + if new_rels: + try: + extracted = self.extract_keys() + self._keys.update(extracted) + self._save_keys() + except Exception: + pass + self.unkeyed = [ + rel for rel, _, _ in self._db_files if not self._key_works(rel) + ] + + def _find_msg_table(self, user: str, conns: List[sqlite3.Connection]) -> Optional[Tuple[sqlite3.Connection, str]]: + target = "Msg_" + _md5_hex(user.encode()) + for conn in conns: + row = conn.execute( + "SELECT name FROM sqlite_master WHERE type='table' AND name=?", + (target,), + ).fetchone() + if row: + return conn, target + return None + + def _invalidate_cache(self, rel: str) -> None: + """删除某个库的解密缓存 + stamp,强制下次 _open 全量重建。""" + dst = os.path.join(self.workdir, rel.replace(os.sep, "__")) + for p in (dst, dst + ".stamp"): + try: + if os.path.exists(p): + os.remove(p) + except OSError: + pass + + def _msg_conn(self, user: str) -> Optional[Tuple[sqlite3.Connection, str]]: + """打开消息库并定位用户消息表(调用方负责 close 连接)。 + + 缓存被并发写坏时(database disk image is malformed)自动删缓存重试一次。 + """ + for attempt in range(2): + conns = [self._open(rel) for rel in self._message_dbs()] + try: + found = self._find_msg_table(user, conns) + except sqlite3.DatabaseError: + for c in conns: + c.close() + if attempt == 0: + for rel in self._message_dbs(): + self._invalidate_cache(rel) + continue + raise + if not found: + for c in conns: + c.close() + return None + return found + + def get_messages(self, user: str, limit: int = 20, offset: int = 0) -> List[dict]: + """读取指定会话(微信号/群号)的最近消息""" + found = self._msg_conn(user) + if not found: + return [] + conn, table = found + try: + rows = conn.execute( + "SELECT local_id, local_type, real_sender_id, create_time, " + "message_content, source, packed_info_data, sort_seq " + "FROM %s ORDER BY sort_seq DESC LIMIT ? OFFSET ?" % table, + (limit, offset), + ).fetchall() + finally: + conn.close() + return [self._msg_row_to_dict(r) for r in rows] + + def get_message_row(self, user: str, local_id: int) -> Optional[dict]: + """按 local_id 读取一条消息的完整原始字段(媒体下载用,含 server_id/packed_info)""" + found = self._msg_conn(user) + if not found: + return None + conn, table = found + try: + row = conn.execute( + "SELECT local_id, local_type, server_id, real_sender_id, create_time, " + "message_content, source, packed_info_data, compress_content, sort_seq " + "FROM %s WHERE local_id=? LIMIT 1" % table, + (local_id,), + ).fetchone() + finally: + conn.close() + if not row: + return None + return { + "local_id": row["local_id"], + "local_type": row["local_type"], + "server_id": row["server_id"], + "sender_id": row["real_sender_id"], + "create_time": row["create_time"], + "content": row["message_content"], + "source": row["source"], + "packed_info": row["packed_info_data"], + "compress_content": row["compress_content"], + "sort_seq": row["sort_seq"], + } + + def _find_media_rows(self, user: str, types: set) -> List[int]: + """按 local_type 直接查该会话全部媒体 local_id(降序),不受总消息分页限制。 + + 供批量下载场景使用(如一次性拉取某群全部图片)。 + """ + found = self._msg_conn(user) + if not found: + return [] + conn, table = found + try: + placeholders = ",".join("?" * len(types)) + rows = conn.execute( + "SELECT local_id FROM %s WHERE local_type IN (%s) " + "ORDER BY sort_seq DESC" % (table, placeholders), + tuple(sorted(types)), + ).fetchall() + finally: + conn.close() + return [r["local_id"] for r in rows] + + def get_new_messages(self, user: str, since_seq: int = 0, limit: int = 200) -> List[dict]: + """返回 sort_seq > since_seq 的新消息(升序),供轮询监听使用""" + found = self._msg_conn(user) + if not found: + return [] + conn, table = found + try: + rows = conn.execute( + "SELECT local_id, local_type, real_sender_id, create_time, " + "message_content, source, packed_info_data, sort_seq " + "FROM %s WHERE sort_seq > ? ORDER BY sort_seq ASC LIMIT ?" % table, + (since_seq, limit), + ).fetchall() + finally: + conn.close() + return [self._msg_row_to_dict(r) for r in rows] + + @staticmethod + def _msg_row_to_dict(r) -> dict: + content = r["message_content"] + mtype = WeChatDB._msg_type_name(r["local_type"]) + if isinstance(content, bytes): + content = WeChatDB._friendly_content(content, mtype) + return { + "local_id": r["local_id"], + "type": mtype, + "sender_id": r["real_sender_id"], + "create_time": r["create_time"], + "content": content, + "sort_seq": r["sort_seq"], + } + + @staticmethod + def _friendly_content(content: bytes, mtype) -> str: + try: + text = content.decode("utf-8") + except UnicodeDecodeError: + if content[:4] == b"\x28\xb5\x2f\xfd": + text = _extract_text_from_blob(content) + if text: + return text + if mtype == "图片": + md5 = re.search(rb'md5="([0-9a-fA-F]{32})"', content) + if md5: + return "[图片 md5=%s]" % md5.group(1).decode() + return "[%s]" % mtype + return text.strip() or "[%s]" % mtype + + def get_sessions(self, limit: int = 100) -> List[dict]: + """会话列表(来自 session.db)""" + sessions = [] + for rel, path, _ in self._db_files: + if os.path.basename(path) != "session.db": + continue + conn = self._open(rel) + try: + rows = conn.execute( + "SELECT username, unread_count, summary, last_timestamp, " + "last_msg_sender, last_sender_display_name " + "FROM SessionTable WHERE is_hidden=0 " + "ORDER BY sort_timestamp DESC LIMIT ?", + (limit,), + ).fetchall() + finally: + conn.close() + for r in rows: + sessions.append({ + "username": r["username"], + "unread": r["unread_count"], + "summary": r["summary"], + "last_time": r["last_timestamp"], + "last_sender": r["last_sender_display_name"] or r["last_msg_sender"], + }) + break + return sessions + + def search_contact(self, keyword: str) -> List[dict]: + """按昵称/备注/微信号搜索联系人""" + results = [] + for rel, path, _ in self._db_files: + if os.path.basename(path) != "contact.db": + continue + conn = self._open(rel) + try: + rows = conn.execute( + "SELECT username, nick_name, remark FROM contact " + "WHERE nick_name LIKE ? OR remark LIKE ? OR username LIKE ? " + "OR alias LIKE ? LIMIT 50", + ("%" + keyword + "%",) * 4, + ).fetchall() + finally: + conn.close() + for r in rows: + results.append({ + "username": r["username"], + "nick_name": r["nick_name"], + "remark": r["remark"], + }) + break + return results + + def get_nickname(self, user: str) -> str: + """通过微信号查昵称(用于显示)""" + for rel, path, _ in self._db_files: + if os.path.basename(path) != "contact.db": + continue + conn = self._open(rel) + try: + row = conn.execute( + "SELECT nick_name, remark FROM contact WHERE username=? LIMIT 1", + (user,), + ).fetchone() + finally: + conn.close() + if row: + return row["remark"] or row["nick_name"] or user + break + return user + + # ------------------------------------------------------------------ + # 历史消息全量导出 + # ------------------------------------------------------------------ + def _build_md5_index(self) -> Dict[str, str]: + """会话 md5 → 用户名 反查表(来自 contact/session)""" + idx: Dict[str, str] = {} + for rel, path, _ in self._db_files: + base = os.path.basename(path) + if base not in ("contact.db", "session.db"): + continue + conn = self._open(rel) + try: + if base == "contact.db": + rows = conn.execute("SELECT username FROM contact") + else: + rows = conn.execute("SELECT username FROM SessionTable") + for (u,) in rows: + if u: + idx.setdefault(_md5_hex(u.encode()), u) + finally: + conn.close() + return idx + + def _nickname_index(self) -> Dict[str, str]: + idx = {} + for rel, path, _ in self._db_files: + if os.path.basename(path) != "contact.db": + continue + conn = self._open(rel) + try: + for u, n, r in conn.execute( + "SELECT username, nick_name, remark FROM contact" + ): + idx[u] = r or n or u + finally: + conn.close() + break + return idx + + def _sender_id_index(self) -> Dict[int, str]: + """消息表 real_sender_id(数字) → 用户名,来自 message_resource.SenderName2Id""" + idx: Dict[int, str] = {} + for rel, path, _ in self._db_files: + if os.path.basename(path) != "message_resource.db": + continue + conn = self._open(rel) + try: + for rid, u in conn.execute( + "SELECT rowid, user_name FROM SenderName2Id" + ): + if u: + idx[int(rid)] = u + finally: + conn.close() + break + return idx + + def is_self_sender(self, sender_id) -> bool: + """判断 real_sender_id 是否对应当前登录账号(自己发的消息)。 + + 微信 4.x 的 real_sender_id 是 message_resource.SenderName2Id 表的 rowid, + 并非固定值(本机实测自己=3、对方=12),必须动态映射,不能硬编码 2。 + """ + if sender_id is None: + return False + try: + return self._sender_id_index().get(int(sender_id)) == self.wxid + except (TypeError, ValueError): + return False + + def _resolve_sender(self, sender_id, sender_index, nicks, self_nick) -> str: + try: + if sender_index.get(int(sender_id)) == self.wxid: + return self_nick + except (TypeError, ValueError): + pass + if isinstance(sender_id, int): + u = sender_index.get(sender_id) + if u: + return nicks.get(u, u) + u = str(sender_id) + return nicks.get(u, u) + + @staticmethod + def _msg_type_name(t: int): + """消息类型显示名;兼容微信 4.x 的资源包装类型(低字节为真实类型)""" + if t in MSG_TYPE_NAMES: + return MSG_TYPE_NAMES[t] + if isinstance(t, int) and t > 0xFFFF and (t & 0xFF) in MSG_TYPE_NAMES: + return MSG_TYPE_NAMES[t & 0xFF] + return t + + def _export_row(self, r, mtype_names) -> dict: + content = r["message_content"] + mtype = mtype_names.get(r["local_type"], self._msg_type_name(r["local_type"])) + md5 = None + if isinstance(content, bytes): + content = self._friendly_content(content, mtype) + pi = r["packed_info_data"] + if pi: + try: + md5 = re.search(rb"([0-9a-fA-F]{32})", pi) + md5 = md5.group(1).decode().lower() if md5 else None + except TypeError: + md5 = None + return { + "local_id": r["local_id"], + "type": mtype, + "type_code": r["local_type"], + "sender_id": r["real_sender_id"], + "create_time": r["create_time"], + "content": content, + "server_id": r["server_id"], + "md5": md5, + "sort_seq": r["sort_seq"], + } + + def list_message_chats(self) -> List[dict]: + """所有含消息的会话(md5、用户名、昵称、消息数)""" + tables: Dict[str, int] = {} + for rel in self._message_dbs(): + conn = self._open(rel) + try: + rows = conn.execute( + "SELECT name FROM sqlite_master WHERE type='table' AND name LIKE 'Msg_%'" + ) + for t in rows: + key = t[0][4:] + try: + cnt = conn.execute( + "SELECT count(*) FROM %s" % t[0] + ).fetchone()[0] + tables[key] = tables.get(key, 0) + cnt + except sqlite3.DatabaseError: + continue + finally: + conn.close() + idx = self._build_md5_index() + nicks = self._nickname_index() + out = [] + for md5, cnt in tables.items(): + user = idx.get(md5, md5) + out.append({ + "md5": md5, + "username": user, + "name": nicks.get(user, user), + "message_count": cnt, + }) + out.sort(key=lambda x: -x["message_count"]) + return out + + def export_history( + self, + out_path: str, + fmt: str = "json", + users: Optional[List[str]] = None, + limit_per_chat: Optional[int] = None, + progress: Optional[callable] = None, + ) -> dict: + """导出历史消息到 JSON 或 SQLite。 + + :param out_path: 输出文件路径(json 或 .db/.sqlite) + :param fmt: "json" 或 "sqlite" + :param users: 指定会话(用户名或 md5),None 导出全部 + :param limit_per_chat: 每会话最多导出条数(按 sort_seq 升序保留最新) + :param progress: 回调 (chat_index, total_chats, chat_name) + :return: {"chats": n, "messages": total, "out": out_path} + """ + if fmt not in ("json", "sqlite"): + raise ValueError("fmt 仅支持 json/sqlite") + idx = self._build_md5_index() + nicks = self._nickname_index() + self_info = self.get_self_info() + sender_index = self._sender_id_index() + target_md5s = None + if users: + target_md5s = { + u if re.fullmatch(r"[0-9a-f]{32}", u) else _md5_hex(u.encode()) + for u in users + } + + # md5 -> [(conn, table), ...] 按消息库聚合(会话跨分库分片) + buckets: Dict[str, list] = {} + all_conns: List[sqlite3.Connection] = [] + for rel in self._message_dbs(): + conn = self._open(rel) + all_conns.append(conn) + tabs = conn.execute( + "SELECT name FROM sqlite_master WHERE type='table' AND name LIKE 'Msg_%'" + ).fetchall() + for (t,) in tabs: + md5 = t[4:] + if target_md5s is not None and md5 not in target_md5s: + continue + buckets.setdefault(md5, []).append((conn, t)) + try: + total = 0 + chat_info = [] + order = sorted(buckets.keys()) + for i, md5 in enumerate(order): + user = idx.get(md5, md5) + name = nicks.get(user, user) + if progress: + progress(i, len(order), name) + rows = [] + for conn, table in buckets[md5]: + try: + rows += conn.execute( + "SELECT local_id, local_type, server_id, real_sender_id, " + "create_time, message_content, packed_info_data, sort_seq " + "FROM %s" % table + ).fetchall() + except sqlite3.DatabaseError: + continue + if not rows: + continue + rows.sort(key=lambda r: (r["sort_seq"], r["local_id"])) + if limit_per_chat: + rows = rows[-limit_per_chat:] + msgs = [ + dict( + self._export_row(r, MSG_TYPE_NAMES), + sender_name=self._resolve_sender( + r["real_sender_id"], sender_index, nicks, + self_info.get("nick_name", "我"), + ), + ) + for r in rows + ] + total += len(msgs) + chat_info.append({ + "md5": md5, + "username": user, + "name": name, + "messages": msgs, + }) + if fmt == "json": + payload = { + "wxid": self.wxid, + "nick_name": self_info.get("nick_name", ""), + "exported_at": time.strftime("%Y-%m-%d %H:%M:%S"), + "chats": [], + "messages": [], + } + for c in chat_info: + payload["chats"].append({ + "md5": c["md5"], + "username": c["username"], + "name": c["name"], + "message_count": len(c["messages"]), + }) + for m in c["messages"]: + payload["messages"].append( + dict(m, chat=c["username"]) + ) + with open(out_path, "w", encoding="utf-8") as f: + json.dump(payload, f, ensure_ascii=False, indent=1) + else: + conn = sqlite3.connect(out_path) + try: + conn.execute( + "CREATE TABLE chats(md5 TEXT PRIMARY KEY, username TEXT, " + "name TEXT, message_count INT)" + ) + conn.execute( + "CREATE TABLE messages(username TEXT, local_id INT, " + "type TEXT, type_code INT, sender_id TEXT, sender_name TEXT, " + "create_time INT, content TEXT, server_id INT, md5 TEXT, " + "sort_seq INT)" + ) + for c in chat_info: + conn.execute( + "INSERT INTO chats VALUES(?,?,?,?)", + (c["md5"], c["username"], c["name"], len(c["messages"])), + ) + conn.executemany( + "INSERT INTO messages VALUES(?,?,?,?,?,?,?,?,?,?,?)", + [( + c["username"], m["local_id"], m["type"], m["type_code"], + str(m["sender_id"]), m["sender_name"], m["create_time"], + m["content"], m["server_id"], m["md5"], m["sort_seq"], + ) for m in c["messages"]], + ) + conn.commit() + finally: + conn.close() + return {"chats": len(chat_info), "messages": total, "out": out_path} + finally: + for conn in all_conns: + try: + conn.close() + except Exception: + pass + + +def list_accounts(db_dir: Optional[str] = None) -> List[dict]: + """扫描数据目录下的所有微信账号目录。 + + 返回: [{"account": "wxid_xxx_abcd", "wxid": "wxid_xxx", + "path": ..., "last_activity": mtime, "self_nick": 昵称或空}] + """ + db_dir = db_dir or auto_detect_db_dir() + if not db_dir: + return [] + out = [] + for d in _find_account_dirs(db_dir): + recent = max( + ( + os.path.getmtime(os.path.join(root, f)) + for root, _, files in os.walk(os.path.join(d, "db_storage")) + for f in files + if f.endswith(".db") and not f.endswith("-wal") + ), + default=0, + ) + account = os.path.basename(d) + out.append({ + "account": account, + "wxid": re.sub(r"_\w{4}$", "", account), + "path": d, + "last_activity": recent, + }) + out.sort(key=lambda x: -x["last_activity"]) + return out + + +_LISTENER_STOP = object() + + +class Listener: + """新消息轮询监听器(只读,基于合并了 -wal 的消息库视图)。 + + 用法:: + + listener = Listener(db, interval=1.0) + listener.add_listener("filehelper", on_new_msg) + listener.start() + ... + listener.stop() + + watermark 可持久化(json),下次启动不会重复推送。 + + 回调在独立工作线程中执行:每个被监听对象(会话)对应一条串行工作 + 线程,保证同一会话内消息按序处理、不同会话间并行。轮询线程只负责 + 读取数据库并分派任务,不会被慢回调(AI 调用/图片识别等)阻塞。 + """ + + def __init__(self, db: "WeChatDB", interval: float = 1.0, + watermark: Optional[Dict[str, int]] = None): + self.db = db + self.interval = interval + self._watermark: Dict[str, int] = watermark or {} + self._callbacks: Dict[str, List[callable]] = {} + self._stop = threading.Event() + self._thread: Optional[threading.Thread] = None + # 每会话一条串行工作线程:跨会话并行 + 会话内保序 + self._worker_queues: Dict[str, queue.Queue] = {} + self._worker_threads: Dict[str, threading.Thread] = {} + self._workers_lock = threading.Lock() + + def add_listener(self, user: str, callback: callable) -> None: + """注册新消息回调:callback(msg: dict, listener)""" + self._callbacks.setdefault(user, []).append(callback) + if user not in self._watermark: + msgs = self.db.get_messages(user, limit=1) + self._watermark[user] = msgs[0]["sort_seq"] if msgs else 0 + + def remove_listener(self, user: str, callback: callable) -> None: + try: + self._callbacks[user].remove(callback) + except (KeyError, ValueError): + pass + + def add_all(self, callback: callable, discover: bool = True) -> None: + """注册全局回调:监听所有已知会话的新消息。 + + Args: + callback: 回调函数,签名 callback(msg: dict, listener)。 + msg 包含 local_id / type / sender_id / create_time / + content / sort_seq / username(会话原始 username)字段。 + discover: 为 True 时,轮询过程中自动发现新出现的会话并注册 + 回调(无需重复调用 add_all)。默认 True。 + + 与 add_listener 的区别:add_listener 只监听指定的单个会话, + add_all 监听所有会话(含后续新建的群聊等)。 + """ + self._all_callback = callback + self._discover_new = discover + sessions = self.db.get_sessions(limit=500) + for s in sessions: + username = s["username"] + if username not in self._callbacks: + self.add_listener(username, callback) + + @property + def watermark(self) -> Dict[str, int]: + return dict(self._watermark) + + def start(self) -> None: + if self._thread and self._thread.is_alive(): + return + self._stop.clear() + self._thread = threading.Thread(target=self._run, name="wxdb-listener", daemon=True) + self._thread.start() + + def stop(self) -> None: + self._stop.set() + if self._thread: + self._thread.join(timeout=5) + with self._workers_lock: + queues = list(self._worker_queues.values()) + threads = list(self._worker_threads.values()) + for q in queues: + q.put(_LISTENER_STOP) + for t in threads: + t.join(timeout=5) + + def _run(self) -> None: + while not self._stop.is_set(): + try: + self._poll_once() + except Exception as exc: # 单次轮询失败不终止监听 + sys.stderr.write("listener poll error: %r\n" % exc) + self._stop.wait(self.interval) + + def _poll_once(self) -> None: + # 自动发现新会话(add_all 的 discover 模式) + if getattr(self, '_discover_new', False) and getattr(self, '_all_callback', None): + try: + sessions = self.db.get_sessions(limit=500) + for s in sessions: + username = s["username"] + if username not in self._callbacks: + self.add_listener(username, self._all_callback) + except Exception: + pass + for user, callbacks in list(self._callbacks.items()): + since = self._watermark.get(user, 0) + msgs = self.db.get_new_messages(user, since_seq=since) + if not msgs: + continue + self._watermark[user] = msgs[-1]["sort_seq"] + if not callbacks: + continue + self._dispatch(user, msgs) + + def _dispatch(self, user: str, msgs: List[dict]) -> None: + """把新消息交给该会话的工作线程处理,不阻塞轮询线程。""" + with self._workers_lock: + q = self._worker_queues.get(user) + if q is None: + q = queue.Queue() + self._worker_queues[user] = q + t = threading.Thread(target=self._worker_run, args=(user,), + name="wxmsg-%s" % user, daemon=True) + self._worker_threads[user] = t + t.start() + cbs = tuple(self._callbacks.get(user, ())) + for m in msgs: + m["username"] = user + q.put((m, cbs)) + + def _worker_run(self, user: str) -> None: + q = self._worker_queues.get(user) + if q is None: + return + while True: + task = q.get() + if task is _LISTENER_STOP: + break + m, cbs = task + for cb in cbs: + try: + cb(m, self) + except Exception as exc: + sys.stderr.write("listener callback error: %r\n" % exc) + + +def _extract_path_from_config(content: str) -> Optional[str]: + """从配置内容中提取数据目录路径,兼容 JSON 字段 / 纯路径 / 任意文本。 + + 微信 4.x 不同版本配置文件格式不一:有的是纯路径,有的是 JSON + (字段如 dataDir / fileSavePath)。这里统一兜底提取第一个 Windows 路径。 + """ + content = (content or "").strip().lstrip("\ufeff") + if not content: + return None + try: + obj = json.loads(content) + if isinstance(obj, dict): + for key in ("dataDir", "data_dir", "fileSavePath", "savePath", + "path", "defaultFileSavePath"): + v = obj.get(key) + if isinstance(v, str) and v.strip(): + return v.strip() + elif isinstance(obj, list): + for item in obj: + if isinstance(item, str) and re.match(r"^[A-Za-z]:[\\/]", item): + return item + except Exception: + pass + if re.match(r"^[A-Za-z]:[\\/]", content): + return content + m = re.search(r"[A-Za-z]:[\\/][^\s\x00-\x1f\"']+", content) + if m: + return m.group(0).rstrip("\\/") + return None + + +def _config_candidates() -> List[str]: + """可能的微信 4.x 配置目录(按新旧版本与 32/64 位安装差异)。""" + out = [] + for env in ("APPDATA", "LOCALAPPDATA"): + base = os.environ.get(env, "") + if base: + out.extend([ + os.path.join(base, "Tencent", "xwechat"), + os.path.join(base, "Tencent", "xwechat", "config"), + os.path.join(base, "Tencent", "WeChat"), + ]) + return out + + +def _registry_data_dirs() -> List[str]: + """从注册表读取可能指向数据目录的值(用户自定义保存位置时补充来源)。""" + import winreg + dirs = [] + for hive, sub in ( + (winreg.HKEY_CURRENT_USER, r"Software\Tencent\xwechat"), + (winreg.HKEY_CURRENT_USER, r"Software\Tencent\xwechat\config"), + (winreg.HKEY_CURRENT_USER, r"Software\Tencent\WeChat"), + ): + try: + key = winreg.OpenKey(hive, sub) + except OSError: + continue + try: + i = 0 + while True: + try: + name, data, _ = winreg.EnumValue(key, i) + except OSError: + break + i += 1 + if not isinstance(data, str) or not data.strip(): + continue + low = name.lower() + if "path" in low or "dir" in low or "save" in low: + dirs.append(data.strip()) + finally: + winreg.CloseKey(key) + return dirs + + +def _locate_account_root(root: Optional[str]) -> Optional[str]: + """在候选根目录下定位「包含账号目录」的目录。 + + 账号目录以含 db_storage 子目录为准(微信号不一定以 wxid_ 开头)。 + 兼容两种布局: + /xwechat_files//db_storage + //db_storage + 返回的目录即 WeChatDB.db_dir(账号目录的父目录)。 + """ + if not root or not os.path.isdir(root): + return None + root = root.rstrip("\\/") + candidates = [root] + for name in ("xwechat_files", "WeChat Files", "xwechat_files_data"): + candidates.append(os.path.join(root, name)) + seen = set() + for cand in candidates: + cand = cand.rstrip("\\/") + if cand in seen or not os.path.isdir(cand): + continue + seen.add(cand) + try: + dirs = os.listdir(cand) + except OSError: + continue + if any( + os.path.isdir(os.path.join(cand, d, "db_storage")) + for d in dirs + ): + return cand + return None + + +def auto_detect_db_dir() -> Optional[str]: + """自动定位微信 4.x 数据目录(不同电脑存储位置不同)。 + + 探测顺序: + 1. 微信配置文件(%APPDATA%/%LOCALAPPDATA%,支持 JSON/纯路径/任意文本); + 2. 注册表; + 3. 常见默认目录(Documents / 用户主目录)。 + """ + # 1) 配置文件 + for cfg_dir in _config_candidates(): + if not os.path.isdir(cfg_dir): + continue + for fp in glob.glob(os.path.join(cfg_dir, "*")): + if os.path.isdir(fp): + continue + try: + raw = open(fp, "r", encoding="utf-8").read(8192) + except (UnicodeDecodeError, OSError): + try: + raw = open(fp, "r", encoding="gbk").read(8192) + except (UnicodeDecodeError, OSError): + continue + path = _extract_path_from_config(raw) + if not path: + continue + hit = _locate_account_root(path) + if hit: + return hit + # 2) 注册表 + for p in _registry_data_dirs(): + hit = _locate_account_root(p) + if hit: + return hit + # 3) 常见默认目录兜底 + userprofile = os.environ.get("USERPROFILE", "") + for base in (os.path.join(userprofile, "Documents"), userprofile): + hit = _locate_account_root(base) + if hit: + return hit + return None diff --git a/wechatauto/demo.py b/wechatauto/demo.py new file mode 100644 index 0000000..1eebe0a --- /dev/null +++ b/wechatauto/demo.py @@ -0,0 +1,76 @@ +# -*- coding: utf-8 -*- +"""wechatauto 复刻版使用示例 + +使用前请确认: +1. 已登录微信 4.x 客户端 +2. 微信窗口在任务栏(未被完全最小化/隐藏) +3. 已安装依赖:pip install -e . +""" + +from wechatauto import WeChat, WxParam, WxResponse + + +def demo_basic(): + # 初始化,连接到已登录的微信主窗口 + wx = WeChat(debug=True) + + # 当前登录昵称 + print(f"当前登录:{wx.nickname}") + + # 获取会话列表 + sessions = wx.GetSession() + for session in sessions[:5]: + print(f"会话:{session.name},未读:{session.unread_count}") + + # 打开与好友的聊天窗口 + who = "文件传输助手" + wx.ChatWith(who) + + # 发送文本消息 + result = wx.SendMsg("你好,世界!", who) + print(f"发送结果:{result}") + + # 发送文件 + # wx.SendFiles(r"C:\path\to\file.txt", who) + + # 获取当前聊天窗口的所有消息 + messages = wx.GetAllMessage() + for msg in messages: + print(f"[{msg.attr}] {msg.content}") + + # 获取聊天窗口信息(群聊成员数、聊天类型等) + info = wx.ChatInfo() + print(f"聊天信息:{info}") + + +def demo_listener(): + """消息监听示例:收到新消息后自动回复""" + wx = WeChat() + + def callback(msg, chat): + print(f"收到消息:{chat.who} - {msg.content}") + # 简单自动回复 + if msg.is_friend: + chat.SendMsg(f"收到你的消息:{msg.content}") + + # 添加监听聊天(会将聊天窗口独立出去) + wx.AddListenChat("文件传输助手", callback=callback) + + print("开始监听,按 Ctrl+C 退出") + wx.KeepRunning() + + +def demo_moments(): + """朋友圈示例(只读,发布功能已舍弃)""" + wx = WeChat() + + # 获取朋友圈动态 + moments = wx.Moment.GetMoments() + for item in moments[:3]: + print(f"{item.publisher}: {item.text}") + + +if __name__ == "__main__": + demo_basic() + # demo_listener() + # demo_moments() diff --git a/wechatauto/demo_db.py b/wechatauto/demo_db.py new file mode 100644 index 0000000..9902ed3 --- /dev/null +++ b/wechatauto/demo_db.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- +"""wechatauto 复刻版 —— 数据库读取示例程序 + +基于本地数据库解密,读取微信 4.x 的消息与会话,不依赖 UI 自动化。 + +使用前提: + 1. 微信 4.x 已登录运行(首次运行时需要从进程内存提取密钥) + 2. 已安装依赖:pip install -e . + +用法: + python demo_db.py +""" + +from __future__ import annotations + +import os +import sys +import time + +try: + os.system("chcp 65001 >nul 2>&1") +except Exception: + pass +try: + sys.stdout.reconfigure(encoding="utf-8", errors="replace") +except AttributeError: + pass + +from wechatauto import WeChatDB + + +def show_account(db: WeChatDB): + info = db.get_self_info() + print("-" * 60) + print("当前账号信息") + print("-" * 60) + print(f" 微信号 : {info['username']}") + print(f" 昵称 : {info['nick_name']}") + print(f" 数据目录: {db.account_dir}") + + +def show_sessions(db: WeChatDB, limit: int = 8): + print() + print("-" * 60) + print("会话列表(前 %d 条)" % limit) + print("-" * 60) + for s in db.get_sessions(limit=limit): + name = db.get_nickname(s["username"]) + if not s["summary"]: + continue + t = time.strftime("%m-%d %H:%M", time.localtime(s["last_time"])) + unread = f" [未读 {s['unread']}]" if s["unread"] else "" + print(f" {name:<20} {t} {s['summary'][:30]}{unread}") + + +def show_messages(db: WeChatDB, who: str, limit: int = 10, display_name: str = ""): + print() + print("-" * 60) + print(f"最近消息:{display_name or who}") + print("-" * 60) + messages = db.get_messages(who, limit=limit) + if not messages: + print(" (没有找到消息,请确认微信号/群号是否正确)") + return + for m in reversed(messages): + t = time.strftime("%m-%d %H:%M", time.localtime(m["create_time"])) + sender = "我" if m["sender_id"] == 2 else "对方" + content = m["content"].replace("\n", " ") + print(f" [{t}] {sender} [{m['type']}] {content[:60]}") + + +def main(): + print("正在初始化微信数据库读取器 ...") + t0 = time.time() + db = WeChatDB() + print(f"初始化完成({time.time() - t0:.1f}s,账号目录:{db.account})") + + show_account(db) + show_sessions(db) + + who = input("\n输入会话昵称或微信号(直接回车查看示例会话):").strip() + if not who: + who = "文件传输助手" + hits = db.search_contact(who) + if hits: + who = hits[0]["username"] + else: + hits = db.search_contact(who) + if hits and hits[0]["nick_name"] != who: + who = hits[0]["username"] + print(f" 已匹配联系人:{hits[0]['nick_name']}({who})") + + show_messages(db, who, display_name=db.get_nickname(who)) + + +if __name__ == "__main__": + main() diff --git a/wechatauto/demo_emoji_capture.py b/wechatauto/demo_emoji_capture.py new file mode 100644 index 0000000..884d6c4 --- /dev/null +++ b/wechatauto/demo_emoji_capture.py @@ -0,0 +1,100 @@ +# -*- coding: utf-8 -*- +"""表情包截图示例 —— 遇到「动画表情」消息时截取其图片 + +背景:微信 4.x 表情消息在本地数据库中的 content 为加密数据,无法直接 +提取原图。因此采用「打开会话 → 滚动到底 → 对最后一条消息区域截图」的 +屏幕截图方案(EmojiMessage.capture()),返回 PNG 路径。 + +用法: + python demo_emoji_capture.py # 默认会话:文件传输助手 + python demo_emoji_capture.py 某个群 # 指定会话 + python demo_emoji_capture.py --listen 某个群 # 监听模式:收到表情自动截图 +""" +from __future__ import annotations + +import os +import sys +import time + +try: + os.system("chcp 65001 >nul 2>&1") +except Exception: + pass +try: + sys.stdout.reconfigure(encoding="utf-8", errors="replace") +except AttributeError: + pass + +from wechatauto import WeChat + +SAVE_DIR = os.path.join(os.path.expanduser("~"), "emoji_capture") + + +def capture_emoji(msg) -> str | None: + """对一条表情消息截图,返回 PNG 路径;失败返回 None。 + + 截图位置根据消息方向自动判断: + - msg.attr == 'self' → 右对齐(自己发的) + - 否则 → 左对齐(对方发的) + """ + path = msg.capture(save_dir=SAVE_DIR) + return path + + +def capture_latest_emoji(wx: WeChat, who: str) -> None: + """打开会话,截取最新一条表情消息的气泡图片。 + + 说明:capture() 截图的是屏幕上「最新一条消息」的位置,因此表情 + 必须是该会话的最新一条消息才能截到它;否则请用 --listen 模式, + 收到表情时它即为最新一条,可自动截图。 + """ + wx.ChatWith(who) + time.sleep(0.5) + msgs = wx.GetAllMessage() # 新→旧排列,msgs[0] 是会话最新一条 + if not msgs: + print(f"会话「{who}」没有消息") + return + if getattr(msgs[0], "type", None) != "emotion": + print(f"会话「{who}」最新一条不是表情(是 {msgs[0].type})") + print("提示:capture() 只截取最新一条消息,请用 --listen 模式在收到表情时自动截图") + return + msg = msgs[0] + path = capture_emoji(msg) + if path: + print(f"[表情截图] 方向={msg.attr} 路径={path}") + else: + print("[表情截图] 截图失败(微信窗口是否可见?会话是否在最前?)") + + +def listen_emoji(wx: WeChat, who: str) -> None: + """监听模式:实时收到表情消息时自动截图。""" + def callback(msg, chat): + if getattr(msg, "type", None) == "emotion": + path = capture_emoji(msg) + if path: + print(f"[收到表情 {msg.attr}] 截图成功 -> {path}") + else: + print("[收到表情] 截图失败") + + wx.AddListenChat(who, callback=callback) + print(f"监听中,Ctrl+C 退出:{who}") + wx.KeepRunning() + + +def main(): + args = [a for a in sys.argv[1:]] + listen = "--listen" in args + names = [a for a in args if not a.startswith("--")] + who = names[0] if names else "送你挖银子" + + wx = WeChat() + print(f"当前登录:{wx.nickname}") + + if listen: + listen_emoji(wx, who) + else: + capture_latest_emoji(wx, who) + + +if __name__ == "__main__": + main() diff --git a/wechatauto/demo_forward_voice.py b/wechatauto/demo_forward_voice.py new file mode 100644 index 0000000..1432698 --- /dev/null +++ b/wechatauto/demo_forward_voice.py @@ -0,0 +1,89 @@ +# -*- coding: utf-8 -*- +"""wechatauto v1.0.9 转发语音演示 —— 从本地媒体库提取 SILK 并作为文件发送 + +微信不支持右键直接转发语音消息(无转发入口),本项目实现为: + 「本地媒体库提取 SILK 音频文件 → 以文件消息发送给目标联系人」。 + +链路: + 1. 打开会话,定位最近一条语音消息(mmui::ChatVoiceItemView / DB 语音); + 2. MediaDownloader.download_voice 从 media_0.db 提取 voice_data 落盘 .silk; + 3. WeChatGUI.send_file 以文件消息发送给目标。 + +用法: + python demo_forward_voice.py # 小哲→文件传输助手(安全演示) + python demo_forward_voice.py --target 豆芽 # 指定转发目标 + python demo_forward_voice.py --who 群名 --target 某人 +""" +from __future__ import annotations + +import os +import sys +import time + +try: + os.system("chcp 65001 >nul 2>&1") +except Exception: + pass +try: + sys.stdout.reconfigure(encoding="utf-8", errors="replace") +except AttributeError: + pass + +from wechatauto import WeChat + +SRC_DEFAULT = "小哲" +TGT_DEFAULT = "文件传输助手" + + +def main(): + args = [a for a in sys.argv[1:]] + who = SRC_DEFAULT + target = TGT_DEFAULT + if "--who" in args: + i = args.index("--who") + who = args[i + 1] + args = args[:i] + args[i + 2:] + if "--target" in args: + i = args.index("--target") + target = args[i + 1] + args = args[:i] + args[i + 2:] + names = [a for a in args if not a.startswith("--")] + if names: + who = names[0] + + wx = WeChat() + print(f"当前登录:{wx.nickname}") + print(f"语音来源会话:{who}") + print(f"转发目标:{target}") + + if who != wx._cur().who: + r = wx.ChatWith(who) + if not (isinstance(r, str) and r): + print(f" 打开会话「{who}」失败:{r}") + sys.exit(1) + + chat = wx._cur() + msgs = chat.GetAllMessage() + voice = None + for m in msgs: + if getattr(m, "type", None) == "voice": + voice = m + break + if voice is None: + print(f" 会话「{who}」最近 50 条中没有语音消息,无法演示。") + sys.exit(1) + print(f" 找到语音消息:local_id={voice.local_id} 方向={voice.attr}") + + t0 = time.time() + r = voice.forward_to(target) + print(f" 转发 => {r['status']} :: {r['message']} ({time.time()-t0:.1f}s)") + data = r.get("data") or {} + path = data.get("path") + if path: + print(f" 本地语音文件:{path}") + + print("\n转发完成。") + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/wechatauto/demo_group_messages.py b/wechatauto/demo_group_messages.py new file mode 100644 index 0000000..a185eb2 --- /dev/null +++ b/wechatauto/demo_group_messages.py @@ -0,0 +1,356 @@ +# -*- coding: utf-8 -*- +"""wechatauto 演示:读取并识别固定群的最新消息(含红包 ZSTD 解析)。 + +从微信本地数据库直接读取指定群的最新消息,识别每条消息的类型、 +发送者昵称与内容;红包消息自动解压 ZSTD 并提取祝福语/红包类型。 + +用法: + python demo_group_messages.py [群名关键词] + [--limit N] [--list-groups] + [--watch] [--red-only] [--sleep 秒] + +参数: + 群名关键词 匹配群名(模糊匹配),默认列出所有群后取第一个 + --list-groups 仅列出所有群(名称 + wxid + 消息数),不读消息 + --limit 读取最新 N 条消息(默认 20) + --watch 轮询模式:每 --sleep 秒读取一次新消息(增量,按 sort_seq) + --sleep 轮询间隔秒数(默认 3) + --red-only 只显示红包消息 + +例: + python demo_group_messages.py --list-groups + python demo_group_messages.py 家长群 + python demo_group_messages.py 家长群 --limit 30 + python demo_group_messages.py 家长群 --watch --red-only + python demo_group_messages.py 家长群 --watch --sleep 5 + +原理: + contact.db 存群(username 含 @chatroom)与成员(wxid → nick_name/remark); + message_*.db 按 Md5(群wxid) 建表存消息,群文本消息的 message_content 形如 + "wxid: 内容",发送者 wxid 藏在内容前缀中(4.x 群消息 sender_id 不可靠)。 + 红包卡片 local_type=0x7D100000031,message_content 为「容器头 + ZSTD 压缩 + XML」,解压后可读到祝福语、红包类型(sceneid)、sendid 等。 +""" + +from __future__ import annotations + +import argparse +import hashlib +import os +import re +import sys +import time + +try: + os.system("chcp 65001 >nul 2>&1") +except Exception: + pass +try: + sys.stdout.reconfigure(encoding="utf-8", errors="replace") +except AttributeError: + pass + +from wechatauto import WeChatDB + +# 红包卡片 local_type = 0x7D100000031 +RED_PACKET_TYPE = 0x7D100000031 + +TYPE_LABEL = { + 1: "文本", + 3: "图片", + 34: "语音", + 43: "视频", + 47: "动画表情", + 48: "位置", + 49: "文件/链接/卡片", + 10000: "系统消息", +} + + +def load_nickname_map(db: WeChatDB) -> dict: + """wxid -> 昵称/备注""" + mapping = {} + for rel, path, _ in db._db_files: + if os.path.basename(path) != "contact.db": + continue + conn = db._open(rel) + try: + rows = conn.execute( + "SELECT username, nick_name, remark FROM contact" + ).fetchall() + finally: + conn.close() + for r in rows: + mapping[r[0]] = r[2] or r[1] or r[0] + break + return mapping + + +def list_groups(db: WeChatDB) -> list: + """列出所有群(名称 + wxid + 消息数),按消息数倒序""" + groups = [] + for rel, path, _ in db._db_files: + if os.path.basename(path) != "contact.db": + continue + conn = db._open(rel) + try: + rows = conn.execute( + "SELECT username, nick_name, remark FROM contact " + "WHERE username LIKE '%@chatroom'" + ).fetchall() + finally: + conn.close() + for r in rows: + groups.append({"name": r[2] or r[1] or r[0], "wxid": r[0]}) + break + for g in groups: + g["count"] = _chat_message_count(db, g["wxid"]) + groups.sort(key=lambda x: -x["count"]) + return groups + + +def _chat_message_count(db: WeChatDB, wxid: str) -> int: + md5hex = hashlib.md5(wxid.encode()).hexdigest() + total = 0 + for rel in db._message_dbs(): + conn = db._open(rel) + try: + tabs = [r[0] for r in conn.execute( + "SELECT name FROM sqlite_master WHERE type='table'")] + for tab in tabs: + if tab == "Msg_%s" % md5hex: + total += conn.execute( + "SELECT COUNT(*) FROM %s" % tab).fetchone()[0] + finally: + conn.close() + return total + + +def find_group(db: WeChatDB, keyword: str): + kw = keyword.strip() + groups = list_groups(db) + if not kw: + return groups[0] if groups else None + exact = [g for g in groups if g["name"] == kw] + if exact: + return exact[0] + fuzzy = [g for g in groups if kw in g["name"]] + return fuzzy[0] if fuzzy else None + + +def _raw_messages(db: WeChatDB, wxid: str, limit: int): + """批量读取该会话最新消息原始行(保留 message_content 二进制),升序返回。 + + 4.x 会把同一会话的表拆分在多个 message_*.db 中(历史遗留), + 因此需跨库聚合后按 sort_seq 排序取最新 limit 条。 + """ + md5hex = hashlib.md5(wxid.encode()).hexdigest() + tab = "Msg_%s" % md5hex + all_rows = [] + for rel in db._message_dbs(): + conn = db._open(rel) + try: + exists = conn.execute( + "SELECT 1 FROM sqlite_master WHERE type='table' AND name=?", + (tab,)).fetchone() + if not exists: + continue + cur = conn.execute( + "SELECT local_id, local_type, real_sender_id, create_time, " + "message_content, sort_seq FROM %s" % tab) + cols = [c[0] for c in cur.description] + all_rows.extend(dict(zip(cols, r)) for r in cur.fetchall()) + finally: + conn.close() + all_rows.sort(key=lambda r: r.get("sort_seq") or 0) + return all_rows[-limit:] + + +def zstd_decompress(content: bytes, max_size: int = 200000) -> str: + """解 ZSTD:微信 4.x 卡片/红包 message_content 为 ZSTD 压缩 XML""" + if not content: + return "" + if isinstance(content, bytes): + try: + return content.decode("utf-8") + except UnicodeDecodeError: + pass + try: + import zstandard as zstd + dctx = zstd.ZstdDecompressor() + return dctx.decompress(content, max_output_size=max_size).decode( + "utf-8", "ignore") + except ImportError: + return "" + except Exception: + return "" + return str(content) + + +def parse_red_packet(xml: str) -> dict: + """从红包 XML 提取关键字段""" + info = {} + if "wcpayinfo" not in xml: + return info + + def cdata(tag): + m = re.search(r"<%s>" % (tag, tag), xml, re.S) + return m.group(1).strip() if m else "" + + info["des"] = cdata("des") + info["receivertitle"] = cdata("receivertitle") + info["sendertitle"] = cdata("sendertitle") + info["sceneid"] = cdata("sceneid") + info["paymsgid"] = cdata("paymsgid") + info["fromusername"] = cdata("fromusername") + m = re.search(r"", xml) + info["type"] = m.group(1) if m else "" + m = re.search(r"total_num=(\d+)", xml) + info["total_num"] = m.group(1) if m else "" + m = re.search(r"", xml) + if m: + info["invalidtime"] = int(m.group(1)) + return info + + +def parse_sender(content, sender_id, nickname_map) -> str: + """解析群消息发送者昵称: + 1) 文本 content 前缀 "wxid: 内容"(4.x 群消息 sender 藏在这里) + 2) 兜底 real_sender_id(已不推荐) + """ + if isinstance(content, bytes): + try: + text = content.decode("utf-8") + except UnicodeDecodeError: + text = "" + else: + text = content + m = re.match(r"^(wxid_[0-9a-zA-Z_-]+|.*@chatroom):\s*", text) + if m: + wx = m.group(1) + return nickname_map.get(wx, wx), m.end() + return "", 0 + + +def classify_message(row: dict, nickname_map: dict) -> dict: + """识别单条消息:类型 + 发送者昵称 + 内容""" + local_type = row.get("local_type") + if local_type == RED_PACKET_TYPE: + label = "红包" + else: + label = TYPE_LABEL.get(local_type, "类型%d" % local_type) + + content = row.get("message_content") + extra = {} + + if local_type == RED_PACKET_TYPE: + xml = zstd_decompress(content) + extra = parse_red_packet(xml) + + # 发送者:红包用 XML 里的 fromusername(content 是二进制无前缀) + if local_type == RED_PACKET_TYPE and extra.get("fromusername"): + fw = extra["fromusername"] + sender = nickname_map.get(fw, fw) + else: + # 文本等:优先 content 前缀 + sender, cut = parse_sender(content, row.get("real_sender_id"), nickname_map) + if not sender: + sender = "成员#%s" % row.get("real_sender_id") + + if isinstance(content, bytes): + display = content + else: + display = str(content) + + # 文本:去掉 wxid 前缀显示正文 + if local_type == 1 and cut: + display = display[cut:] + + return { + "local_id": row.get("local_id"), + "type": label, + "sender": sender, + "create_time": row.get("create_time"), + "sort_seq": row.get("sort_seq"), + "content": display, + "extra": extra, + } + + +def print_message(m: dict) -> None: + line = "[%s] %s %s | %s" % ( + m["type"], m["sender"], m["create_time"], str(m["content"])[:80]) + print(line) + ex = m["extra"] + if ex: + parts = [] + if ex.get("des"): + parts.append("描述: %s" % ex["des"]) + if ex.get("receivertitle"): + parts.append("祝福语: %s" % ex["receivertitle"]) + if ex.get("sceneid"): + parts.append("类型(sceneid): %s" % ex["sceneid"]) + if ex.get("total_num"): + parts.append("个数: %s" % ex["total_num"]) + if ex.get("paymsgid"): + parts.append("红包ID: %s" % ex["paymsgid"]) + if ex.get("fromusername"): + parts.append("来源: %s" % ex["fromusername"]) + if parts: + print(" " + " | ".join(parts)) + + +def main() -> None: + parser = argparse.ArgumentParser( + description="读取并识别固定群的最新消息(含红包解析)") + parser.add_argument("group", nargs="?", default="", + help="群名关键词(模糊匹配)") + parser.add_argument("--list-groups", action="store_true", + help="仅列出所有群,不读消息") + parser.add_argument("--limit", type=int, default=20, + help="读取最新 N 条消息(默认 20)") + parser.add_argument("--watch", action="store_true", + help="轮询模式:持续读取新消息") + parser.add_argument("--sleep", type=float, default=3.0, + help="轮询间隔秒数(默认 3)") + parser.add_argument("--red-only", action="store_true", + help="只显示红包消息") + args = parser.parse_args() + + db = WeChatDB() + nickname_map = load_nickname_map(db) + + if args.list_groups: + groups = list_groups(db) + print("群列表(%d 个,按消息数倒序):" % len(groups)) + for g in groups: + print(" %-28s %-32s %d 条" % (g["name"], g["wxid"], g["count"])) + return + + group = find_group(db, args.group) + if not group: + print("未找到群:%r(可用 --list-groups 查看全部群)" % args.group) + sys.exit(1) + + print("读取群:%s (%s)\n" % (group["name"], group["wxid"])) + + since_seq = 0 + while True: + rows = _raw_messages(db, group["wxid"], args.limit) + for row in rows: + if args.watch and row.get("sort_seq", 0) <= since_seq: + continue + info = classify_message(row, nickname_map) + if args.red_only and info["type"] != "红包": + continue + print_message(info) + since_seq = max(since_seq, row.get("sort_seq", 0)) + + if not args.watch: + break + print("\n--- 等待新消息 (%ds) ---" % args.sleep) + time.sleep(args.sleep) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/wechatauto/demo_guia.py b/wechatauto/demo_guia.py new file mode 100644 index 0000000..dd616d4 --- /dev/null +++ b/wechatauto/demo_guia.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- +"""wechatauto 复刻版 —— 坐标 + OCR 发送消息示例程序 + +针对微信 4.1.12+ 自绘聊天界面(UIA 方案失效)的发送路线: +定位窗口 → 打开会话 → 点击输入框 → 剪贴板粘贴 → 点击发送。 + +使用前提: + 1. 微信 4.x 已登录、桌面已解锁; + 2. 已安装依赖:pip install -e . + 若使用拼音回退输入,另需:pip install pypinyin + +用法: + python demo_guia.py +""" + +from __future__ import annotations + +import os +import sys +import time + +try: + os.system("chcp 65001 >nul 2>&1") +except Exception: + pass +try: + sys.stdout.reconfigure(encoding="utf-8", errors="replace") +except AttributeError: + pass + +from wechatauto.guia import WeChatGUI + + +def main(): + print("=" * 60) + print("wechatauto 复刻版 —— 坐标 + OCR 发送消息示例") + print("=" * 60) + + wx = WeChatGUI() + if not wx.desktop_available(): + print("\n[错误] 微信窗口不可见(可能处于锁屏/断开的会话)," + "请先解锁桌面后重试。") + sys.exit(1) + + wx.bring_to_front() + print(f"已连接到微信主窗口(hwnd={wx.main_hwnd})") + + # 1. 列出当前可见会话(OCR) + print("\n--- 当前可见会话 ---") + for row in wx.get_sessions()[:10]: + print(f" {row['name']}") + + # 2. 打开会话 + who = "文件传输助手" + print(f"\n--- 打开会话:{who} ---") + wx.open_chat(who) + time.sleep(0.5) + + # 3. 检测输入框 + box = wx.get_input_box() + if box: + x0, y0, x1, y1 = box + print(f"检测到输入框(相对坐标):x[{x0}..{x1}] y[{y0}..{y1}]") + else: + print("未检测到输入框") + + # 4. 发送消息 + text = "这是 wechatauto 复刻版坐标+OCR 自动化测试消息" + print(f"\n--- 发送消息 ---") + print(f"内容:{text}") + result = wx.send_msg(text, verify=True) + print(f"结果:{result}") + if not result: + sys.exit(1) + + # 5. 读取最近消息(数据库路线,交叉验证) + try: + from wechatauto.db import WeChatDB + db = WeChatDB() + hits = db.search_contact(who) + if hits: + msgs = db.get_messages(hits[0]["username"], limit=3) + print("\n--- 数据库读回最近 3 条 ---") + for m in reversed(msgs): + sender = "我" if m["sender_id"] == 2 else "对方" + t = time.strftime("%H:%M:%S", time.localtime(m["create_time"])) + print(f" [{t}] {sender} {m['content'][:40]}") + except Exception as e: + print(f"(数据库读回失败:{e})") + + print("\n完成。") + + +if __name__ == "__main__": + main() diff --git a/wechatauto/demo_listen.py b/wechatauto/demo_listen.py new file mode 100644 index 0000000..17abaad --- /dev/null +++ b/wechatauto/demo_listen.py @@ -0,0 +1,122 @@ +# -*- coding: utf-8 -*- +"""实时消息监听示例 —— 基于本地数据库增量轮询(Listener) + +用法: + python demo_listen.py [会话名1] [会话名2] ... + # 不带参数则默认监听「文件传输助手」 + +例: + python demo_listen.py wxid_xxx 123456@chatroom + python demo_listen.py 兔仔仔 我的群 # 昵称/备注会自动映射到会话 username + python demo_listen.py --all # 监听所有非隐藏会话 + +⚠️ 注意: + names 里最终匹配的是「会话 username」——即 get_sessions() 返回的 + wxid_xxx(个聊)或 xxx@chatroom(群聊),不是微信昵称、也不是 + 你设置的微信号(alias)。传入昵称/备注时本脚本会自动帮你转换; + 若转换失败会给出提示,此时请先运行一次本脚本查看列出的会话清单。 +""" +from __future__ import annotations + +import os +import sys +import time +import threading + +try: + os.system("chcp 65001 >nul 2>&1") +except Exception: + pass +try: + sys.stdout.reconfigure(encoding="utf-8", errors="replace") +except AttributeError: + pass + +from wechatauto.db import WeChatDB, Listener + + +def fmt_time(ts: float) -> str: + return time.strftime("%m-%d %H:%M:%S", time.localtime(ts)) + + +def sender_name(db, sid: int) -> str: + if sid == 2: + return "我" + nick = db.get_nickname(sid) if isinstance(sid, str) else None + return nick or f"用户{sid}" + + +def make_callback(db, chat_name: str): + """为某个会话生成回调函数。callback(msg: dict, listener)""" + def on_msg(msg: dict, lst: Listener): + sender = sender_name(db, msg["sender_id"]) + t = fmt_time(msg["create_time"]) + print(f"[{t}] {chat_name} | {sender} ({msg['type']}) {msg['content']}") + # 可在此扩展业务:msg['content'] 含关键字时自动回复等 + return on_msg + + +def resolve_name(db, sessions, raw: str) -> str: + """把用户输入(username / 昵称 / 备注 / 微信号)解析成会话 username。 + + 匹配优先级:session.username 精确匹配 > contact 的 nick_name/remark 精确匹配 + > 未命中直接原样返回(可能本身即为有效 username)。 + """ + sessions_by_user = {s["username"]: s for s in sessions} + if raw in sessions_by_user: + return raw + hits = db.search_contact(raw) + if hits: + return hits[0]["username"] + return raw + + +def main(): + names = [a for a in sys.argv[1:] if not a.startswith("-")] + all_chats = "--all" in sys.argv + + db = WeChatDB() + info = db.get_self_info() + print(f"账号:{info.get('nick_name') or info.get('username')}") + + # 1. 列出当前会话,供挑选(username 就是监听必须使用的值) + sessions = db.get_sessions(limit=30) + #print(f"\n当前会话(共 {len(sessions)} 个,最近 15 个,请把 username 填入 names):") + #for s in sessions[:15]: + #print(f" {s['username']:<24} 未读={s['unread']} {s['summary'][:24] or ''}") + + # 2. 确定监听目标 + if all_chats: + names = [s["username"] for s in sessions] + elif not names: + names = ["送你挖银子"] + if not names: + print("未找到任何会话,退出") + sys.exit(1) + + # 3. 昵称/备注 → username 映射 + resolved = [resolve_name(db, sessions, n) for n in names] + for raw, got in zip(names, resolved): + if raw != got: + print(f" 「{raw}」→ {got}") + + # 4. 注册监听(回调在后台线程触发) + lst = Listener(db, interval=1.0) + for name in resolved: + lst.add_listener(name, make_callback(db, name)) + print(f" 监听:{name}") + + print("\n开始监听(Ctrl+C 停止)...") + lst.start() + try: + while True: + time.sleep(1) + except KeyboardInterrupt: + pass + finally: + lst.stop() + print("\n已停止监听。") + + +if __name__ == "__main__": + main() diff --git a/wechatauto/demo_media.py b/wechatauto/demo_media.py new file mode 100644 index 0000000..e9bf70f --- /dev/null +++ b/wechatauto/demo_media.py @@ -0,0 +1,225 @@ +# -*- coding: utf-8 -*- +"""wechatauto 演示:读取并下载会话中的媒体文件(图片/语音/视频/文件)。 + +从微信本地数据库直接取媒体消息并解密落地,无需 GUI 操作。 + +用法: + python demo_media.py [会话] [--out 目录] [--photos N] + [--limit N] [--ids 3,5,7] [--filter 图片,文件] + [--list] [--open] + +默认行为(不带任何选项): + 下载文件传输助手里最近 N 张真实照片(jpg/png,自动跳过表情)和所有视频。 + +参数: + 会话 会话名(昵称/备注/username),默认「文件传输助手」 + --photos 默认模式下下载照片张数(默认 3) + --limit 列出最近 N 条消息(默认 200) + --ids 仅下载指定 local_id(逗号分隔,此时忽略 --limit) + --filter 只处理指定类型,逗号分隔,可选 图片/语音/视频/文件 + --out 下载保存目录(默认 ~/Documents/wechatauto_media) + --list 仅列出媒体消息,不下载 + --open 下载完成后用系统默认程序打开(仅单文件时有效) + +例: + python demo_media.py # 最近 3 张照片+视频 + python demo_media.py 兔仔仔 --photos 5 # 指定会话和数量 + python demo_media.py 文件传输助手 --list --limit 30 + python demo_media.py 我的群 --ids 105,107,109 --out D:\\media + python demo_media.py 文件传输助手 --filter 文件 --open + +原理: + WeChatDB.get_messages 列出消息(local_type 识别媒体类型), + MediaDownloader.download_media 按类型自动分发:图片解密 .dat、 + 语音 SILK 提取、视频/文件从缓存目录复制。 +""" + +from __future__ import annotations + +import argparse +import os +import sys +import time + +try: + os.system("chcp 65001 >nul 2>&1") +except Exception: + pass +try: + sys.stdout.reconfigure(encoding="utf-8", errors="replace") +except AttributeError: + pass + +from wechatauto import WeChatDB, MediaDownloader + +MEDIA_TYPES = {"图片": 3, "语音": 34, "视频": 43, "文件": 49} + + +def resolve_target(db: WeChatDB, raw: str) -> str: + hits = db.search_contact(raw) + return hits[0]["username"] if hits else raw + + +def fmt_size(n: int) -> str: + if n >= 1024 * 1024: + return f"{n / 1024 / 1024:.1f}MB" + if n >= 1024: + return f"{n / 1024:.1f}KB" + return f"{n}B" + + +def media_failure_reason(md, who: str, local_id: int) -> str: + """下载失败时给出细分原因(表情容器 / 未落地 / 不支持)。 + + 图片消息本地缓存的 .dat 解密后若为 wxgf(微信动画表情容器), + 库会按设计不落盘;本函数复现该判定以区分「表情」与「真失败」。 + """ + row = md.db.get_message_row(who, local_id) + if not row: + return "消息不存在" + t = row["local_type"] + if t == 3: # 图片 + md5 = md._img_md5(row) + dat = md._find_dat(who, md5, row["create_time"]) if md5 else None + if not dat: + return "本地无 .dat 缓存(未在微信查看过/已清理)" + try: + data = md.decrypt_image(dat) + except Exception as e: + return f"解密失败:{str(e)[:40]}" + if data[:4] == b"wxgf": + return "微信动画表情容器(wxgf)" + return "未知图片格式" + if t in (34, 43, 49): + return "本地缓存未落地或文件已清理" + return "类型不支持" + + +def main(): + parser = argparse.ArgumentParser( + description="wechatauto 演示:读取/下载微信会话中的媒体文件", + add_help=False) + parser.add_argument("target", nargs="?", default="26级金高新生群1群", + help="会话名(昵称/备注/username),默认文件传输助手") + parser.add_argument("--limit", type=int, default=1000, help="列出最近 N 条(默认 200)") + parser.add_argument("--photos", type=int, default=10, help="默认模式下载照片张数(默认 3)") + parser.add_argument("--ids", default=None, + help="仅下载指定 local_id,逗号分隔,如 105,107") + parser.add_argument("--filter", default=None, + help="仅处理指定类型,逗号分隔:图片/语音/视频/文件") + parser.add_argument("--out", default=None, help="下载保存目录") + parser.add_argument("--image-key", default=None, + help="图片 AES 密钥(16 位,若内存扫描不可用)") + parser.add_argument("--list", action="store_true", help="仅列出媒体消息,不下载") + parser.add_argument("--open", action="store_true", + help="下载后用系统默认程序打开(仅单文件)") + parser.add_argument("-h", "--help", action="help") + args = parser.parse_args() + + filt = None + if args.filter: + filt = set(t.strip() for t in args.filter.split(",") if t.strip()) + unknown = [t for t in filt if t not in MEDIA_TYPES] + if unknown: + print(f"未知类型:{', '.join(unknown)}(可选:图片/语音/视频/文件)") + sys.exit(1) + + print("=" * 60) + print("wechatauto 媒体读取演示") + print("=" * 60) + + db = WeChatDB() + info = db.get_self_info() + print(f"账号:{info.get('nick_name') or info.get('username')}") + who = resolve_target(db, args.target) + print(f"会话:{args.target} -> {who}") + + # ---- 指定 local_id:直接下载 ---- + if args.ids: + ids = [int(x.strip()) for x in args.ids.split(",") if x.strip().isdigit()] + if not ids: + print("--ids 无效") + sys.exit(1) + md = MediaDownloader(db, save_dir=args.out, image_key=args.image_key) + for lid in ids: + row = db.get_message_row(who, lid) + if not row: + print(f" local_id={lid} 未找到,跳过") + continue + name = next((k for k, v in MEDIA_TYPES.items() if v == row["local_type"]), "") + t = time.strftime("%m-%d %H:%M", time.localtime(row["create_time"])) + label = name or ("类型%d" % row["local_type"]) + print(f"\n[local_id={lid}] {t} {label}") + out = md.download_media(who, lid, args.out) + if out: + print(f" ✅ 已保存:{out} ({fmt_size(os.path.getsize(out))})") + if args.open: + os.startfile(out) + else: + print(f" ⚠️ 下载失败:{media_failure_reason(md, who, lid)}") + print("\n完成。") + sys.exit(0) + + # ---- 列出最近消息并筛选媒体 ---- + mode = "默认照片+视频" if filt is None else "+".join(sorted(filt)) + msgs = db.get_messages(who, limit=args.limit) + media_msgs = [] + print(f"\n最近 {len(msgs)} 条消息中的媒体项(模式:{mode}):") + for m in reversed(msgs): + name = MEDIA_TYPES.get(m.get("type"), "") + if not name: + continue + if filt and m.get("type") not in filt: + continue + if filt is None and m.get("type") not in ("图片", "视频"): + continue + t = time.strftime("%m-%d %H:%M", time.localtime(m["create_time"])) + sender = "我" if m["sender_id"] == 2 else "对方" + media_msgs.append(m) + print(f" {m['local_id']:<6} {t} {sender} {m.get('type')} {m.get('content', '')[:40]}") + + if args.list: + print(f"\n共 {len(media_msgs)} 条媒体消息(用 --ids 或 --filter 配合下载)。") + sys.exit(0) + + if not media_msgs: + print("\n没有符合条件的媒体消息。") + sys.exit(0) + + # ---- 下载筛选出的媒体 ---- + md = MediaDownloader(db, save_dir=args.out, image_key=args.image_key) + ok = skip = fail = 0 + photo_done = 0 + for m in media_msgs: + t = time.strftime("%H:%M:%S", time.localtime(m["create_time"])) + print(f"\n[local_id={m['local_id']}] {t} {m.get('type')}") + is_photo_target = filt is None and m.get("type") == "图片" + if is_photo_target and photo_done >= args.photos: + print(f" ➖ 已达照片上限 {args.photos} 张,停止") + break + out = md.download_media(who, m["local_id"], args.out) + if out: + print(f" ✅ {fmt_size(os.path.getsize(out))} {out}") + ok += 1 + if is_photo_target: + photo_done += 1 + else: + reason = media_failure_reason(md, who, m["local_id"]) + if "表情容器" in reason: + print(f" ➖ {reason}") + skip += 1 + else: + print(f" ⚠️ 下载失败:{reason}") + fail += 1 + + print(f"\n完成:成功 {ok} 项,跳过 {skip} 项(表情),失败 {fail} 项。" + + (f" 保存目录:{os.path.abspath(args.out or md.save_dir)}" if ok else "")) + if args.open and ok == 1: + out = md.download_media(who, media_msgs[0]["local_id"], args.out) + if out: + os.startfile(out) + sys.exit(0 if fail == 0 else 1) + + +if __name__ == "__main__": + main() diff --git a/wechatauto/demo_reply_at.py b/wechatauto/demo_reply_at.py new file mode 100644 index 0000000..a9c714d --- /dev/null +++ b/wechatauto/demo_reply_at.py @@ -0,0 +1,76 @@ +# -*- coding: utf-8 -*- +"""reply_msg / at_member 实测脚本(对应 README §7 待实测功能)""" +from __future__ import annotations + +import os +import sys +import time + +try: + os.system("chcp 65001 >nul 2>&1") +except Exception: + pass +try: + sys.stdout.reconfigure(encoding="utf-8", errors="replace") +except AttributeError: + pass + +from wechatauto.guia import WeChatGUI +from wechatauto.db import WeChatDB + + +def db_latest(who, n=5): + """数据库读回最近 n 条,交叉验证发送结果。""" + try: + db = WeChatDB() + hits = db.search_contact(who) + if not hits: + return [] + msgs = db.get_messages(hits[0]["username"], limit=n) + return [f"[{time.strftime('%H:%M:%S', time.localtime(m['create_time']))}] " + f"{'我' if m['sender_id'] == 2 else '对方'} {m['content'][:40]}" + for m in reversed(msgs)] + except Exception as e: + return [f"(读回失败:{e})"] + + +def main(): + wx = WeChatGUI() + if not wx.desktop_available(): + print("[错误] 微信窗口不可见,请解锁桌面后重试") + sys.exit(1) + + # ========== 1. reply_msg:回复最近一条消息 ========== + who = "文件传输助手" + print("=" * 60) + print(f"[1] reply_msg 回复最近一条消息(会话:{who})") + print("=" * 60) + print("数据库当前最近 3 条:") + for line in db_latest(who, 3): + print(" ", line) + + r = wx.reply_msg("这是自动回复测试 [reply]", who=who, verify=True) + print(f"\nreply_msg 结果:\n ok={r.is_success}\n 消息={r['message']}\n 数据={r['data']}") + + print("\n发送后数据库最近 5 条:") + for line in db_latest(who, 5): + print(" ", line) + + # ========== 2. at_member:群聊 @ 成员(改你实际的群名和成员) ========== + group = "STABLE一1一161008" # ← 改成你的群名 + member = "文件传输助手" # ← 改成群内的成员名 + print("\n" + "=" * 60) + print(f"[2] at_member 群聊 @ 成员(群:{group},成员:{member})") + print("=" * 60) + + r2 = wx.at_member(member, "大家看下这条 @ 测试", who=group, verify=True) + print(f"at_member 结果:\n ok={r2.is_success}\n 消息={r2['message']}\n 数据={r2['data']}") + + print("\n发送后数据库最近 5 条:") + for line in db_latest(group, 5): + print(" ", line) + + print("\n完成。若 ok=False,请把打印的失败信息贴出来。") + +if __name__ == "__main__": + main() diff --git a/wechatauto/demo_robust.py b/wechatauto/demo_robust.py new file mode 100644 index 0000000..7c10277 --- /dev/null +++ b/wechatauto/demo_robust.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +"""wechatauto v1.0.9 稳健性演示 —— 失败可回退,绝不崩溃 + +演示「失败回退」设计原则: + 1. 微信未打开时执行 voice_call / poke / open_chat, + 返回明确失败(WxResponse.failure / False),而非崩溃/抛异常; + 2. 微信已打开时展示正常成功路径(语音通话、拍一拍); + 3. 截图失败自动回退连通域(表情截图不中断)。 + +用法: + python demo_robust.py # 自动检测微信状态演示 + python demo_robust.py --force-off # 强制演示"微信未打开"分支 +""" +from __future__ import annotations + +import os +import sys +import time + +try: + os.system("chcp 65001 >nul 2>&1") +except Exception: + pass +try: + sys.stdout.reconfigure(encoding="utf-8", errors="replace") +except AttributeError: + pass + +from wechatauto import WeChat +from wechatauto.wx import WxResponse + +WHO = "送你挖银子" + + +def _show(tag: str, r) -> None: + """统一打印 WxResponse 结果。""" + if isinstance(r, WxResponse): + status = r["status"] + msg = r["message"] or "" + print(f" [{tag}] {status} :: {msg}") + return + print(f" [{tag}] 返回值 {r!r}") + + +def _guard(func): + """包装:任何异常都记录为失败而非崩溃。""" + def wrapper(*a, **k): + try: + return func(*a, **k) + except Exception as e: + import traceback + print(f" [异常拦截] {type(e).__name__}: {e}") + print(f" (演示失败回退:未崩溃,异常已兜底)") + return WxResponse.failure(f"异常已拦截:{e}") + return wrapper + + +def _wechat_alive() -> bool: + """不实例化 WeChat/WeChatGUI(微信未打开时构造会抛异常),直接探测主窗口。""" + try: + import ctypes + from wechatauto.guia import WX_MAIN_WIN_TITLE + hwnd = ctypes.windll.user32.FindWindowW(None, WX_MAIN_WIN_TITLE) + return bool(hwnd) + except Exception: + return False + + +def demo_wechat_closed() -> None: + """微信未打开/未登录时调用各功能,验证返回失败而非崩溃。 + + 注意:不触发热激活(写 Weixin.dll 的 Qt accessibility gate)——微信 + 未登录时没有可用的 ``mmui::MainWindow``,热激活无意义且属不必要的内存 + 写入。演示通过给驱动注入「未就绪」状态,让各功能走失败回退分支。 + """ + print("\n" + "=" * 60) + print("场景 A:微信未打开/未登录 —— 功能应优雅失败") + print("=" * 60) + try: + from wechatauto.uia_driver import WeChatUIA + + eng = WeChatUIA(timeout=8.0) # 可无窗口构造 + print(" 构造 UIA 驱动成功(未触碰微信进程)…") + # 阻止 ensure_window 触发热激活:微信未登录时打桩掉窗口探测与 + # 唤醒路径,让各功能直接走失败返回(不拉起微信、不写其进程内存)。 + eng._find_main = lambda: None + eng._login_window = lambda: None + eng._wechat_hwnds = lambda: [] + eng.ensure_window = lambda *a, **k: False + print(" 已打桩窗口探测(微信未登录,跳过热激活与拉起)…") + except Exception as e: + import traceback + print(f" [构造拦截] {type(e).__name__}: {e}") + print(f" (演示失败回退:驱动不可用时降级,不中断)") + _show("voice_call", WxResponse.failure(f"UIA 驱动不可用:{e}")) + _show("poke", WxResponse.failure(f"UIA 驱动不可用:{e}")) + return + + t0 = time.time() + ok = _guard(eng.voice_call)(who=WHO) + _show("voice_call", + WxResponse.success("已发起通话") if ok + else WxResponse.failure("UIA 驱动不可用,无法发起通话")) + print(f" (耗时 {time.time()-t0:.1f}s,未崩溃)") + + t0 = time.time() + ok = _guard(eng.poke)(who=WHO) + _show("poke", + WxResponse.success("已对 " + WHO + " 拍一拍") if ok + else WxResponse.failure("拍一拍失败(未找到对方消息或菜单不可识别)")) + print(f" (耗时 {time.time()-t0:.1f}s,未崩溃)") + + print("\n -> 微信未打开/未登录时:返回明确失败信息,无异常栈、无崩溃。") + print(" 验证调用方只需判断返回值即可安全降级,不干扰其他功能。") + + +def demo_wechat_open(wx: WeChat) -> None: + """微信已打开时展示正常成功路径。""" + print("\n" + "=" * 60) + print("场景 B:微信已打开 —— 功能正常工作") + print("=" * 60) + print(f" 打开会话「{WHO}」并验证…") + r = wx.ChatWith(WHO) + _show("ChatWith", r) + if not isinstance(r, str) or not r: + print(" 会话打开失败,跳过成功路径演示。") + return + chat = wx._cur() + try: + ans = input(" 发起语音通话? [Y/n] ").strip().lower() + except (EOFError, KeyboardInterrupt): + ans = "" + if ans not in ("n", "no"): + _show("voice_call", _guard(chat.VoiceCall)()) + time.sleep(1) + print(" (请手动挂断)") + try: + ans = input(" 发起拍一拍? [Y/n] ").strip().lower() + except (EOFError, KeyboardInterrupt): + ans = "" + if ans not in ("n", "no"): + _show("poke", _guard(chat.Poke)()) + print("\n -> 成功路径正常。") + + +def main(): + args = [a for a in sys.argv[1:]] + force_off = "--force-off" in args + + alive = _wechat_alive() + if force_off: + alive = False + print(f" 微信主窗口存活:{alive}") + + try: + if alive: + wx = WeChat() + print(f"当前登录:{wx.nickname}") + demo_wechat_open(wx) + demo_wechat_closed() + else: + demo_wechat_closed() + except RuntimeError as e: + # 探测误判(如残留窗口/登录态)导致构造失败 → 降级到未打开分支 + print(f" [探测误判] WeChat 构造失败:{e}") + print(" (降级演示:按微信未打开处理)") + demo_wechat_closed() + + print("\n稳健性演示完成。") + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/wechatauto/demo_send.py b/wechatauto/demo_send.py new file mode 100644 index 0000000..69d5bba --- /dev/null +++ b/wechatauto/demo_send.py @@ -0,0 +1,193 @@ +# -*- coding: utf-8 -*- +"""wechatauto 测试发送脚本 —— 坐标 + OCR 发送(微信 4.x 自绘界面) + +默认发送三件套:一条测试消息 + 一张图片 + 一个文件(README.md)。 + +用法: + python demo_send.py [目标] [内容] [--image [图片路径]] [--file 文件路径] + [--skip-text] [--skip-image] [--skip-file] + [--verify] [--times N] + +参数: + 目标 要发送到的会话名(昵称/备注/搜索关键词),默认「文件传输助手」 + 内容 文本消息内容;不填则生成带时间戳的测试消息 + --image 图片路径。不带路径时使用默认图片(RWTemp 最新截图) + --file 文件路径。默认 C:\\Users\\fxj13\\Documents\\Default Project\\README.md + --skip-text 跳过文本消息 + --skip-image 跳过图片 + --skip-file 跳过文件 + --verify 发送后通过本地数据库读回确认 + --times 重复发送轮数(每轮三件套,默认 1) + +例: + python demo_send.py # 三件套发到文件传输助手 + python demo_send.py 兔仔仔 # 三件套发给人 + python demo_send.py 文件传输助手 "你好" # 自定义文本 + python demo_send.py 我的群 --image C:\\pics\\a.png # 指定图片 + python demo_send.py 文件传输助手 --skip-text --skip-image # 只发文件 + +原理: + WeChatGUI.send_msg 采用 坐标+OCR:激活窗口 → 搜索并打开会话 → 点击输入框 + → 剪贴板粘贴 → 点击发送;可选 verify 用数据库读回(sender_id=2)确认。 +""" + +from __future__ import annotations + +import argparse +import glob +import os +import sys +import time + +try: + os.system("chcp 65001 >nul 2>&1") +except Exception: + pass +try: + sys.stdout.reconfigure(encoding="utf-8", errors="replace") +except AttributeError: + pass + +from wechatauto import WeChatGUI, WeChatDB, WxResponse + +# 默认图片:RWTemp 中最新的截图(微信收到的图片会缓存在这里) +DEFAULT_IMAGE = ( + r"D:\微信文件\xwechat_files\wxid_gzalsg6ockm822_236a\temp\RWTemp\2026-08" + r"\b0c56fafd84abdd055b91d47b1516550.png" +) +# 默认文件 +DEFAULT_FILE = r"C:\Users\fxj13\Documents\Default Project\README.md" + + +def pick_default_image() -> str: + """在 RWTemp 目录下找最新的一张图片;找不到则回退到 DEFAULT_IMAGE。""" + base = os.path.dirname(DEFAULT_IMAGE) + if os.path.isdir(base): + imgs = sorted( + glob.glob(os.path.join(base, "*.png")) + + glob.glob(os.path.join(base, "*.jpg")) + + glob.glob(os.path.join(base, "*.jpeg")), + key=os.path.getmtime, + ) + if imgs: + return imgs[-1] + return DEFAULT_IMAGE + + +def resolve_target(db: WeChatDB, raw: str) -> str: + """把输入(username / 昵称 / 备注)解析成会话 username 并打印映射。""" + hits = db.search_contact(raw) + if hits: + return hits[0]["username"] + return raw + + +def show_result(resp: WxResponse) -> bool: + """打印发送结果。WxResponse 是 dict,状态值:成功/失败/错误。""" + print(f" [{resp['status']}] {resp['message']}") + return resp.is_success + + +def read_back(db: WeChatDB, who: str, text: str = None, n: int = 5) -> None: + """从数据库读回最近消息做交叉验证。""" + msgs = db.get_messages(who, limit=n) + print(f"\n--- 数据库读回最近 {len(msgs)} 条 ---") + for m in reversed(msgs): + sender = "我" if m["sender_id"] == 2 else "对方" + t = time.strftime("%H:%M:%S", time.localtime(m["create_time"])) + print(f" [{t}] {sender} {m['content'][:50]}") + if text: + sent = any(m["sender_id"] == 2 and text in (m.get("content") or "") + for m in msgs) + print(f"\n验证结果:{'✅ 已找到我发送的该消息' if sent else '⚠️ 最近记录中未找到该消息(可能未落库或异步延迟)'}") + + +def main(): + parser = argparse.ArgumentParser( + description="wechatauto 测试发送脚本(坐标+OCR 发送)", add_help=False) + parser.add_argument("target", nargs="?", default="文件传输助手", + help="目标会话(昵称/备注/username),默认文件传输助手") + parser.add_argument("content", nargs="?", default=None, + help="文本内容;不填则生成带时间戳的测试消息") + parser.add_argument("--image", nargs="?", const=True, default=None, + help="图片路径。不带路径时用默认图片(RWTemp 最新截图)") + parser.add_argument("--file", nargs="?", const=True, default=None, + help="文件路径。不带路径时用默认文件 README.md") + parser.add_argument("--skip-text", action="store_true", help="跳过文本消息") + parser.add_argument("--skip-image", action="store_true", help="跳过图片") + parser.add_argument("--skip-file", action="store_true", help="跳过文件") + parser.add_argument("--verify", action="store_true", help="发送后读库确认") + parser.add_argument("--times", type=int, default=1, help="重复发送轮数") + parser.add_argument("-h", "--help", action="help") + args = parser.parse_args() + + #who = args.target + who = "卢立竺" + text = args.content or f"wechatauto 发送测试 {time.strftime('%H:%M:%S')}" + image = pick_default_image() if (args.image is True or (args.image is None and not args.skip_image)) else args.image + file_ = DEFAULT_FILE if (args.file is True or (args.file is None and not args.skip_file)) else args.file + if args.skip_text: + text = None + if args.skip_image: + image = None + if args.skip_file: + file_ = None + + print("=" * 60) + print("wechatauto 测试发送") + print("=" * 60) + if text: + print(f" 文本:{text}") + if image: + print(f" 图片:{image}") + if file_: + print(f" 文件:{file_}") + if not (text or image or file_): + print(" (未选择任何发送内容)") + + # 1. 目标会话 username 解析(仅用于读回验证) + db = None + target_username = None + if args.verify: + db = WeChatDB() + info = db.get_self_info() + print(f"账号:{info.get('nick_name') or info.get('username')}") + target_username = resolve_target(db, who) + print(f"目标:{who} -> {target_username}") + + # 2. 初始化 GUI 并检查桌面可用 + wx = WeChatGUI() + if not wx.desktop_available(): + print("\n[错误] 微信窗口不可见(可能锁屏/会话断开),请解锁桌面后重试。") + sys.exit(1) + wx.bring_to_front() + print(f"已连接微信主窗口(hwnd={wx.main_hwnd})") + + # 3. 逐轮发送三件套 + ok = True + for i in range(args.times): + if args.times > 1: + print(f"\n--- 第 {i + 1}/{args.times} 轮 ---") + if text: + print("\n[发送文本]") + if not show_result(wx.send_msg(text, who, verify=args.verify)): + ok = False + if image: + print("\n[发送图片]") + if not show_result(wx.send_image(image, who, verify=args.verify)): + ok = False + if file_: + print("\n[发送文件]") + if not show_result(wx.send_file(file_, who, verify=args.verify)): + ok = False + + # 4. 读回确认 + if args.verify and db and target_username: + read_back(db, target_username, text) + + print("\n" + ("✅ 全部发送完成。" if ok else "⚠️ 存在失败的发送,请查看上方结果。")) + sys.exit(0 if ok else 1) + + +if __name__ == "__main__": + main() diff --git a/wechatauto/demo_v109.py b/wechatauto/demo_v109.py new file mode 100644 index 0000000..5f58fbd --- /dev/null +++ b/wechatauto/demo_v109.py @@ -0,0 +1,192 @@ +# -*- coding: utf-8 -*- +"""wechatauto v1.0.9 新功能演示 —— open_chat 账号搜索 / 语音通话 / 拍一拍 / UIA 表情截图 + +覆盖本次新增/优化能力: + 1. open_chat 账号(wxid)搜索修复:微信搜索框不认 wxid,自动经 DB + 映射为昵称/备注/微信号再搜索; + 2. Chat.VoiceCall() 发起语音通话(UIA 定位标题栏通话按钮); + 3. Chat.Poke() 发起拍一拍(右键头像 + OCR 定位「拍一拍」菜单); + 4. UIA 表情包精确截图(EmojiMessage.capture() 优先走 UIA 定位)。 + +用法: + python demo_v109.py # 全部顺序演示(交互确认) + python demo_v109.py 豆芽 # 指定演示对象 + python demo_v109.py --only open_chat 豆芽 # 只跑某一步 + +注意:语音通话 / 拍一拍会真实触发操作,请确认目标联系人可接受。 +""" +from __future__ import annotations + +import os +import sys +import time + +try: + os.system("chcp 65001 >nul 2>&1") +except Exception: + pass +try: + sys.stdout.reconfigure(encoding="utf-8", errors="replace") +except AttributeError: + pass + +from wechatauto import WeChat +from wechatauto.wx import WxResponse + +WHO_DEFAULT = "送你挖银子" +EMOJI_SAVE_DIR = os.path.join(os.path.expanduser("~"), "emoji_capture") + + +def _is_ok(r) -> bool: + """ChatWith 成功返回会话显示名(str),失败返回 None。""" + return isinstance(r, str) and bool(r) + + +def _confirm(prompt: str) -> bool: + """交互确认,返回是否继续。""" + try: + return input(prompt + " [y/N] ").strip().lower() in ("y", "yes") + except (EOFError, KeyboardInterrupt): + return True + + +def demo_open_chat_by_wxid(wx: WeChat) -> None: + """按账号(wxid)打开会话 —— 验证搜索框不认 wxid 的映射修复。""" + print("\n" + "=" * 60) + print("[1/4] open_chat 账号搜索(wxid 映射)") + print("=" * 60) + db = wx._db + info = db.get_self_info() + self_username = info.get("username", "") + print(f"本机账号:{self_username}") + print("从通讯录中找一个联系人账号(wxid)来测试:") + contacts = db.search_contact("")[:20] or [] + if not contacts: + print(" 通讯录为空,跳过。") + return + for i, c in enumerate(contacts[:10]): + name = c.get("nick_name") or c.get("remark") or c.get("username") + print(f" [{i}] {name} (wxid={c.get('username')})") + try: + pick = int(input(" 输入序号:").strip()) + except (EOFError, KeyboardInterrupt, ValueError): + return + contact = contacts[pick] + username = contact.get("username", "") + display = contact.get("nick_name") or contact.get("remark") or username + print(f" 尝试 open_chat(wxid={username}) …") + t0 = time.time() + ok = wx._gui.open_chat(username) + print(f" => 打开 {display}(按 wxid){'成功' if ok else '失败'} {time.time()-t0:.1f}s") + if ok: + uia = wx._gui._get_uia() + cur = uia.current_chat() if uia is not None else None + print(f" 当前会话确认:{cur}") + + +def demo_voice_call(wx: WeChat, who: str) -> None: + """发起语音通话。""" + print("\n" + "=" * 60) + print("[2/4] 语音通话 VoiceCall") + print("=" * 60) + print(f" 将向「{who}」发起语音通话(真实呼出)…") + if not _confirm(" 确认拨出?"): + print(" 已跳过。") + return + r = wx.ChatWith(who) + if not _is_ok(r): + print(f" 打开会话失败:{r}") + return + t0 = time.time() + r = wx._cur().VoiceCall() + print(f" VoiceCall => {r['status']} {r['message']} ({time.time()-t0:.1f}s)") + print(" (请手动挂断结束通话)") + + +def demo_poke(wx: WeChat, who: str) -> None: + """发起拍一拍。""" + print("\n" + "=" * 60) + print("[3/4] 拍一拍 Poke") + print("=" * 60) + print(f" 将对「{who}」发起拍一拍(真实触发)…") + if not _confirm(" 确认发送?"): + print(" 已跳过。") + return + r = wx.ChatWith(who) + if not _is_ok(r): + print(f" 打开会话失败:{r}") + return + t0 = time.time() + r = wx._cur().Poke() + print(f" Poke => {r['status']} {r['message']} ({time.time()-t0:.1f}s)") + + +def demo_emoji_capture(wx: WeChat, who: str) -> None: + """UIA 表情截图:找会话最新一条动画表情并截图。""" + print("\n" + "=" * 60) + print("[4/4] UIA 表情包精确截图") + print("=" * 60) + r = wx.ChatWith(who) + if not _is_ok(r): + print(f" 打开会话失败:{r.message}") + return + os.makedirs(EMOJI_SAVE_DIR, exist_ok=True) + chat = wx._cur() + msgs = chat.GetAllMessage() + emo = [m for m in msgs if getattr(m, "type", None) == "emotion"] + if not emo: + print(f" 会话「{who}」最近 50 条无表情消息,跳过(可先发一个表情再跑)。") + return + msg = emo[0] + print(f" 找到表情消息:方向={msg.attr},开始 UIA 截图…") + t0 = time.time() + path = msg.capture(save_dir=EMOJI_SAVE_DIR) + if path: + size = None + try: + from PIL import Image + size = Image.open(path).size + except Exception: + pass + print(f" => 截图成功 {size if size else ''} {time.time()-t0:.1f}s") + print(f" 路径:{path}") + else: + print(f" => 截图失败({time.time()-t0:.1f}s)") + + +def main(): + args = [a for a in sys.argv[1:]] + only = None + if "--only" in args: + i = args.index("--only") + only = args[i + 1] + args = args[:i] + args[i + 2:] + names = [a for a in args if not a.startswith("--")] + who = names[0] if names else WHO_DEFAULT + + wx = WeChat() + print(f"当前登录:{wx.nickname}") + + steps = { + #"open_chat": demo_open_chat_by_wxid, + #"voice": demo_voice_call, + "poke": demo_poke, + #"emoji": demo_emoji_capture, + } + if only: + fn = steps.get(only) + if not fn: + print(f"未知步骤:{only}(可选:{', '.join(steps)})") + sys.exit(1) + fn(wx, who) if only != "open_chat" else fn(wx) + return + + #demo_open_chat_by_wxid(wx) + #demo_voice_call(wx, who) + demo_poke(wx, who) + #demo_emoji_capture(wx, who) + #print("\n全部演示完成。") + + +if __name__ == "__main__": + main() diff --git a/wechatauto/diagnose_keys.py b/wechatauto/diagnose_keys.py new file mode 100644 index 0000000..c5925b6 --- /dev/null +++ b/wechatauto/diagnose_keys.py @@ -0,0 +1,175 @@ +# -*- coding: utf-8 -*- +"""密钥提取失败诊断脚本。 + +在微信【已登录】状态下运行(务必让微信窗口保持打开): + + python -m wechatauto.diagnose_keys + +或直接: + + python wechatauto/diagnose_keys.py + +把输出完整发给维护者。 +""" +import json +import os +import subprocess +import sys +import traceback + +print("=" * 60) +print("wechatauto-replica key diagnostic") +print("=" * 60) +print("Python:", sys.version.split()[0]) +print("Python bits:", 64 if sys.maxsize > 2**32 else 32) +print("OS:", sys.platform) + +# 1. library version +try: + import wechatauto + from wechatauto import WeChatDB + from wechatauto.db import _find_account_dirs + print("lib version:", getattr(wechatauto, "__version__", "?")) + import wechatauto.db as dbmod + print("db.py:", dbmod.__file__) +except Exception as e: + print("import error:", repr(e)) + traceback.print_exc() + +# 2. Weixin processes +print("\n--- Weixin processes ---") +weixin_pids = [] +try: + r = subprocess.run( + ["tasklist", "/FI", "IMAGENAME eq Weixin.exe", "/FO", "CSV", "/NH"], + capture_output=True, text=True) + print("tasklist:\n%s" % (r.stdout.strip() or "(no Weixin.exe)")) + for line in r.stdout.strip().splitlines(): + parts = line.strip('"').split('","') + if len(parts) >= 2 and parts[1].isdigit(): + weixin_pids.append(int(parts[1])) +except Exception as e: + print("tasklist failed:", repr(e)) + +# 2b. per-PID permission / read test (key root-cause for silent 0-key extraction) +print("\n--- per-PID access test ---") +if not weixin_pids: + print("(no Weixin.exe running - open WeChat and log in first)") +else: + import ctypes + from ctypes import wintypes + from wechatauto.db import _MBI + k32 = ctypes.WinDLL("kernel32", use_last_error=True) + k32.OpenProcess.restype = wintypes.HANDLE + k32.OpenProcess.argtypes = [wintypes.DWORD, wintypes.BOOL, wintypes.DWORD] + k32.ReadProcessMemory.argtypes = [ + wintypes.HANDLE, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t, + ctypes.POINTER(ctypes.c_size_t)] + k32.VirtualQueryEx.argtypes = [ + wintypes.HANDLE, ctypes.c_void_p, ctypes.POINTER(_MBI), ctypes.c_size_t] + for pid in weixin_pids: + h = k32.OpenProcess(0x0010 | 0x0400, False, pid) # VM_READ | QUERY_INFORMATION + if not h: + err = ctypes.get_last_error() + print("PID %d: OpenProcess FAILED (error %d - likely needs admin / same-elevation)" % (pid, err)) + continue + ok = 0 + first_region = None + addr = ctypes.c_void_p(0) + for _ in range(4000): + mbi = _MBI() + n = k32.VirtualQueryEx(h, addr, ctypes.byref(mbi), ctypes.sizeof(_MBI)) + if n == 0: + break + if (mbi.State == 0x1000 and (mbi.Protect & 0xFF) & 0xE6 + and not (mbi.Protect & 0x100) and 0 < mbi.RegionSize < 0x10000000): + buf = ctypes.create_string_buffer(8) + br = ctypes.c_size_t(0) + if k32.ReadProcessMemory(h, ctypes.c_void_p(mbi.BaseAddress or 0), buf, 8, ctypes.byref(br)) and br.value == 8: + ok += 1 + if first_region is None: + first_region = mbi.BaseAddress or 0 + break + addr = ctypes.c_void_p((mbi.BaseAddress or 0) + mbi.RegionSize) + ctypes.windll.kernel32.CloseHandle(h) + print("PID %d: OpenProcess OK, first readable region: %s (readable-region check %s)" + % (pid, "0x%x" % first_region if first_region else "NONE", "OK" if ok else "FAILED")) + +# 3. data dir detection +print("\n--- data dir ---") +try: + from wechatauto.db import auto_detect_db_dir + d = auto_detect_db_dir() + print("auto_detect_db_dir:", d) + if d and os.path.isdir(d): + for x in os.listdir(d): + if os.path.isdir(os.path.join(d, x, "db_storage")): + print(" account dir:", x) +except Exception as e: + print("dir detect error:", repr(e)) + +# 4. WeChatDB init (uses cached keys) +print("\n--- WeChatDB init ---") +db = None +try: + db = WeChatDB() + print("workdir:", db.workdir) + print("keys_file:", db.keys_file, "exists:", os.path.exists(db.keys_file)) + print("account:", db.account) + if os.path.exists(db.keys_file): + with open(db.keys_file, encoding="utf-8") as f: + keys = json.load(f) + print("keys cached:", len(keys)) + for k in sorted(keys): + print(" ", k) + else: + print("keys cached: (file not found)") + print("db_files:", len(db._db_files)) + print("keys loaded:", len(db._keys)) + missing = [rel for rel, _, _ in db._db_files if rel not in db._keys] + print("missing:", missing) + print("unkeyed:", db.unkeyed) + # which account dirs exist vs which one was picked + print("accounts on disk:", sorted( + os.path.basename(x) for x in _find_account_dirs(db.db_dir))) + print("picked account: ", db.account) +except Exception as e: + print("init error:", repr(e)) + traceback.print_exc() + +# 5. fresh key extraction from memory +print("\n--- extract_keys from Weixin.exe memory ---") +try: + if db is None: + db = WeChatDB() + pids = db._find_weixin_pids() + print("Weixin PIDs:", pids) + if not pids: + print("no Weixin.exe running - open WeChat and log in first") + else: + keys = db.extract_keys() + print("extracted:", len(keys)) + for k in sorted(keys): + print(" ", k) + missing2 = [rel for rel, _, _ in db._db_files if rel not in keys] + print("still missing:", missing2) +except Exception as e: + print("extract error:", repr(e)) + traceback.print_exc() + +# 6. verify cached keys actually work +print("\n--- verify cached keys ---") +try: + if db is None: + db = WeChatDB() + works = 0 + for rel, _, _ in db._db_files: + if db._key_works(rel): + works += 1 + print("keys that verify: %d / %d" % (works, len(db._db_files))) +except Exception as e: + print("verify error:", repr(e)) + +print("=" * 60) +print("done. send the full output to the maintainer.") +print("=" * 60) \ No newline at end of file diff --git a/wechatauto/exceptions.py b/wechatauto/exceptions.py new file mode 100644 index 0000000..35c57b1 --- /dev/null +++ b/wechatauto/exceptions.py @@ -0,0 +1,65 @@ +"""项目内部使用的异常类型定义。""" + +from __future__ import annotations + +from dataclasses import dataclass +from typing import Optional + + +@dataclass +class WechatautoError(Exception): + """基础异常类型。 + + Args: + message: 错误信息。若未提供则使用 ``default_message``。 + detail: 附加的上下文信息,可用于在日志中打印更友好的提示。 + """ + + default_message: str = "" + message: Optional[str] = None + detail: Optional[str] = None + + def __post_init__(self) -> None: + msg = self.message or self.default_message or self.__class__.__name__ + super().__init__(msg) + self.message = msg + + def __str__(self) -> str: + return self.message or "" + + def __repr__(self) -> str: + detail = f", detail={self.detail!r}" if self.detail else "" + return f"{self.__class__.__name__}(message={self.message!r}{detail})" + + +class NetWorkError(WechatautoError): + """网络请求相关异常。""" + + default_message = "微信无法连接到网络" + + +class WechatautoUINotFoundError(WechatautoError): + """当无法定位到指定 UI 控件时抛出。""" + + default_message = "未找到目标 UI 控件" + + +class WechatautoNoteLoadTimeoutError(WechatautoError): + """微信笔记加载超时异常。""" + + default_message = "微信笔记加载超时" + + +class WechatautoNotLoggedInError(WechatautoError): + """未找到已登录的微信窗口时抛出。""" + + default_message = "未找到已登录的微信主窗口" + + +__all__ = [ + "WechatautoError", + "NetWorkError", + "WechatautoUINotFoundError", + "WechatautoNoteLoadTimeoutError", + "WechatautoNotLoggedInError", +] diff --git a/wechatauto/guia.py b/wechatauto/guia.py new file mode 100644 index 0000000..7e9fe80 --- /dev/null +++ b/wechatauto/guia.py @@ -0,0 +1,2066 @@ +# -*- coding: utf-8 -*- +"""wechatauto.guia —— 微信 4.x 自绘界面「坐标 + OCR」自动化发送模块 + +背景 +---- +微信 4.1.12+ 的聊天区域改用自绘渲染(``MMUIRenderSubWindow*``,不同版本 +后缀不同,如 ``MMUIRenderSubWindowHW`` / ``MMUIRenderSubWindow``), +对 UIAutomation / MSAA 不再暴露任何无障碍节点,因此原 wechatauto 的 UIA +方案在 4.1.x 上失效。本项目已通过「本地数据库解密」(``wechatauto/db.py``) +解决读消息;本模块针对**发送消息**补充一条「坐标 + OCR」路线: + + * 通过 Win32 定位微信主窗口与其内的 QtQuick 渲染子窗口(多特征兜底: + 标题 / 类名前缀 / 进程名 weixin.exe / 可见 / 大尺寸联合评分,类名从 + 「硬条件」降级为「软条件」,Qt 升级改名也不失效;找不到渲染子窗口 + 时直接回退用主窗口矩形计算坐标); + * 布局动态校准:首次运行时实测侧栏边界 / 搜索框 / 发送按钮锚点,保存到 + ``~/.wechatauto/layout-<机器>.json``,之后自动加载,DPI/布局漂移时 + 输入框探测连续失败会自动重校准; + * 用 Windows OCR(WinRT ``Windows.Media.Ocr``)识别会话列表 / + 输入框 / 发送按钮在屏幕上的位置; + * 用真实鼠标事件 + 剪贴板粘贴(Ctrl+V)输入文字(避免中文输入法拦截); + * 点击「发送」按钮完成发送。 + +坐标系说明 +---------- +微信最大化时渲染子窗口与屏幕重合(本机 3072x1920)。本模块一律以 +**渲染子窗口坐标系**(相对坐标)描述布局,运行时通过渲染窗口的屏幕 +矩形换算成屏幕绝对坐标,从而兼容窗口缩放/未最大化的情况。 + +使用前提: + 1. 微信 4.x 已登录并**解锁桌面**(锁屏状态下无法 GUI 操作); + 2. ``pip install -e .`` 安装依赖(含 ``winsdk``)。 + +示例: + from wechatauto.guia import WeChatGUI + wx = WeChatGUI() + wx.bring_to_front() + wx.open_chat('文件传输助手') + wx.send_msg('你好,这是自动化测试') +""" + +from __future__ import annotations + +import asyncio +import ctypes +import json +import os +import platform +import re +import tempfile +import time +from ctypes import wintypes +from typing import Dict, List, Optional, Tuple + +from PIL import Image + +from wechatauto.logger import wxlog +from wechatauto.param import WxResponse + +# --------------------------------------------------------------------------- +# DPI:模块加载时立即设为 PER_MONITOR_AWARE_V2,保证后续所有 +# GetWindowRect / GetSystemMetrics / ImageGrab 截图 / SetCursorPos 点击 +# 都处于同一坐标系(物理像素)。 +# --------------------------------------------------------------------------- +try: + ctypes.windll.user32.SetProcessDpiAwarenessContext(ctypes.c_void_p(-4)) +except Exception: + try: + ctypes.windll.shcore.SetProcessDpiAwareness(2) + except Exception: + pass + +# --------------------------------------------------------------------------- +# Win32 原生常量与结构 +# --------------------------------------------------------------------------- + +# keyboard / mouse 输入标志 +KEYEVENTF_KEYUP = 0x0002 +KEYEVENTF_UNICODE = 0x0004 +MOUSEEVENTF_LEFTDOWN = 0x0002 +MOUSEEVENTF_LEFTUP = 0x0004 +MOUSEEVENTF_RIGHTDOWN = 0x0008 +MOUSEEVENTF_RIGHTUP = 0x0010 +MOUSEEVENTF_WHEEL = 0x0800 +MOUSEEVENTF_ABSOLUTE = 0x8000 + +# 虚拟键 +VK_CONTROL = 0x11 +VK_SHIFT = 0x10 +VK_RETURN = 0x0D +VK_SPACE = 0x20 +VK_ESCAPE = 0x1B +VK_DELETE = 0x2E +VK_A = 0x41 +VK_C = 0x43 +VK_V = 0x56 + + +class KEYBDINPUT(ctypes.Structure): + _fields_ = [ + ("wVk", wintypes.WORD), + ("wScan", wintypes.WORD), + ("dwFlags", wintypes.DWORD), + ("time", wintypes.DWORD), + ("dwExtraInfo", ctypes.c_size_t), + ] + + +class _INPUT_UNION(ctypes.Union): + _fields_ = [("ki", KEYBDINPUT)] + + +class INPUT(ctypes.Structure): + _fields_ = [("type", wintypes.DWORD), ("u", _INPUT_UNION)] + + +class MOUSEINPUT(ctypes.Structure): + _fields_ = [ + ("dx", wintypes.LONG), + ("dy", wintypes.LONG), + ("mouseData", wintypes.DWORD), + ("dwFlags", wintypes.DWORD), + ("time", wintypes.DWORD), + ("dwExtraInfo", ctypes.c_size_t), + ] + + +class _MOUSE_UNION(ctypes.Union): + _fields_ = [("mi", MOUSEINPUT)] + + +class MOUSE_INPUT(ctypes.Structure): + _fields_ = [("type", wintypes.DWORD), ("u", _MOUSE_UNION)] + + +# 微信 4.x 窗口类名(不同版本/机型存在差异,统一用前缀匹配兼容所有变体) +# 主窗口:Qt51514QWindowIcon;渲染子窗口:MMUIRenderSubWindow / +# MMUIRenderSubWindowHW / 未来其他后缀。按前缀识别可覆盖全部已知/未知变体。 +WX_MAIN_WIN_CLASS_PREFIX = "Qt51514QWindowIcon" +WX_MAIN_WIN_TITLE = "微信" +WX_RENDER_WIN_CLASS_PREFIX = "MMUIRenderSubWindow" + +# 布局比例常量(相对渲染窗口尺寸,跨分辨率自适应) +# 侧栏宽度约占窗口 22%(微信 4.x 侧栏为固定逻辑宽度,最大化时≈0.22); +# 其余布局元素按其与侧栏宽/窗口高的实测比例换算,保证不同 DPI/分辨率 +# 与窗口尺寸下无需改动即可工作。 +SIDEBAR_LEFT = 0 +SIDEBAR_RATIO = 0.22 # 侧栏宽度 / 窗口宽度 +SIDEBAR_TOP = 0.05 # 会话列表顶部起始(相对窗口高) +SEARCH_BOX_RATIO = (0.18, 0.041, 0.86, 0.079) # (x0,y0,x1,y1),x 相对侧栏宽、y 相对窗口高 +SEND_BUTTON_RATIO = (0.78, 0.92, 0.995, 0.99) # 「发送」按钮检索区(相对窗口) + +# 多特征兜底:类名只是「软条件」之一,还需 进程名/可见/大尺寸/标题 等特征 +# 联合判断,避免 Qt 升级改名(Qt51514 → Qt6xxx)后主窗口定位失效。 +PROCESS_NAME = 'weixin.exe' # 微信进程名(小写) +MIN_WINDOW_SIZE = 800 # 主窗口最小边长(像素),小于此视为非主窗 +MAIN_TITLE_KEYWORDS = ('微信', 'Weixin', 'WeChat') + +# 布局校准配置目录:~/.wechatauto/layout-<机器标识>.json +LAYOUT_CONFIG_DIR = os.path.join(os.path.expanduser('~'), '.wechatauto') + + +def _machine_id() -> str: + """机器标识:主机名 + 屏幕分辨率,用于区分不同机器/DPI 的布局配置。""" + try: + node = platform.node() or 'unknown' + except Exception: + node = 'unknown' + cx = ctypes.windll.user32.GetSystemMetrics(0) # SM_CXSCREEN + cy = ctypes.windll.user32.GetSystemMetrics(1) # SM_CYSCREEN + safe = re.sub(r'[^\w\-]', '_', node) + return f'{safe}_{cx}x{cy}' + + +def _layout_path() -> str: + """返回本机布局校准文件路径(不存在则创建目录)。""" + if not os.path.isdir(LAYOUT_CONFIG_DIR): + try: + os.makedirs(LAYOUT_CONFIG_DIR, exist_ok=True) + except Exception: + pass + return os.path.join(LAYOUT_CONFIG_DIR, f'layout-{_machine_id()}.json') + + +def _restore_keep_maximize(user32, hwnd: int): + """取消最小化并显示窗口,同时保留其最大化状态。 + + ``ShowWindow(hwnd, SW_RESTORE)`` 会把最大化窗口恢复为普通大小 + (窗口被缩小)。这里先用 ``GetWindowPlacement`` 记录其最大化状态: + 原为最大化则用 ``SW_SHOWMAXIMIZED`` 恢复,否则才走 ``SW_RESTORE``。 + """ + if not hwnd or not user32.IsWindow(hwnd): + return + + class _POINT(ctypes.Structure): + _fields_ = [("x", wintypes.LONG), ("y", wintypes.LONG)] + + class _WINDOWPLACEMENT(ctypes.Structure): + _fields_ = [ + ("length", wintypes.UINT), + ("flags", wintypes.UINT), + ("showCmd", wintypes.UINT), + ("ptMinPosition", _POINT), + ("ptMaxPosition", _POINT), + ("rcNormalPosition", wintypes.RECT), + ] + + wp = _WINDOWPLACEMENT() + wp.length = ctypes.sizeof(_WINDOWPLACEMENT) + if user32.GetWindowPlacement(hwnd, ctypes.byref(wp)): + if wp.showCmd == 3: # SW_SHOWMAXIMIZED + user32.ShowWindow(hwnd, 3) # 保持/恢复最大化 + return + user32.ShowWindow(hwnd, 9) # SW_RESTORE + + +# --------------------------------------------------------------------------- +# 底层输入封装 +# --------------------------------------------------------------------------- + +class WinInput: + """基于 Win32 的真实鼠标/键盘输入(DPI 感知)。""" + + def __init__(self): + user32 = ctypes.windll.user32 + # 保持 DPI-UNAWARE:整条管线(GetWindowRect / 截图 / SetCursorPos 点击) + # 都使用系统虚拟化后的逻辑坐标,保证截图与点击坐标一致。 + # (若设为 DPI-aware,屏幕仅 1536x960 物理像素,而截图仍按 + # GetWindowRect 返回的逻辑矩形(如 3018x1818)采集,会造成 + # 截图与 SetCursorPos 物理坐标错位。) + self._user32 = user32 + self.screen_w = user32.GetSystemMetrics(0) + self.screen_h = user32.GetSystemMetrics(1) + wxlog.debug(f'WinInput 初始化,屏幕尺寸:{self.screen_w}x{self.screen_h}') + + # -- 鼠标 ---------------------------------------------------------- + def real_click(self, x: int, y: int, right: bool = False): + """SetCursorPos + mouse_event 的「真实」点击,坐标为本机像素。""" + u = self._user32 + u.SetCursorPos(int(x), int(y)) + time.sleep(0.15) + down = MOUSEEVENTF_RIGHTDOWN if right else MOUSEEVENTF_LEFTDOWN + up = MOUSEEVENTF_RIGHTUP if right else MOUSEEVENTF_LEFTUP + u.mouse_event(down, 0, 0, 0, 0) + u.mouse_event(up, 0, 0, 0, 0) + time.sleep(0.3) + + def send_input_click(self, x: int, y: int): + """SendInput 绝对坐标点击(按真实屏幕尺寸缩放)。""" + u = self._user32 + n = int(x * 65535 // self.screen_w) + m = int(y * 65535 // self.screen_h) + for flags in (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN, + MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTUP): + inp = MOUSE_INPUT() + inp.type = 0 + inp.u.mi.dx = n + inp.u.mi.dy = m + inp.u.mi.dwFlags = flags + u.SendInput(1, ctypes.byref(inp), ctypes.sizeof(MOUSE_INPUT)) + time.sleep(0.06) + time.sleep(0.3) + + def wheel(self, delta: int = -300): + """滚轮滚动(delta 为正向上,负向下)。""" + u = self._user32 + u.mouse_event(MOUSEEVENTF_WHEEL, 0, 0, delta, 0) + time.sleep(0.4) + + # -- 键盘 ---------------------------------------------------------- + def key(self, vk: int, ctrl: bool = False, shift: bool = False): + """发送一次虚拟键(可带 Ctrl/Shift)。""" + mods = [(VK_CONTROL, ctrl), (VK_SHIFT, shift)] + for vk_mod, on in mods: + if on: + self._raw_key(vk_mod, down=True) + self._raw_key(vk, down=True) + self._raw_key(vk, down=False) + for vk_mod, on in reversed(mods): + if on: + self._raw_key(vk_mod, down=False) + + def _raw_key(self, vk: int, down: bool): + """发送一次虚拟键事件。 + + 优先使用 ``keybd_event``(老式 API):在部分远程/虚拟化会话中 + ``SendInput`` 键盘事件会被系统丢弃(返回 0),而 ``keybd_event`` + 与 ``mouse_event`` 走同一套老式输入管线,与鼠标点击一致可用。 + """ + flags = KEYEVENTF_KEYUP if not down else 0 + ctypes.windll.user32.keybd_event(vk & 0xFFFF, 0, flags, 0) + time.sleep(0.05) + + def type_unicode(self, text: str): + """以 SendInput Unicode 方式键入文本(绕开键盘布局/大小写问题)。""" + u = self._user32 + for ch in text: + down = INPUT() + down.type = 1 + down.u.ki.wScan = ord(ch) + down.u.ki.dwFlags = KEYEVENTF_UNICODE + up = INPUT() + up.type = 1 + up.u.ki.wScan = ord(ch) + up.u.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP + u.SendInput(1, ctypes.byref(down), ctypes.sizeof(INPUT)) + time.sleep(0.02) + u.SendInput(1, ctypes.byref(up), ctypes.sizeof(INPUT)) + time.sleep(0.04) + + def type_pinyin(self, pinyin: str): + """以虚拟键逐字母输入拼音(供中文输入法组合,如 ``ceshi`` → 测试)。""" + for ch in pinyin.lower(): + if 'a' <= ch <= 'z': + self.key(ord(ch) - 32) + elif ch == ' ': + self.key(VK_SPACE) + time.sleep(0.05) + + +# --------------------------------------------------------------------------- +# OCR 封装(WinRT) +# --------------------------------------------------------------------------- + +class ScreenOCR: + """Windows 自带 OCR(WinRT Windows.Media.Ocr)封装。 + + 用法:``ScreenOCR.recognize(pil_image)`` 返回 + ``[(text, x, y, w, h), ...]``,坐标为图像内相对坐标。 + """ + + @staticmethod + def recognize(image: Image.Image) -> List[Tuple[str, int, int, int, int]]: + from winsdk.windows.media.ocr import OcrEngine + from winsdk.windows.graphics.imaging import BitmapDecoder + from winsdk.windows.storage import StorageFile + + async def _run() -> List[Tuple[str, int, int, int, int]]: + tmp = os.path.join(tempfile.gettempdir(), 'wechatauto_ocr_tmp.png') + image.save(tmp) + f = await StorageFile.get_file_from_path_async(tmp) + s = await f.open_async(0) + dec = await BitmapDecoder.create_async(s) + bmp = await dec.get_software_bitmap_async() + eng = OcrEngine.try_create_from_user_profile_languages() + if eng is None: + return [] + res = await eng.recognize_async(bmp) + out = [] + for line in res.lines: + text = line.text.replace(' ', '') + if not text: + continue + r = line.words[0].bounding_rect + out.append((text, int(r.x), int(r.y), int(r.width), int(r.height))) + return out + + try: + return asyncio.run(asyncio.wait_for(_run(), timeout=8)) + except asyncio.TimeoutError: + wxlog.debug('OCR 识别超时(8s)') + return [] + except Exception as e: + wxlog.debug(f'OCR 识别失败:{e}') + return [] + + +# --------------------------------------------------------------------------- +# 微信主流程 +# --------------------------------------------------------------------------- + +class WeChatGUI: + """基于坐标 + OCR 的微信 4.x 自动化实例。 + + Attributes: + main_hwnd: 微信主窗口句柄 + render_hwnd: QtQuick 渲染子窗口句柄 + render_rect: 渲染窗口屏幕矩形 (left, top, right, bottom) + """ + + def __init__(self, title: str = WX_MAIN_WIN_TITLE, hwnd: int = None, + calibrate: bool = False): + self._input = WinInput() + self._sidebar_ratio = SIDEBAR_RATIO + self._send_button_ratio = SEND_BUTTON_RATIO + self.main_hwnd = hwnd or self._find_main_window(title) + if not self.main_hwnd: + raise RuntimeError('未找到微信主窗口,请确认微信已登录并运行') + self.render_hwnd = self._find_render_window(self.main_hwnd) + if not self.render_hwnd: + # 找不到渲染子窗口(Qt 改版等)→ 直接用主窗口矩形计算坐标 + wxlog.warning('未找到微信渲染子窗口,回退用主窗口矩形定位坐标') + self.render_hwnd = self.main_hwnd + self._update_render_rect() + self.pid = self._get_pid(self.main_hwnd) + self._current_chat = None # 最近打开的会话名,用于连续发送时复用 + self._last_input_box = None # 最近一次成功发送的输入框位置,连续发送复用 + self._uia = None # UIA 引擎(惰性创建,仅当可用时启用) + self._uia_tried = False + # 布局校准:显式 calibrate=True 强制重校准;否则加载本机已校准配置, + # 没有配置则自动校准一次(OCR 可用时),实现「跑一次永久兼容」。 + if not calibrate: + calibrate = not self._load_layout() + if calibrate: + self.calibrate_layout() + wxlog.info( + f'WeChatGUI 初始化成功:hwnd={self.main_hwnd}, ' + f'render={self.render_hwnd}, rect={self.render_rect}') + + # ------------------------------------------------------------------ + # 窗口定位 + # ------------------------------------------------------------------ + def _process_name(self, pid: int) -> str: + """返回 pid 对应进程的可执行文件名(小写),失败返回空串。""" + if not pid: + return '' + PROCESS_QUERY_LIMITED_INFORMATION = 0x1000 + h = ctypes.windll.kernel32.OpenProcess( + PROCESS_QUERY_LIMITED_INFORMATION, False, pid) + if not h: + return '' + try: + buf = ctypes.create_unicode_buffer(1024) + size = wintypes.DWORD(1024) + ok = ctypes.windll.kernel32.QueryFullProcessImageNameW( + h, 0, buf, ctypes.byref(size)) + if ok: + return os.path.basename(buf.value).lower() + except Exception: + return '' + finally: + ctypes.windll.kernel32.CloseHandle(h) + return '' + + def _looks_like_main_window(self, hwnd: int) -> bool: + """多特征联合判断是否为微信主窗口(类名只是软条件之一)。 + + 特征:标题含微信关键字 / 类名前缀 Qt51514QWindowIcon* / + 进程名为 weixin.exe / 可见 / 尺寸 >= MIN_WINDOW_SIZE。任一项都不 + 单独成立,评分(权重和)>=5 才认可,防止 Qt 升级改名后失效。 + """ + u = self._input._user32 + if not u.IsWindow(hwnd) or not u.IsWindowVisible(hwnd): + return False + buf = ctypes.create_unicode_buffer(256) + cls = ctypes.create_unicode_buffer(256) + u.GetWindowTextW(hwnd, buf, 256) + u.GetClassNameW(hwnd, cls, 256) + title, cls_name = buf.value.strip(), cls.value + score = 0 + if any(k in title for k in MAIN_TITLE_KEYWORDS): + score += 5 + if cls_name.startswith(WX_MAIN_WIN_CLASS_PREFIX): + score += 4 + if self._process_name(self._get_pid(hwnd)) == PROCESS_NAME: + score += 3 + rr = wintypes.RECT() + u.GetWindowRect(hwnd, ctypes.byref(rr)) + if (rr.right - rr.left) >= MIN_WINDOW_SIZE \ + or (rr.bottom - rr.top) >= MIN_WINDOW_SIZE: + score += 2 + return score >= 5 + + def _find_main_window(self, title: str) -> int: + """多特征兜底定位微信主窗口。 + + 类名前缀不再是硬条件(Qt 升级 Qt51514→Qt6xxx 后会改名),改为在 + 所有可见顶层窗口中按「标题/类名/进程名/可见/尺寸」评分,取最高分。 + 找不到时退回按标题精确查找。 + """ + u = self._input._user32 + scored = [] + cb_ref = [] + + def _cb(h, lp): + if not u.IsWindowVisible(h): + return True + buf = ctypes.create_unicode_buffer(256) + cls = ctypes.create_unicode_buffer(256) + u.GetWindowTextW(h, buf, 256) + u.GetClassNameW(h, cls, 256) + title_text, cls_name = buf.value.strip(), cls.value + if not (title_text or cls_name): + return True + score = 0 + if any(k in title_text for k in MAIN_TITLE_KEYWORDS): + score += 5 + if cls_name.startswith(WX_MAIN_WIN_CLASS_PREFIX): + score += 4 + if self._process_name(self._get_pid(h)) == PROCESS_NAME: + score += 3 + rr = wintypes.RECT() + u.GetWindowRect(h, ctypes.byref(rr)) + w = rr.right - rr.left + ht = rr.bottom - rr.top + if w > 0 and ht > 0: + if w >= MIN_WINDOW_SIZE or ht >= MIN_WINDOW_SIZE: + score += 2 + if score >= 5: + scored.append((score, w * ht, h)) + return True + + CB = ctypes.WINFUNCTYPE(ctypes.c_bool, wintypes.HWND, wintypes.LPARAM) + cb_ref.append(CB(_cb)) + u.EnumWindows(cb_ref[0], 0) + if scored: + scored.sort(key=lambda t: (t[0], t[1]), reverse=True) + return scored[0][2] + # 完全找不到时退回按标题精确查找 + hwnd = u.FindWindowW(None, title) + if hwnd and self._looks_like_main_window(hwnd): + return hwnd + return 0 + + def _find_render_window(self, main_hwnd: int) -> int: + u = self._input._user32 + found = [] + cb_ref = [] + + def _cb(h, lp): + cls = ctypes.create_unicode_buffer(256) + u.GetClassNameW(h, cls, 256) + if not cls.value.startswith(WX_RENDER_WIN_CLASS_PREFIX): + return True + rr = wintypes.RECT() + u.GetWindowRect(h, ctypes.byref(rr)) + w = rr.right - rr.left + ht = rr.bottom - rr.top + if w > 0 and ht > 0: + found.append((w * ht, h)) + return True + + CB = ctypes.WINFUNCTYPE(ctypes.c_bool, wintypes.HWND, wintypes.LPARAM) + cb_ref.append(CB(_cb)) + u.EnumChildWindows(main_hwnd, cb_ref[0], 0) + if not found: + return 0 + found.sort(key=lambda t: t[0], reverse=True) + return found[0][1] + + def _get_pid(self, hwnd: int) -> int: + pid = wintypes.DWORD() + ctypes.windll.user32.GetWindowThreadProcessId(hwnd, ctypes.byref(pid)) + return pid.value + + def _update_render_rect(self): + rr = wintypes.RECT() + ctypes.windll.user32.GetWindowRect(self.render_hwnd, ctypes.byref(rr)) + self.render_rect = (rr.left, rr.top, rr.right, rr.bottom) + self.origin_x, self.origin_y = rr.left, rr.top + self.render_w = rr.right - rr.left + self.render_h = rr.bottom - rr.top + self._update_layout() + + def _update_layout(self): + """根据当前渲染窗口尺寸换算各布局区域(渲染相对坐标)。 + + 所有硬编码像素坐标替换为按比例计算,保证跨 DPI/分辨率/窗口 + 尺寸一致:``sidebar_right``(右面板左边界)、``search_box`` + (左侧搜索框)、``send_button_region``(发送按钮检索区)。 + + 比例优先取布局校准结果(``_sidebar_ratio`` / ``_send_button_ratio``), + 未校准时回落到模块默认常量。 + """ + sb_ratio = getattr(self, '_sidebar_ratio', SIDEBAR_RATIO) + send_ratio = getattr(self, '_send_button_ratio', SEND_BUTTON_RATIO) + self.sidebar_right = max(120, int(self.render_w * sb_ratio)) + self.right_pane_left = self.sidebar_right + sx0, sy0, sx1, sy1 = SEARCH_BOX_RATIO + self.search_box = ( + int(self.sidebar_right * sx0), int(self.render_h * sy0), + int(self.sidebar_right * sx1), int(self.render_h * sy1)) + bx0, by0, bx1, by1 = send_ratio + self.send_button_region = ( + int(self.render_w * bx0), int(self.render_h * by0), + int(self.render_w * bx1), int(self.render_h * by1)) + + # ------------------------------------------------------------------ + # 布局动态校准(防 DPI/布局漂移) + # ------------------------------------------------------------------ + def _detect_sidebar_ratio(self) -> Optional[float]: + """OCR 锚点法实测侧栏宽度比例,失败返回 None。 + + 微信 4.x 侧栏背景与消息区同为白色,像素边界几乎不可见,唯一稳定 + 的结构锚点是搜索框内的「搜索」占位文本(文本中心 ≈ 侧栏宽的 0.28, + 实测于本机 3072x1920)。结果钳制在 [0.14, 0.30],超出正常范围视为 + 误检(如 OCR 读到别处的「搜索」),返回 None 由调用方回退默认比例。 + """ + try: + for _ in range(2): + lines = self.ocr((0, 0, self.render_w, self.render_h)) + for text, x, y, w, h in lines: + t = (text or '').strip() + if '搜索' in t and x < self.render_w * 0.35 \ + and y < self.render_h * 0.3: + cx = x + w // 2 + ratio = (cx / 0.28) / self.render_w + if 0.14 <= ratio <= 0.30: + return ratio + time.sleep(0.8) + return None + except Exception: + return None + + def calibrate_layout(self, save: bool = True) -> bool: + """检测布局锚点并实测布局比例,写入 ``~/.wechatauto/layout-<机器>.json``。 + + 锚点(实测驱动,所有结果都钳制在合理范围,防误检破坏可用布局): + * 侧栏宽度:OCR 找「搜索」占位文本,反推侧栏右边界; + * 发送按钮:OCR 在右下角找「发送」文本,反推检索区比例 + (发送按钮仅输入框有内容时可见,找不到就保持默认)。 + 校准采用「保守优先」策略:任一项检测失败即用模块默认比例,宁可 + 不做调整也不产生错误的坐标。返回是否成功。 + """ + def _run_with_timeout(fn, timeout=5): + result = [None] + def _target(): + try: + result[0] = fn() + except Exception: + pass + t = threading.Thread(target=_target, daemon=True) + t.start() + t.join(timeout) + return result[0] + + try: + self._update_render_rect() + self.bring_to_front() + time.sleep(0.8) + self._update_render_rect() + layout: Dict[str, object] = {'machine': _machine_id()} + # 1) 侧栏宽度:OCR「搜索」锚点(限制 5s 超时) + sb = _run_with_timeout(self._detect_sidebar_ratio, timeout=5) + layout['sidebar_ratio'] = float(sb) if sb else SIDEBAR_RATIO + # 2) 发送按钮:OCR「发送」(仅右下角检索区,限制 5s 超时) + try: + lines = _run_with_timeout( + lambda: self.ocr((int(self.render_w * 0.5), + int(self.render_h * 0.7), + self.render_w, self.render_h)), + timeout=5) + lines = lines or [] + except Exception: + lines = [] + send = None + for text, x, y, w, h in lines: + if (text or '').strip() == '发送': + send = (x, y, w, h) + break + if send: + sx, sy, sw, sh = send + # 检索区需略大于按钮本体,OCR 才能稳定命中;四周留边距 + pad_x, pad_y = 40, 20 + x0 = max(0, sx - pad_x) + y0 = max(0, sy - pad_y) + x1 = min(self.render_w, sx + sw + pad_x) + y1 = min(self.render_h, sy + sh + pad_y) + layout['send_button_ratio'] = [ + x0 / self.render_w, y0 / self.render_h, + x1 / self.render_w, y1 / self.render_h] + else: + layout['send_button_ratio'] = list(SEND_BUTTON_RATIO) + layout['render_w'] = self.render_w + layout['render_h'] = self.render_h + layout['date'] = time.strftime('%Y-%m-%d %H:%M:%S') + if save: + try: + with open(_layout_path(), 'w', encoding='utf-8') as f: + json.dump(layout, f, ensure_ascii=False, indent=2) + except Exception as e: + wxlog.debug(f'保存布局校准文件失败:{e}') + self._apply_layout(layout) + wxlog.info( + f'布局校准完成:sidebar_ratio={layout["sidebar_ratio"]:.3f}, ' + f'send_button_ratio={layout["send_button_ratio"]}') + return True + except Exception as e: + wxlog.debug(f'布局校准失败:{e}') + return False + + def _apply_layout(self, d: dict) -> None: + """应用布局校准结果并重算各布局区域。""" + self._sidebar_ratio = float(d.get('sidebar_ratio', SIDEBAR_RATIO)) + sb = d.get('send_button_ratio') + if isinstance(sb, (list, tuple)) and len(sb) == 4: + try: + self._send_button_ratio = tuple(float(v) for v in sb) + except Exception: + self._send_button_ratio = SEND_BUTTON_RATIO + self._update_layout() + + def _load_layout(self) -> bool: + """运行前自动加载本机已校准的布局配置,返回是否成功采用。 + + 窗口尺寸与校准当时差异过大(>15%,如窗口缩放/未最大化)时视为 + 布局不匹配,拒绝采用并触发重新校准。 + """ + p = _layout_path() + if not os.path.isfile(p): + return False + try: + with open(p, encoding='utf-8') as f: + d = json.load(f) + except Exception: + return False + if abs(float(d.get('render_w', 0) or 0) - self.render_w) \ + / max(self.render_w, 1) > 0.15: + wxlog.info( + f'布局配置与当前窗口尺寸差异过大,忽略并重新校准' + f'(校准={d.get("render_w")} vs 当前={self.render_w})') + return False + self._apply_layout(d) + wxlog.info(f'已加载布局校准:sidebar_ratio={self._sidebar_ratio:.3f}') + return True + + def use_window(self, top_hwnd: int) -> bool: + """把 GUI 操作目标切换到指定顶层微信窗口(主窗或独立聊天窗)。 + + 微信 4.x 通过搜索打开会话时会生成独立聊天窗口(标题如 + “昵称与X的聊天记录”)。切换后 render_rect/origin 等随新窗口更新, + click/paste/OCR 等原语无需改动即可在新窗口内工作。找不到渲染 + 子窗口时直接用该顶层窗口矩形计算坐标。 + """ + if not top_hwnd or not self._input._user32.IsWindow(top_hwnd): + return False + render = self._find_render_window(top_hwnd) + if not render: + render = top_hwnd # 渲染窗口缺失时回退用窗口矩形 + self.main_hwnd = top_hwnd + self.render_hwnd = render + self._update_render_rect() + return True + + def _find_chat_window(self, name: str) -> int: + """在当前微信进程的所有可见窗口中,找标题含 name 前2字与“聊天记录”的独立聊天窗。""" + u = self._input._user32 + wx_pid = self._get_pid(self.main_hwnd) + frag = name[:2] + found = 0 + cb_ref = [] + + def _cb(h, lp): + nonlocal found + pid = wintypes.DWORD() + u.GetWindowThreadProcessId(h, ctypes.byref(pid)) + if pid.value != wx_pid or not u.IsWindowVisible(h): + return True + buf = ctypes.create_unicode_buffer(256) + u.GetWindowTextW(h, buf, 256) + title = buf.value + if title and '聊天记录' in title and frag in title: + found = h + return False + return True + + CB = ctypes.WINFUNCTYPE(ctypes.c_bool, wintypes.HWND, wintypes.LPARAM) + cb_ref.append(CB(_cb)) + u.EnumWindows(cb_ref[0], 0) + return found + + def is_alive(self) -> bool: + return bool(self._input._user32.IsWindow(self.main_hwnd)) + + # ------------------------------------------------------------------ + # 前台与可用性 + # ------------------------------------------------------------------ + def bring_to_front(self, keep_topmost: bool = False) -> bool: + """将微信窗口置为前台,返回是否成功。 + + 依次尝试:恢复窗口 → 置顶(HWND_TOPMOST) → SetForegroundWindow, + 并配合 AttachThreadInput 解除焦点抢占限制。 + + 参数 ``keep_topmost``:为 True 时保持置顶(适合在被其他窗口遮挡 + 的环境下连续操作,操作完成后可调用 ``restore_zorder()`` 取消置顶); + 为 False 时操作结束后立即取消置顶。 + """ + u = self._input._user32 + SWP_NOMOVE, SWP_NOSIZE, SWP_SHOWWINDOW = 0x2, 0x1, 0x40 + + # 清除前台锁(SPI_SETFOREGROUNDLOCKTIMEOUT = 0x2001,值=0 表示无延迟) + SPI_SETFOREGROUNDLOCKTIMEOUT = 0x2001 + ctypes.windll.user32.SystemParametersInfoW( + SPI_SETFOREGROUNDLOCKTIMEOUT, 0, None, 0) + + for attempt in range(5): + fg = u.GetForegroundWindow() + if fg == self.main_hwnd: + break + tid_fg = u.GetWindowThreadProcessId(fg, None) if fg else 0 + tid_t = u.GetWindowThreadProcessId(self.main_hwnd, None) + if tid_fg: + u.AttachThreadInput(tid_fg, tid_t, True) + _restore_keep_maximize(u, self.main_hwnd) + u.SetWindowPos(self.main_hwnd, -1, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW) # HWND_TOPMOST + u.SetForegroundWindow(self.main_hwnd) + u.SetActiveWindow(self.main_hwnd) + u.BringWindowToTop(self.main_hwnd) + if self.render_hwnd and u.GetFocus() != self.render_hwnd: + u.SetFocus(self.render_hwnd) + if tid_fg: + u.AttachThreadInput(tid_fg, tid_t, False) + time.sleep(0.6) + if u.GetForegroundWindow() == self.main_hwnd: + break + if not keep_topmost: + u.SetWindowPos(self.main_hwnd, -2, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE) # HWND_NOTOPMOST + fg = u.GetForegroundWindow() + return fg == self.main_hwnd or fg is None + + def restore_zorder(self): + """取消置顶,恢复普通 Z 序(配合 ``bring_to_front(keep_topmost=True)`` 使用)。""" + self._input._user32.SetWindowPos(self.main_hwnd, -2, 0, 0, 0, 0, 0x2 | 0x1) + + def _minimize_blockers(self) -> int: + """最小化所有与微信主窗口重叠的非微信顶层窗口,返回处理个数。 + + 微信被 Chrome/OpenCode 等窗口覆盖时,鼠标点击的命中测试按 Z 序 + 会落到覆盖层上,必须先把遮挡窗口最小化才能操作微信。 + 只处理「可见 + 与微信重叠 + 非微信进程 + 非系统装饰窗口」的窗口。 + """ + u = self._input._user32 + wx_pid = self._get_pid(self.main_hwnd) + rect = wintypes.RECT() + u.GetWindowRect(self.main_hwnd, ctypes.byref(rect)) + wx = (rect.left, rect.top, rect.right, rect.bottom) + skip_classes = ("Progman", "WorkerW", "Shell_TrayWnd", "kugou_ui", + "MSCTFIME UI", "IME") + targets = [] + + def _cb(h, lp): + if not u.IsWindowVisible(h) or u.IsIconic(h): + return True + cls_buf = ctypes.create_unicode_buffer(256) + u.GetClassNameW(h, cls_buf, 256) + cls = cls_buf.value + if cls in skip_classes or cls.startswith("Windows.UI.Core"): + return True + if self._get_pid(h) == wx_pid: + return True # 微信自身窗口不动 + r2 = wintypes.RECT() + u.GetWindowRect(h, ctypes.byref(r2)) + if not (r2.right > wx[0] and r2.left < wx[2] + and r2.bottom > wx[1] and r2.top < wx[3]): + return True # 与微信不重叠 + title_buf = ctypes.create_unicode_buffer(256) + u.GetWindowTextW(h, title_buf, 256) + if cls == "Chrome_WidgetWin_1" or title_buf.value.strip(): + targets.append(h) + return True + + cb_ref = [] + CB = ctypes.WINFUNCTYPE(ctypes.c_bool, wintypes.HWND, wintypes.LPARAM) + cb_ref.append(CB(_cb)) + u.EnumWindows(cb_ref[0], 0) + for h in targets: + u.ShowWindow(h, 6) # SW_MINIMIZE + if targets: + wxlog.info(f'自动最小化遮挡窗口 {len(targets)} 个') + return len(targets) + + def ensure_visible(self) -> bool: + """自动最小化遮挡窗口并把微信置于前台,返回桌面是否可用。 + + 发送类操作前调用,替代「手动最小化 Chrome 再置顶微信」的步骤。 + 遮挡窗口最小化后微信仍保持置顶,便于连续多次发送。 + + 批量发送(三件套等)会逐条调用本方法,为避免每条都重复 + 枚举窗口 / 置顶(上轮实测每次开销 20s+),15 秒内已成功 + 前置过且窗口仍存活则直接复用,不再重复扫描。 + """ + if (getattr(self, '_last_visible_ok', False) + and getattr(self, '_last_visible_ts', 0) > time.time() - 15 + and self.is_alive()): + return True + self._minimize_blockers() + time.sleep(0.8) + self.bring_to_front(keep_topmost=True) + time.sleep(0.5) + self._update_render_rect() + ok = self.desktop_available() + self._last_visible_ok = ok + self._last_visible_ts = time.time() + return ok + + def wx_click(self, x: int, y: int, right: bool = False): + """点击微信渲染窗口内的坐标。 + + 微信渲染子窗口(MMUIRenderSubWindow*)设置了 + ``WS_EX_LAYERED | WS_EX_TRANSPARENT``,导致 mouse_event + 的点击会穿透到主窗口而无法到达渲染层。此方法在点击前后 + 临时去掉 ``WS_EX_TRANSPARENT``,使点击能被渲染窗口接收, + 随即恢复原样式以保证画面正常合成。 + """ + u = self._input._user32 + GWL_EXSTYLE = -20 + WS_EX_TRANSPARENT = 0x00000020 + old_ex = u.GetWindowLongW(self.render_hwnd, GWL_EXSTYLE) + if old_ex & WS_EX_TRANSPARENT: + u.SetWindowLongW(self.render_hwnd, GWL_EXSTYLE, + old_ex & ~WS_EX_TRANSPARENT) + time.sleep(0.05) + try: + self._input.real_click(x, y, right=right) + finally: + if old_ex & WS_EX_TRANSPARENT: + u.SetWindowLongW(self.render_hwnd, GWL_EXSTYLE, old_ex) + time.sleep(0.05) + + def wx_wheel(self, delta: int): + """滚轮滚动渲染窗口内的内容。 + + 与 wx_click 同理:渲染子窗口带 WS_EX_TRANSPARENT,mouse_event 的 + 滚轮事件会穿透到下层窗口,必须临时去掉该样式再滚动。 + """ + u = self._input._user32 + GWL_EXSTYLE = -20 + WS_EX_TRANSPARENT = 0x00000020 + old_ex = u.GetWindowLongW(self.render_hwnd, GWL_EXSTYLE) + if old_ex & WS_EX_TRANSPARENT: + u.SetWindowLongW(self.render_hwnd, GWL_EXSTYLE, + old_ex & ~WS_EX_TRANSPARENT) + time.sleep(0.05) + try: + self._input.wheel(delta) + finally: + if old_ex & WS_EX_TRANSPARENT: + u.SetWindowLongW(self.render_hwnd, GWL_EXSTYLE, old_ex) + time.sleep(0.05) + + def desktop_available(self) -> bool: + """检查微信窗口是否真的可见(锁屏/会话断开时返回 False)。""" + if not self.is_alive(): + return False + try: + img = self._grab_screen(self.render_rect) + except Exception: + return False + px = img.load() + w, h = img.size + white = total = 0 + for y in range(0, h, 16): + for x in range(0, w, 16): + r, g, b = px[x, y] + total += 1 + if r > 230 and g > 230 and b > 230: + white += 1 + return white / max(total, 1) > 0.05 + + # ------------------------------------------------------------------ + # 截图与 OCR + # ------------------------------------------------------------------ + def _grab_screen(self, box: Optional[Tuple[int, int, int, int]] = None) -> Image.Image: + """截取屏幕区域(带重试)。box 为屏幕绝对坐标。""" + from PIL import ImageGrab + last = None + for _ in range(6): + try: + return ImageGrab.grab(bbox=box) if box else ImageGrab.grab() + except Exception as e: + last = e + time.sleep(0.5) + raise RuntimeError(f'屏幕截图失败:{last}') + + def _rel_to_screen(self, rel: Tuple[int, int, int, int]) -> Tuple[int, int, int, int]: + x0, y0, x1, y1 = rel + return (self.origin_x + x0, self.origin_y + y0, + self.origin_x + x1, self.origin_y + y1) + + def ocr(self, rel_box: Tuple[int, int, int, int]) -> List[Tuple[str, int, int, int, int]]: + """对渲染窗口相对区域做 OCR,返回 (text, rel_x, rel_y, w, h)。""" + screen_box = self._rel_to_screen(rel_box) + img = self._grab_screen(screen_box) + res = ScreenOCR.recognize(img) + out = [] + for text, x, y, w, h in res: + out.append((text, rel_box[0] + x, rel_box[1] + y, w, h)) + return out + + def ocr_zoomed(self, rel_box: Tuple[int, int, int, int], + scale: int = 3) -> List[Tuple[str, int, int, int, int]]: + """对渲染窗口相对区域放大 scale 倍后 OCR,返回渲染相对坐标。 + + 微信 4.x 的小字号标题(尤其含生僻字如「卢立竺」)原尺寸 OCR 常 + 漏识别或读出乱码,放大后识别率显著提升。坐标按 1/scale 还原。 + """ + screen_box = self._rel_to_screen(rel_box) + img = self._grab_screen(screen_box) + w, h = img.size + img = img.resize((w * scale, h * scale), Image.LANCZOS) + res = ScreenOCR.recognize(img) + out = [] + for text, x, y, w, h in res: + out.append((text, rel_box[0] + x // scale, + rel_box[1] + y // scale, w // scale, h // scale)) + return out + + # ------------------------------------------------------------------ + # 会话列表 + # ------------------------------------------------------------------ + def get_sessions(self, zoomed: bool = False) -> List[Dict[str, object]]: + """OCR 识别左侧会话列表,返回 [{name, x, y, w, h}](渲染相对坐标)。 + + 会话名文本约占侧栏宽的 30%~100%;左侧 <30% 为头像/未读角标, + 右侧为时间戳。均按比例过滤,跨分辨率一致。 + + zoomed=True 时对整块侧栏放大 3 倍后 OCR,用于原尺寸扫不到 + (生僻字/小字号)时兜底;速度较慢,仅按需启用。 + """ + rel = (SIDEBAR_LEFT, int(self.render_h * SIDEBAR_TOP), + self.sidebar_right, self.render_h) + lines = self.ocr_zoomed(rel, scale=3) if zoomed else self.ocr(rel) + rows = [] + for text, x, y, w, h in lines: + t = (text or '').strip() + if not t: + continue + if x < self.sidebar_right * 0.30: # 头像/图标/角标区 + continue + if any(k in t for k in ('搜索', '聊天', '通讯录')): + continue + rows.append({'name': t, 'x': x, 'y': y, 'w': w, 'h': h}) + return rows + + @staticmethod + def _name_matches(ocr_name: str, target: str) -> bool: + """OCR 会话名的韧性匹配,容忍首尾字符截断/粘连。 + + 微信 4.x 标题 OCR 常把首字截掉('文件传输助手'→'件传输助'), + 因此不能只用精确相等或 startswith。匹配优先级: + 1. 完整相等 + 2. 识别名是目标名的一段(截首/截尾/截中) + 3. 识别名更长时目标名是其子串(识别名带多余字符) + """ + a = (ocr_name or '').strip() + b = (target or '').strip() + if not a or not b: + return False + if a == b: + return True + # 截断容忍:OCR 名是目标名的一段(识别名比目标短,属截首/截尾/截中) + if a in b: + return True + # 识别名更长(含多余字符):仅当识别名 >= 3 字时接受子串命中, + # 避免目标名(如 2 字)是较长识别名前缀导致的误点 + if b in a and len(a) >= 3: + return True + return False + + def find_session(self, name: str, max_scroll: int = 3) -> Optional[Tuple[int, int]]: + """在会话列表中查找指定会话,返回可点击的 (相对x, 相对y)。 + + 点击点取 OCR 文本框中心(而非硬编码列坐标),自动适配任何 + 窗口宽度/DPI。渲染可能在窗口置前台后短暂未刷新,先重复纯 OCR + 再滚动;找不到时悬停列表滚动重试。 + + 滚动方向自适应:先向上翻找列表上半段的高亮会话(已打开的会话 + 会被置顶),找不到再向下滚动其它区域。 + """ + u = self._input._user32 + + def _scan(zoomed: bool = False) -> Optional[Tuple[int, int]]: + # 按 y 排序,OCR 返回顺序不可靠,保证点击视觉上正确的行 + for row in sorted(self.get_sessions(zoomed=zoomed), key=lambda r: r['y']): + if self._name_matches(row['name'], name): + return (row['x'] + row['w'] // 2, row['y'] + row['h'] // 2) + return None + + def _scan_vote(zoomed: bool = False, rounds: int = 4, + min_votes: int = 2, + tol: int = 30) -> Optional[Tuple[int, int]]: + """多轮 OCR 投票找会话行,抗单轮识别抖动。 + + WinRT OCR 对生僻字/小字号(如「卢立竺」)存在抖动:同一行 + 不同轮次可能读出「卢立竺」或「亠人五」。逐轮扫描并把命中行 + 按 y 聚类,票数达到 min_votes 才返回,显著降低误配率。 + """ + hits = [] # (y, x, w, h) + for _ in range(rounds): + # 每轮只取 y 最靠前的一个命中,避免同轮多个误配行干扰 + for row in sorted(self.get_sessions(zoomed=zoomed), + key=lambda r: r['y']): + if self._name_matches(row['name'], name): + hits.append((row['y'], row['x'], row['w'], row['h'])) + break + time.sleep(0.15) + if not hits: + return None + hits.sort() + clusters = [] # [y均值, x均值, w均值, h均值, 票数] + for y, x, w, h in hits: + for c in clusters: + if abs(c[0] - y) <= tol: + c[4] += 1 + n = c[4] + c[0] = (c[0] * (n - 1) + y) / n + c[1] = (c[1] * (n - 1) + x) / n + c[2] = max(c[2], w) + c[3] = max(c[3], h) + break + else: + clusters.append([float(y), float(x), w, h, 1]) + best = max(clusters, key=lambda c: c[4]) + if best[4] < min_votes: + return None + return (int(best[1] + best[2] // 2), int(best[0] + best[3] // 2)) + + for _ in range(2): # 先不带滚动重试 OCR,等渲染刷新 + hit = _scan() + if hit: + return hit + time.sleep(0.4) + # 原尺寸扫不到 → 放大 3 倍多轮投票(生僻字/小字号会话,如「卢立竺」) + hit = _scan_vote(zoomed=True) + if hit: + return hit + for _ in range(max_scroll): + hit = _scan() + if hit: + return hit + # 未找到 → 悬停会话列表,先向上翻再向下翻各试探 + u.SetCursorPos(self.origin_x + self.sidebar_right // 2, + self.origin_y + int(self.render_h * 0.5)) + time.sleep(0.2) + self.wx_wheel(-360) + time.sleep(0.6) + hit = _scan() + if hit: + return hit + hit = _scan_vote(zoomed=True) + if hit: + return hit + self.wx_wheel(360) + time.sleep(0.6) + return None + + def _row_is_active(self, rel_y: int) -> bool: + """判断侧栏指定行是否为当前高亮(已打开)的会话。 + + 微信 4.x 活动会话行背景为绿色 (≈21,172,112),普通行为浅灰 + (238,238,240)。取会话名右侧空白横向条带统计绿色像素即可判断。 + """ + try: + y0 = max(0, rel_y - 6) + x1 = max(self.right_pane_left - 40, 360) + rel = (360, y0, x1, rel_y + 6) + img = self._grab_screen(self._rel_to_screen(rel)) + px = img.load() + w, h = img.size + green = 0 + for yy in range(0, h, 2): + for xx in range(0, w, 2): + r, g, b = px[xx, yy][:3] + if g > r + 25 and g > b + 25 and g > 100: + green += 1 + return green > 20 + except Exception: + return False + + def _get_uia(self): + """惰性创建并复用 UIA 引擎;不可用时返回 None(由调用方降级 OCR)。 + + 混合驱动:UIA 树需热激活(写 Weixin.dll 的 Qt accessibility byte)。 + 首次尝试失败则本次会话内不再重试(避免每条消息都等超时)。 + """ + if self._uia_tried: + return self._uia + self._uia_tried = True + try: + from wechatauto.uia_driver import WeChatUIA + eng = WeChatUIA() + if eng.ensure_window(): + self._uia = eng + wxlog.info('已启用 UIA 驱动(混合路径:UIA 优先,OCR 兜底)') + else: + wxlog.info('UIA 树不可用,本次会话使用 OCR 驱动') + except Exception as e: + wxlog.debug('初始化 UIA 引擎失败:%s', e) + return self._uia + + def open_chat(self, name: str, exact: bool = False) -> bool: + """打开指定会话的聊天窗口(优先 UIA,其次 OCR 侧栏/搜索)。 + + 微信 4.x 行为:点侧栏会话在主窗右侧面板打开;搜索下拉点联系人则 + 打开独立聊天窗口(标题“昵称与X的聊天记录”)。本方法两条路都处理, + 打开后把 GUI 操作目标切到对应窗口,并验证会话真正打开。 + """ + uia = self._get_uia() + if uia is not None and uia.open_chat(name): + self._current_chat = name + return True + if not self.ensure_visible(): + wxlog.warning('无法将微信窗口置于前台,尝试继续操作') + # 优先:右侧面板当前已打开目标会话 → 直接成功 + # (微信 4.x 已打开的会话才渲染右侧,侧栏查找反而慢且易误配) + self._update_render_rect() + if self._chat_is_open(name) and self._pane_has_content(): + return True + # 优先侧栏:多轮「查找 + 点击 + 确认」(侧栏点击最可靠) + for _ in range(3): + pos = self.find_session(name) + if pos: + self.use_window(self.main_hwnd) + rx, ry = pos + # 行已是当前高亮(会话已打开):再点一次会关闭它,直接确认 + if self._row_is_active(ry): + if self._pane_has_content(): + return True + # 高亮但面板空白:不点击(点击会关闭会话),交给搜索兜底 + wxlog.debug(f'会话 {name} 行已高亮但面板空白,跳过点击') + else: + self.wx_click(self.origin_x + rx, self.origin_y + ry) + if self._chat_open_confirmed(name): + return True + wxlog.debug(f'侧栏未确认打开 {name},重试') + time.sleep(0.5) + # 侧栏找不到 → 搜索框回退(搜索下拉易误开独立历史窗,仅作最后手段) + if self._search_chat(name): + sub = self._find_chat_window(name) + if sub: + _restore_keep_maximize(self._input._user32, sub) + self._input._user32.SetForegroundWindow(sub) + time.sleep(0.5) + self.use_window(sub) + time.sleep(0.3) + return True + if self._chat_open_confirmed(name): + return True + return False + + def _chat_open_confirmed(self, name: str) -> bool: + """点击会话后轮询确认已打开。 + + 微信 4.x 聊天标题为浅灰渲染、OCR 常读不到,因此标题命中算最可靠 + 证据,读不到时以「消息区已渲染非空白」作为会话已打开的判据。 + 注意:若此前已开着其它会话,面板非空白并不代表目标已打开, + 必须优先看标题命中。 + """ + for _ in range(5): + time.sleep(0.6) + if self._chat_is_open(name): + return True + # 标题始终读不到才退而求其次:面板有内容且非目标会话也算打开 + # (点错会话时标题会匹配到别的名字,标题优先可拦截误开) + for _ in range(3): + time.sleep(0.4) + if self._chat_is_open(name): + return True + if self._pane_has_content(): + return True + return False + + def _pane_has_content(self) -> bool: + """右侧消息区是否渲染了内容(非全白空白页)。""" + try: + y0 = int(self.render_h * 0.18) + y1 = int(self.render_h * 0.72) + rel = (self.right_pane_left + 40, y0, self.render_w - 40, y1) + img = self._grab_screen(self._rel_to_screen(rel)) + px = img.load() + w, h = img.size + non_white = sum(1 for y in range(0, h, 6) for x in range(0, w, 6) + if sum(px[x, y][:3]) / 3 <= 235) + return non_white > 30 + except Exception: + return False + + def _chat_is_open(self, name: str) -> bool: + """检测右侧面板是否打开了指定会话(标题 OCR)。 + + 微信 4.x 标题 OCR 常把首字符截掉(“文件传输助手”→“件传输助”), + 因此不能用前 2 字匹配,需用名称中段片段(如第 2-3 字符)。标题 + 字号小、含生僻字时原尺寸 OCR 会漏识别,需放大后再读;标题行实际 + 渲染在 y≈80-180(非顶部 15-100),OCR 区需向上/向下多留。 + """ + try: + # 标题文本贴右面板左边缘(可能略越过侧栏边界),OCR 区向左多留 + x0 = max(0, self.right_pane_left - 60) + res = self.ocr_zoomed((x0, 0, self.render_w, 185), scale=3) + title = ''.join(t.strip() for t, x, y, w, h in res) + if len(name) >= 3: + frags = (name[1:3], name[2:4], name[-2:], name[:2]) + else: + frags = (name,) + return any(f and f in title for f in frags) + except Exception: + return False + + def _search_chat(self, name: str) -> bool: + """退路:搜索框 + 剪贴板粘贴搜索,点选名称匹配的第一条联系人。 + + 搜索下拉结果排布:联系人在最上方,下面是「搜索网络结果 / 搜一搜」 + 等节标题。OCR 结果按 y 排序后,跳过节标题/提示行,点选视觉上 + 第一条匹配名称的联系人行。 + + 群聊的成员预览行(如「00,包含:卢立竺」)也含目标名片段,若不 + 排除会误点群聊而非联系人。群聊节标题「群聊」以下的行优先排除, + 含「包含」的成员预览行直接跳过。 + """ + frag = name[:2] + for _ in range(3): + sb = self._rel_to_screen(self.search_box) + self.wx_click((sb[0] + sb[2]) // 2, (sb[1] + sb[3]) // 2) + time.sleep(0.3) + self._input.key(VK_A, ctrl=True) + self._input.key(VK_DELETE) + self.set_clipboard(name) + self._input.key(VK_V, ctrl=True) + time.sleep(0.8) + res = self.ocr_zoomed((SIDEBAR_LEFT, int(self.render_h * 0.08), + self.sidebar_right, self.render_h), scale=2) + rows = sorted(res, key=lambda r: (r[2], r[1])) + group_section = False + for t, x, y, w, h in rows: + tt = (t.strip() or '') + if not tt: + continue + if tt == '群聊': + group_section = True + continue + if tt.startswith('聊天记录') or tt.startswith('查看全部'): + break + if group_section: + continue + # 跳过“搜索/网络/搜一搜”等节标题与提示行 + if (tt.startswith('搜索') or tt.startswith('搜一搜') + or '网络' in tt or '暂无' in tt): + continue + # 群聊成员预览行,跳过以免误点群聊 + if '包含' in tt or tt.endswith('群') or tt.endswith('群聊'): + continue + if frag in tt: + self.wx_click(self.origin_x + x + w // 2, + self.origin_y + y + h // 2) + time.sleep(0.8) + return True + return False + + # ------------------------------------------------------------------ + # 输入框 + # ------------------------------------------------------------------ + def get_input_box(self) -> Optional[Tuple[int, int, int, int]]: + """自适应输入框检测,返回渲染相对矩形 (x0,y0,x1,y1)。 + + 原理:输入框是右侧面板底部一块**全宽浅色区**,与上方消息区以一条 + 约 2px 的浅灰边框线 ((224,224,224)) 分隔。先取若干探针行(自下而上 + 在输入框下半部找一行,要求该行在 right_pane_left..render_w 范围内 + 白度 >=0.8),再从探针行向上/向下扫描中心竖线确定输入框上下边界。 + 探测失败返回 None(不再回退到默认布局,避免在错误坐标上误点)。 + """ + for _ in range(6): + box = self._probe_input_box() + if box: + return box + time.sleep(0.5) + self._update_render_rect() + wxlog.debug('未检测到输入框') + # 布局异常自动重校准:本机校准配置可能已不匹配(DPI/布局漂移), + # 重新检测锚点并校准一次后再次探测(每会话只自动触发一次)。 + if not getattr(self, '_auto_recalibrated', False): + self._auto_recalibrated = True + wxlog.info('输入框探测连续失败,自动重新校准布局…') + self.calibrate_layout() + for _ in range(3): + box = self._probe_input_box() + if box: + return box + time.sleep(0.5) + self._update_render_rect() + wxlog.debug('未检测到输入框') + # 兜底:输入框与底部工具栏高度固定,窗口缩放只改变消息区高度。 + # 实测本机输入框上边 ≈ render_h-391、下边 ≈ render_h-150。 + return (self.right_pane_left, self.render_h - int(self.render_h * 0.214), + self.render_w, self.render_h - int(self.render_h * 0.082)) + + def _probe_input_box(self) -> Optional[Tuple[int, int, int, int]]: + """探针法定位输入框,失败返回 None。 + + 输入框是右侧面板底部一块全宽浅色区,顶边是一条约 2px 的浅灰 + (224,224,224)分界线,与上方消息区(白底)分隔。消息区在渲染 + 未稳定时可能整体发白,需校验分界线是「细线」而非消息区里的 + 粗灰元素,否则会把消息区误判为输入框。 + """ + cx = (self.right_pane_left + self.render_w) // 2 + sx = self.origin_x + cx + for probe_off in (150, 120, 200, 250, 350, 100, 450): + probe_y = self.render_h - probe_off + if probe_y <= int(self.render_h * 0.50): + continue + sy = self.origin_y + probe_y + row_img = self._grab_screen( + (self.origin_x + self.right_pane_left, sy, + self.origin_x + self.render_w, sy + 1)) + pxx = row_img.load() + w = row_img.size[0] + white = sum(1 for x in range(0, w, 2) if sum(pxx[x, 0]) / 3 > 240) + if white / max(1, (w + 1) // 2) < 0.8: + continue # 该行不在输入框内(如工具条/空白) + scan_top = self.origin_y + int(self.render_h * 0.50) + col = self._grab_screen((sx, scan_top, sx + 1, sy + 1)) + pc = col.load() + dy_probe = sy - scan_top + y0 = dy_probe + while y0 > 0 and sum(pc[0, y0]) / 3 > 240: + y0 -= 1 + y0 += 1 + y1 = dy_probe + while y1 < col.size[1] - 1 and sum(pc[0, y1]) / 3 > 240: + y1 += 1 + # 输入框顶边上方必须是 1-4px 的细灰分界线;若是消息区里的 + # 粗灰元素(如系统消息/时间分隔),说明渲染未稳定,判为失败。 + g = y0 - 1 + while g >= 0 and sum(pc[0, g]) / 3 <= 240: + g -= 1 + divider_h = (y0 - 1) - g + y0_abs = scan_top + y0 - self.origin_y + y1_abs = scan_top + y1 - self.origin_y + if (1 <= divider_h <= 4 + and y1_abs - y0_abs >= 150 + and y0_abs >= int(self.render_h * 0.45) + and y1_abs >= int(self.render_h * 0.85)): + return (self.right_pane_left, y0_abs, self.render_w, y1_abs) + return None + + def focus_input(self, box: Optional[Tuple[int, int, int, int]] = None) -> bool: + """点击输入框文本区使其获得焦点。返回是否检测到输入框。 + + box 可传入已探测好的输入框,避免重复探测在会话切换时偶发失败。 + 点击点取输入框顶部文本行附近(而非中心),避免点到下方 + 表情/工具栏而无法聚焦。 + """ + if box is None: + box = self.get_input_box() + if not box: + return False + x0, y0, x1, y1 = box + cx = (x0 + x1) // 2 + cy = y0 + min(24, (y1 - y0) // 4) # 文本行贴近输入框上沿 + self.wx_click(self.origin_x + cx, self.origin_y + cy) + time.sleep(0.6) + return True + + # ------------------------------------------------------------------ + # 文字输入 + # ------------------------------------------------------------------ + def set_clipboard(self, text: str): + """写入系统剪贴板(pyperclip,兼容中文)。""" + import pyperclip + pyperclip.copy(text) + time.sleep(0.2) + + def input_text(self, text: str, + box: Optional[Tuple[int, int, int, int]] = None, + fast: bool = False) -> bool: + """向当前聚焦的输入框输入文字。 + + 优先走「剪贴板 + Ctrl+V」并多次重试确认(输入框探测 / 焦点 / + 粘贴都可能偶发失败,整体循环重试);均失败后回退到「拼音 + + 回车提交」的输入法组合。 + + fast=True 时复用传入 box 走单次快速路径(分段连续发送用), + 失败即返回 False 由 send_msg 回退到完整流程。 + """ + if fast and box: + if self.focus_input(box): + self.set_clipboard(text) + self._input.key(VK_A, ctrl=True) + self._input.key(VK_DELETE) + self._input.key(VK_V, ctrl=True) + time.sleep(0.35) + if self._input_box_has_text(box): + return True + return False + box = None + for attempt in range(1, 7): + box = self.get_input_box() + if not box: + wxlog.debug(f'未探测到输入框(attempt={attempt}),重试') + time.sleep(0.5) + continue + if not self.focus_input(box): + time.sleep(0.3) + continue + self.set_clipboard(text) + self._input.key(VK_A, ctrl=True) # 清空既有内容 + self._input.key(VK_DELETE) + self._input.key(VK_V, ctrl=True) + time.sleep(0.8) + if self._input_box_has_text(): + self._last_input_box = box + wxlog.debug(f'输入文字(剪贴板粘贴)成功,attempt={attempt}') + return True + wxlog.debug(f'剪贴板粘贴未确认(attempt={attempt}),重试') + time.sleep(0.3) + # 尝试 2:中文输入法拼音(逐字) + wxlog.debug('剪贴板粘贴多次未生效,尝试拼音组合输入') + self.focus_input(box) + self._input.key(VK_A, ctrl=True) + self._input.key(VK_DELETE) + self._input.type_pinyin(self._to_pinyin(text)) + self._input.key(VK_RETURN) # 提交候选 + time.sleep(0.8) + return self._input_box_has_text() + + @staticmethod + def _to_pinyin(text: str) -> str: + """极简中文 → 拼音映射(仅内置少量常用词,供回退路径使用)。 + + 正式方案建议接入 ``pypinyin``(pip install pypinyin)。 + """ + table = { + '测试': 'ceshi', '你好': 'nihao', '你好世界': 'nihaoshijie', + '你好,世界': 'nihaoshijie', '消息': 'xiaoxi', '发送': 'fasong', + '自动化': 'zidonghua', '成功': 'chenggong', '文件': 'wenjian', + '文件传输助手': 'wenjianchuanshuzhushou', + } + if text in table: + return table[text] + try: + import pypinyin + return ''.join(pypinyin.lazy_pinyin(text)) + except ImportError: + return ''.join(ch for ch in text if '\u4e00' <= ch <= '\u9fff') or text + + def _input_box_has_text(self, box=None) -> bool: + """检测输入框文本区是否有深色像素(文字/光标),确认输入生效。 + + box 可传入已探测好的输入框,避免连续发送时重复探测。 + + 阈值收紧到 sum<450:空输入框的浅灰占位符约为 (200,200,200) 即 + 600,避免把占位符误判为未发送的文字导致消息重复发送。 + """ + if box is None: + box = self.get_input_box() + if not box: + return False + x0, y0, x1, y1 = box + rel = (x0 + 20, y0 + 10, x1 - 20, y0 + 200) + img = self._grab_screen(self._rel_to_screen(rel)) + px = img.load() + dark = sum(1 for y in range(0, img.size[1], 2) for x in range(0, img.size[0], 2) + if sum(px[x, y]) < 450) + return dark > 20 + + # ------------------------------------------------------------------ + # 发送 + # ------------------------------------------------------------------ + def click_send(self, fast: bool = False) -> bool: + """发送消息并确认输入框已清空。 + + 优先回车键(输入框刚粘贴完必已聚焦,回车最可靠);回车后输入框 + 仍有内容则回退到 OCR 定位「发送」按钮点击。每次操作后都必须确认 + 输入框文本已清空(即消息真正发出),否则重试。 + + 关键防护:发送前若输入框本无文字,回车等于空发,必须判定失败 + 让上层重试(否则消息未发出却被误判成功)。 + + fast=True 时仅回车 + 短等待(分段连续发送用),失败返回 False + 由 send_msg 回退到完整流程。 + """ + box = getattr(self, '_last_input_box', None) + if fast: + if not self._input_box_has_text(box): + return False + self._input.key(VK_RETURN) + time.sleep(0.5) + if not self._input_box_has_text(box): + return True + return False + for attempt in range(3): + if not self._input_box_has_text(box): + wxlog.debug('发送前输入框无文字,跳过空发') + return False + self._input.key(VK_RETURN) + time.sleep(1.0) + if not self._input_box_has_text(box): + return True + wxlog.debug(f'回车发送未生效(attempt={attempt}),改用「发送」按钮') + res = self.ocr(self.send_button_region) + clicked = False + for text, x, y, w, h in res: + if '发送' in text: + self.wx_click(self.origin_x + x + w // 2, + self.origin_y + y + h // 2) + clicked = True + break + if not clicked: + return False + time.sleep(1.0) + if not self._input_box_has_text(box): + return True + return False + + def send_msg(self, text: str, who: Optional[str] = None, + verify: bool = False) -> WxResponse: + """发送一条文本消息。 + + Args: + text: 消息内容 + who: 目标会话名称(默认发送到当前打开的会话) + verify: 是否用数据库读取器回读确认发送成功 + + Returns: + WxResponse + + 整条流程带总时限(默认 75s):打开会话 / 输入 / 发送任一步偶发 + 失败时重试;已发送但 DB 未落库时轮询等待确认,不重复发送。 + """ + # 快速路径:连续发送同一会话(如分段回复)时,复用已探测的输入框, + # 跳过 ensure_visible / 会话重检 / 重复探测与截图确认,失败自动回退完整流程。 + if (not verify and who + and who == getattr(self, '_current_chat', None) + and getattr(self, '_last_input_box', None) is not None + and self.input_text(text, box=self._last_input_box, fast=True) + and self.click_send(fast=True)): + return WxResponse.success(f'消息已发送:{text}', data={'content': text}) + # UIA 路径:热激活后可直接输入+回车发送,无 OCR 抖动,最快。 + uia = self._get_uia() + if uia is not None: + if not who or uia.current_chat() == who or uia.open_chat(who): + if uia.send_text(text): + if not verify: + return WxResponse.success(f'消息已发送:{text}', data={'content': text}) + if self._verify_sent(text, who): + return WxResponse.success(f'消息已发送并确认:{text}', data={'content': text}) + wait_until = time.time() + 8 + while time.time() < wait_until: + time.sleep(1.0) + if self._verify_sent(text, who): + return WxResponse.success(f'消息已发送并确认:{text}', data={'content': text}) + return WxResponse.failure('消息已操作发送,但数据库未确认', data={'content': text}) + if not self.ensure_visible(): + return WxResponse.failure('微信窗口不可见(可能锁屏/会话断开)') + self._last_input_box = None + deadline = time.time() + 75 + for attempt in range(3): + if who: + if time.time() > deadline: + break + # 会话复用:目标仍是当前已打开会话时跳过 open_chat(每次 + # open_chat 都重扫侧栏/点击,是逐条发送的主要耗时点) + if not (who == getattr(self, '_current_chat', None) + and self._chat_is_open(who)): + if not self.open_chat(who): + wxlog.debug(f'open_chat 未确认(attempt={attempt}),重试') + continue + self._current_chat = who + time.sleep(0.8) # 等右侧面板/输入框渲染稳定,避免探测误判 + if time.time() > deadline: + break + if not self.input_text(text): + wxlog.debug(f'输入文字失败(attempt={attempt}),重试') + continue + if not self.click_send(): + wxlog.debug(f'点击发送未确认清空输入框(attempt={attempt}),重试') + continue + if not verify: + return WxResponse.success(f'消息已发送:{text}', data={'content': text}) + if self._verify_sent(text, who): + return WxResponse.success(f'消息已发送并确认:{text}', data={'content': text}) + # 可能已发送但 DB 异步落库,轮询确认,不重发避免重复 + wait_until = time.time() + 8 + while time.time() < wait_until: + time.sleep(1.0) + if self._verify_sent(text, who): + return WxResponse.success(f'消息已发送并确认:{text}', data={'content': text}) + return WxResponse.failure('消息已操作发送,但数据库未确认', data={'content': text}) + return WxResponse.failure('发送失败:多次重试未完成') + + def _get_db(self): + """惰性创建并复用 WeChatDB(密钥提取/解密较慢,避免每次校验都重建)。""" + if getattr(self, '_cached_db', None) is None: + from wechatauto.db import WeChatDB + self._cached_db = WeChatDB() + return self._cached_db + + def _verify_sent(self, text: str, who: Optional[str]) -> bool: + try: + db = self._get_db() + if not who: + who = db.get_self_info()['username'] + else: + hits = db.search_contact(who) + if hits: + who = hits[0]["username"] + msgs = db.get_messages(who, limit=3) + for m in msgs: + if db.is_self_sender(m.get('sender_id')) and text in (m.get('content') or ''): + return True + except Exception as e: + wxlog.debug(f'发送校验失败:{e}') + return False + + # ------------------------------------------------------------------ + # 文件 / 图片发送(剪贴板 CF_HDROP + Ctrl+V) + # ------------------------------------------------------------------ + @staticmethod + def copy_files_to_clipboard(paths: List[str]) -> bool: + """把本地文件以 CF_HDROP 格式写入剪贴板,供微信粘贴为附件/图片。 + + 相比走「+ 菜单 → 文件对话框」,该路线不依赖自绘界面图标定位, + 兼容性最好:在聊天输入框 Ctrl+V 后,微信会把文件/图片插入草稿。 + """ + paths = [os.path.abspath(p) for p in paths] + if not paths: + return False + class DROPFILES(ctypes.Structure): + _fields_ = [ + ("pFiles", ctypes.c_uint), + ("pt_x", ctypes.c_long), + ("pt_y", ctypes.c_long), + ("fNC", ctypes.c_int), + ("fWide", ctypes.c_int), + ] + u32 = ctypes.windll.user32 + k32 = ctypes.windll.kernel32 + u32.OpenClipboard.argtypes = [ctypes.c_void_p] + u32.SetClipboardData.argtypes = [ctypes.c_uint, ctypes.c_void_p] + k32.GlobalAlloc.restype = ctypes.c_void_p + k32.GlobalAlloc.argtypes = [ctypes.c_uint, ctypes.c_size_t] + k32.GlobalLock.restype = ctypes.c_void_p + k32.GlobalLock.argtypes = [ctypes.c_void_p] + k32.GlobalUnlock.argtypes = [ctypes.c_void_p] + CF_HDROP = 15 + try: + if not u32.OpenClipboard(None): + return False + u32.EmptyClipboard() + df = DROPFILES() + df.pFiles = ctypes.sizeof(DROPFILES) + df.fWide = 1 + raw = (ctypes.string_at(ctypes.byref(df), ctypes.sizeof(DROPFILES)) + + ("\0".join(paths) + "\0").encode("utf-16-le") + b"\0\0") + h = k32.GlobalAlloc(0x0042, len(raw)) + if not h: + u32.CloseClipboard() + return False + dst = k32.GlobalLock(h) + ctypes.memmove(dst, raw, len(raw)) + k32.GlobalUnlock(h) + u32.SetClipboardData(CF_HDROP, h) + u32.CloseClipboard() + return True + except Exception as e: + wxlog.debug(f'写入 CF_HDROP 剪贴板失败:{e}') + return False + + def _paste_attachment_and_send(self, path: str, + box: Optional[Tuple[int, int, int, int]] = None) -> bool: + """聚焦输入框 → 粘贴文件 → 检测草稿就绪 → 回车发送。 + + 图片草稿为彩色像素、文件为灰色卡片。图片粘贴偶发失效, + 采用「重新聚焦 + 重新粘贴」重试循环提升可靠性。 + + box 可传入已探测好的输入框(连续发送附件时复用,避免重复探测)。 + """ + if not os.path.isfile(path): + wxlog.debug(f'文件不存在:{path}') + return False + is_image = path.lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp')) + if box is None: + box = self.get_input_box() + wxlog.debug(f'粘贴前输入框探测:{box}') + for attempt in range(3): + if not self.focus_input(box): + return False + if not self.copy_files_to_clipboard([path]): + return False + time.sleep(0.3) + self._input.key(VK_A, ctrl=True) + self._input.key(VK_DELETE) + self._input.key(VK_V, ctrl=True) + if is_image: + draft_ok = self._input_box_has_color_draft(box, wait=6.0) + wxlog.debug(f'粘贴尝试 {attempt + 1} 草稿检测:{draft_ok}') + if draft_ok: + break + else: + time.sleep(2.0) + break + else: + wxlog.debug('多次粘贴仍未检测到图片草稿,仍尝试回车') + self._input.key(VK_RETURN) + time.sleep(1.5) + return True + + def _input_box_has_color_draft(self, box: Optional[Tuple[int, int, int, int]] = None, + wait: float = 8.0) -> bool: + """轮询输入框区域是否存在彩色像素(图片缩略图草稿已渲染)。 + + 图片粘贴后输入框会向上扩展容纳缩略图,因此扫描区域向上多 + 覆盖一段(y0-150),避免草稿出现在探测基线之上而漏检。 + """ + if box is None: + box = self.get_input_box() + if not box: + return False + x0, y0, x1, y1 = box + scan_y0 = max(100, y0 - 150) + scan_y1 = min(self.render_h - 15, y1 + 80) + rel = (x0 + 10, scan_y0, x1 - 10, scan_y1) + screen_rect = self._rel_to_screen(rel) + deadline = time.time() + wait + last_colored = 0 + while time.time() < deadline: + try: + img = self._grab_screen(screen_rect) + px = img.load() + colored = 0 + for yy in range(0, img.size[1], 4): + for xx in range(0, img.size[0], 4): + r, g, b = px[xx, yy][:3] + if abs(r - g) > 20 or abs(g - b) > 20 or abs(r - b) > 20: + colored += 1 + last_colored = colored + if colored > 30: + return True + except Exception: + pass + time.sleep(0.3) + wxlog.debug(f'草稿检测失败:box={box} rel={rel} colored={last_colored}') + return False + + def _open_chat_and_settle(self, who: str) -> bool: + """打开会话并等待切换动画完成,返回输入框是否可探测。 + + 会话消息区若正显示大图,输入框探测会失败(返回 None)。 + 重复点击会话会改变消息区滚动状态,重试直到探测成功。 + """ + for _ in range(5): + self.open_chat(who) + time.sleep(1.2) + if self.get_input_box(): + return True + wxlog.debug(f'打开会话后未检测到输入框,重试 open_chat({who})') + return bool(self.get_input_box()) + + def send_file(self, path: str, who: Optional[str] = None, + verify: bool = False) -> WxResponse: + """发送本地文件(剪贴板粘贴路线)。""" + if not self.ensure_visible(): + return WxResponse.failure('微信窗口不可见(可能锁屏/会话断开)') + # 会话复用:目标仍是当前已打开会话且输入框可探测时跳过 open_chat + # (open_chat 重扫侧栏/点击是附件发送的主要耗时点) + if who and not (who == getattr(self, '_current_chat', None) + and self.get_input_box()): + if not self._open_chat_and_settle(who): + return WxResponse.failure(f'无法打开会话:{who}') + self._current_chat = who + box = self.get_input_box() + before_seq = self._target_seq(who) + if not self._paste_attachment_and_send(path, box): + return WxResponse.failure(f'文件发送失败:{path}') + if verify: + ok = self._verify_attachment_sent(path, who, before_seq) + return (WxResponse.success(f'文件已发送并确认:{path}', data={'path': path}) + if ok else WxResponse.failure('文件已操作发送,但数据库未确认', data={'path': path})) + return WxResponse.success(f'文件已发送:{path}', data={'path': path}) + + def send_image(self, path: str, who: Optional[str] = None, + verify: bool = False) -> WxResponse: + """发送本地图片(剪贴板粘贴路线,微信自动作为图片消息插入)。""" + if not self.ensure_visible(): + return WxResponse.failure('微信窗口不可见(可能锁屏/会话断开)') + if who and not (who == getattr(self, '_current_chat', None) + and self.get_input_box()): + if not self._open_chat_and_settle(who): + return WxResponse.failure(f'无法打开会话:{who}') + self._current_chat = who + box = self.get_input_box() + before_seq = self._target_seq(who) + if not self._paste_attachment_and_send(path, box): + return WxResponse.failure(f'图片发送失败:{path}') + if verify: + ok = self._verify_attachment_sent(path, who, before_seq) + return (WxResponse.success(f'图片已发送并确认:{path}', data={'path': path}) + if ok else WxResponse.failure('图片已操作发送,但数据库未确认', data={'path': path})) + return WxResponse.success(f'图片已发送:{path}', data={'path': path}) + + def _target_seq(self, who: Optional[str]) -> int: + """取目标会话当前最大 sort_seq,作为发送后校验的基线。""" + try: + db = self._get_db() + if not who: + who = db.get_self_info()['username'] + else: + hits = db.search_contact(who) + if hits: + who = hits[0]["username"] + msgs = db.get_messages(who, limit=1) + return msgs[0]['sort_seq'] if msgs else 0 + except Exception: + return 0 + + def _verify_attachment_sent(self, path: str, who: Optional[str], + before_seq: int = 0) -> bool: + try: + db = self._get_db() + if not who: + who = db.get_self_info()['username'] + else: + hits = db.search_contact(who) + if hits: + who = hits[0]["username"] + fname = os.path.basename(path) + fname_bytes = fname.encode('utf-8') + # 微信会自动重名文件为 名称(n).ext,匹配文件名主干 + stem = os.path.splitext(fname)[0] + stem_bytes = stem.encode('utf-8') + is_image = path.lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp')) + expect_type = '图片' if is_image else '文件/链接/卡片' + # 微信发送后 DB 异步落库,文件消息落库更慢,轮询放宽到 10s + deadline = time.time() + (6.0 if is_image else 10.0) + while time.time() < deadline: + # 优先:发送后出现了 sort_seq 更大的同类型消息(图片消息无文件名,只能靠它) + for m in db.get_new_messages(who, since_seq=before_seq, limit=8): + if m.get('sender_id') != 2 or m.get('type') != expect_type: + continue + # 文件消息再做文件名匹配,图片消息仅凭类型+时序 + if is_image: + return True + if fname in (m.get('content') or ''): + return True + row = db.get_message_row(who, m.get('local_id')) + if row and row.get('packed_info') and isinstance(row['packed_info'], bytes): + if fname_bytes in row['packed_info']: + return True + # 兼容重命名:主干匹配 + packed_info 内同一文件(主干名出现即可) + if stem_bytes in row['packed_info']: + return True + time.sleep(0.5) + except Exception as e: + wxlog.debug(f'附件校验失败:{e}') + return False + + # ------------------------------------------------------------------ + # 回复 / 引用 + # ------------------------------------------------------------------ + def _last_message_y(self) -> Optional[int]: + """估算最近一条消息的位置(输入框上沿往上一点)。""" + box = self.get_input_box() + if not box: + return None + return max(100, box[1] - 80) + + def reply_msg(self, text: str, who: Optional[str] = None, + target_text: Optional[str] = None, verify: bool = False) -> WxResponse: + """回复最近一条消息(悬停消息 → 点击「回复」→ 输入 → 发送)。 + + target_text 用于在 OCR 结果中匹配目标消息(可选)。 + """ + if not self.ensure_visible(): + return WxResponse.failure('微信窗口不可见(可能锁屏/会话断开)') + if who: + self.open_chat(who) + time.sleep(0.8) + y = self._last_message_y() + if y is None: + return WxResponse.failure('未检测到消息区域') + u = self._input._user32 + u.SetCursorPos(self.origin_x + (self.render_w + self.right_pane_left) // 2, + self.origin_y + y) + time.sleep(0.8) + # OCR 悬停工具栏(回复/引用等图标) + region = (self.right_pane_left, y - 60, self.render_w, y + 40) + items = self.ocr(region) + click_pt = None + for text, x, yy, w, h in items: + if '回复' in text or '引用' in text or '转发' in text: + click_pt = (x + w // 2, yy + h // 2) + break + if not click_pt: + wxlog.debug('未识别到回复工具栏,尝试右键菜单') + self.wx_click(self.origin_x + (self.render_w + self.right_pane_left) // 2, + self.origin_y + y, right=True) + time.sleep(0.6) + menu = self.ocr((self.right_pane_left, y, self.render_w, self.render_h)) + for text, x, yy, w, h in menu: + if '回复' in text: + click_pt = (x + w // 2, yy + h // 2) + break + if not click_pt: + return WxResponse.failure('未找到回复入口') + self.wx_click(self.origin_x + click_pt[0], self.origin_y + click_pt[1]) + time.sleep(0.6) + if not self.input_text(text): + return WxResponse.failure('输入回复内容失败') + self.click_send() + if verify: + ok = self._verify_sent(text, who) + return (WxResponse.success(f'回复已发送并确认:{text}', data={'content': text}) + if ok else WxResponse.failure('回复已操作发送,但数据库未确认', data={'content': text})) + return WxResponse.success(f'回复已发送:{text}', data={'content': text}) + + # ------------------------------------------------------------------ + # 艾特成员(群聊) + # ------------------------------------------------------------------ + def at_member(self, member: str, text: str, who: Optional[str] = None, + verify: bool = False) -> WxResponse: + """在群聊中 @ 成员后追加发送 text。 + + 流程:输入框键入 '@' → OCR 成员选择弹层定位成员 → 点击 → 输入正文 → 发送。 + """ + if not self.ensure_visible(): + return WxResponse.failure('微信窗口不可见(可能锁屏/会话断开)') + if who: + self.open_chat(who) + time.sleep(0.8) + if not self.focus_input(): + return WxResponse.failure('输入框不可用') + self._input.type_unicode('@') + time.sleep(0.9) + box = self.get_input_box() + popup = (self.right_pane_left, max(80, (box[1] if box else int(self.render_h * 0.49)) - 500), + self.render_w, (box[1] if box else int(self.render_h * 0.77))) + items = self.ocr(popup) + target = None + for t, x, yy, w, h in items: + if member in t or t.startswith(member): + target = (x + w // 2, yy + h // 2) + break + if not target: + return WxResponse.failure(f'未在成员列表中找到:{member}') + self.wx_click(self.origin_x + target[0], self.origin_y + target[1]) + time.sleep(0.6) + if text and not self.input_text(text): + return WxResponse.failure('输入消息正文失败') + self.click_send() + if verify: + ok = self._verify_sent(text, who) + return (WxResponse.success(f'@成员消息已发送并确认', data={'member': member, 'content': text}) + if ok else WxResponse.failure('@消息已操作发送,但数据库未确认', data={'member': member})) + return WxResponse.success(f'@成员消息已发送', data={'member': member, 'content': text}) + + +# --------------------------------------------------------------------------- +# 便捷入口 +# --------------------------------------------------------------------------- + +def quick_send(text: str, who: str = None, verify: bool = False) -> WxResponse: + """一行式发送消息。 + + >>> from wechatauto.guia import quick_send + >>> quick_send('你好', '文件传输助手') + """ + wx = WeChatGUI() + return wx.send_msg(text, who, verify) + + +def quick_send_file(path: str, who: str = None, verify: bool = False) -> WxResponse: + """一行式发送文件。""" + wx = WeChatGUI() + return wx.send_file(path, who, verify) + + +def quick_send_image(path: str, who: str = None, verify: bool = False) -> WxResponse: + """一行式发送图片。""" + wx = WeChatGUI() + return wx.send_image(path, who, verify) + + +def quick_reply(text: str, who: str = None, verify: bool = False) -> WxResponse: + """一行式回复最近一条消息。""" + wx = WeChatGUI() + return wx.reply_msg(text, who, verify=verify) diff --git a/wechatauto/languages.py b/wechatauto/languages.py new file mode 100644 index 0000000..f055728 --- /dev/null +++ b/wechatauto/languages.py @@ -0,0 +1,279 @@ +"""微信界面文案的多语言配置表。 + +每一项均为 ``{键: {'cn': ..., 'cn_t': ..., 'en': ...}}`` 结构, +通过 :func:`get_lang` 依据 :attr:`wechatauto.param.WxParam.LANGUAGE` +取值,未命中时回退到简体中文,再回退到键本身。 +""" + +from wechatauto.param import WxParam + + +def get_lang(table: dict, key: str) -> str: + item = table.get(key) + if not isinstance(item, dict): + return key + text = item.get(getattr(WxParam, 'LANGUAGE', 'cn')) + if text: + return text + text = item.get('cn') + return text if text else key + + +WECHAT_MAIN = { + '新的朋友': {'cn': '新的朋友', 'cn_t': '', 'en': ''}, + '添加朋友': {'cn': '添加朋友', 'cn_t': '', 'en': ''}, + '搜索结果': {'cn': '搜索:', 'cn_t': '', 'en': ''}, + '发起群聊': {'cn': '发起群聊', 'cn_t': '', 'en': ''}, + '找不到相关账号或内容': {'cn': '找不到相关账号或内容', 'cn_t': '', 'en': ''}, +} + +WECHAT_NAVIGATION_BOX = { + '聊天': {'cn': '聊天', 'cn_t': '聊天', 'en': 'Chats'}, + '通讯录': {'cn': '通讯录', 'cn_t': '通訊錄', 'en': 'Contacts'}, + '收藏': {'cn': '收藏', 'cn_t': '收藏', 'en': 'Favorites'}, + '聊天文件': {'cn': '聊天文件', 'cn_t': '聊天文件', 'en': 'Files'}, + '朋友圈': {'cn': '朋友圈', 'cn_t': '朋友圈', 'en': 'Moments'}, + '搜一搜': {'cn': '搜一搜', 'cn_t': '搜一搜', 'en': 'Search'}, + '视频号': {'cn': '视频号', 'cn_t': '視頻號', 'en': 'Channels'}, + '看一看': {'cn': '看一看', 'cn_t': '看一看', 'en': 'Top Stories'}, + '小程序面板': {'cn': '小程序面板', 'cn_t': '小程序面板', 'en': 'Mini Programs'}, + '手机': {'cn': '手机', 'cn_t': '手機', 'en': 'Phone'}, + '设置及其他': {'cn': '设置及其他', 'cn_t': '設置及其他', 'en': 'Settings'}, + '更多': {'cn': '更多', 'cn_t': '更多', 'en': 'More'}, +} + +WECHAT_CHAT_BOX = { + '查看更多消息': {'cn': '查看更多消息', 'cn_t': '', 'en': ''}, + '消息': {'cn': '消息', 'cn_t': '', 'en': ''}, + '表情': {'cn': '表情(Alt+E)', 'cn_t': '', 'en': ''}, + '发送文件': {'cn': '发送文件', 'cn_t': '', 'en': ''}, + '截图': {'cn': '截图', 'cn_t': '', 'en': ''}, + '聊天记录': {'cn': '聊天记录', 'cn_t': '', 'en': ''}, + '语音聊天': {'cn': '语音聊天', 'cn_t': '', 'en': ''}, + '视频聊天': {'cn': '视频聊天', 'cn_t': '', 'en': ''}, + '聊天信息': {'cn': '聊天信息', 'cn_t': '', 'en': ''}, + '发送': {'cn': '发送(S)', 'cn_t': '', 'en': ''}, + '置顶': {'cn': '置顶', 'cn_t': '', 'en': ''}, + '最小化': {'cn': '最小化', 'cn_t': '', 'en': ''}, + '最大化': {'cn': '最大化', 'cn_t': '', 'en': ''}, + '关闭': {'cn': '关闭', 'cn_t': '', 'en': ''}, + '多选': {'cn': '多选', 'cn_t': '', 'en': ''}, + '以下为新消息': {'cn': '以下为新消息', 'cn_t': '', 'en': ''}, + 're_新消息按钮': {'cn': r'.*?条新消息', 'cn_t': '', 'en': ''}, +} + +WECHAT_SESSION_BOX = { + # 聊天页面 + '聊天记录': {'cn': '聊天记录', 'cn_t': '', 'en': ''}, + '会话': {'cn': '会话', 'cn_t': '', 'en': ''}, + '已置顶': {'cn': '已置顶', 'cn_t': '', 'en': ''}, + '文件传输助手': {'cn': '文件传输助手', 'cn_t': '', 'en': ''}, + '折叠的群聊': {'cn': '折叠的群聊', 'cn_t': '', 'en': ''}, + '折叠置顶聊天': {'cn': '折叠置顶聊天', 'cn_t': '', 'en': ''}, + '发起群聊': {'cn': '发起群聊', 'cn_t': '', 'en': ''}, + '搜索': {'cn': '搜索', 'cn_t': '', 'en': ''}, + 're_条数': {'cn': r'\[\d+条\]', 'cn_t': '', 'en': ''}, + 're_置顶聊天': {'cn': r'.*?个置顶聊天', 'cn_t': '', 'en': ''}, + + # 联系人页面 + '添加朋友': {'cn': '添加朋友', 'cn_t': '', 'en': ''}, + '联系人': {'cn': '联系人', 'cn_t': '', 'en': ''}, + '通讯录管理': {'cn': '通讯录管理', 'cn_t': '', 'en': ''}, + '新的朋友': {'cn': '新的朋友', 'cn_t': '', 'en': ''}, + '公众号': {'cn': '公众号', 'cn_t': '', 'en': ''}, + '企业号': {'cn': '企业号', 'cn_t': '', 'en': ''}, + '群聊': {'cn': '群聊', 'cn_t': '', 'en': ''}, + + # 收藏页面 + '分类': {'cn': '分类', 'cn_t': '', 'en': ''}, + '新建笔记': {'cn': '新建笔记', 'cn_t': '', 'en': ''}, + '全部收藏': {'cn': '全部收藏', 'cn_t': '', 'en': ''}, + '最近使用': {'cn': '最近使用', 'cn_t': '', 'en': ''}, + '链接': {'cn': '链接', 'cn_t': '', 'en': ''}, + '图片与视频': {'cn': '图片与视频', 'cn_t': '', 'en': ''}, + '笔记': {'cn': '笔记', 'cn_t': '', 'en': ''}, + '文件': {'cn': '文件', 'cn_t': '', 'en': ''}, + '分割线': {'cn': '分割线', 'cn_t': '', 'en': ''}, + '展开标签': {'cn': '展开标签', 'cn_t': '', 'en': ''}, + '折叠标签': {'cn': '折叠标签', 'cn_t': '', 'en': ''}, + '标签': {'cn': '标签', 'cn_t': '', 'en': ''}, +} + +MESSAGES = { + '[图片]': {'cn': '[图片]', 'cn_t': '', 'en': ''}, + '[视频]': {'cn': '[视频]', 'cn_t': '', 'en': ''}, + '[语音]': {'cn': '[语音]', 'cn_t': '', 'en': ''}, + '[音乐]': {'cn': '[音乐]', 'cn_t': '', 'en': ''}, + '[位置]': {'cn': '[位置]', 'cn_t': '', 'en': ''}, + '[链接]': {'cn': '[链接]', 'cn_t': '', 'en': ''}, + '[文件]': {'cn': '[文件]', 'cn_t': '', 'en': ''}, + '[名片]': {'cn': '[名片]', 'cn_t': '', 'en': ''}, + '[笔记]': {'cn': '[笔记]', 'cn_t': '', 'en': ''}, + '[视频号]': {'cn': '[视频号]', 'cn_t': '', 'en': ''}, + '[动画表情]': {'cn': '[动画表情]', 'cn_t': '', 'en': ''}, + '[聊天记录]': {'cn': '[聊天记录]', 'cn_t': '', 'en': ''}, + '微信转账': {'cn': '微信转账', 'cn_t': '', 'en': ''}, + '接收中': {'cn': '接收中', 'cn_t': '', 'en': ''}, + 're_语音': {'cn': r'^\[语音\]\d+秒(,未播放)?$', 'cn_t': '', 'en': ''}, + 're_引用消息': {'cn': r'(^.+)\n引用.*?的消息 : (.+$)', 'cn_t': '', 'en': ''}, + 're_拍一拍': {'cn': r'^.+拍了拍.+$', 'cn_t': '', 'en': ''}, +} + +MENU_OPTIONS = { + # session + '置顶': {'cn': '置顶', 'cn_t': '置頂', 'en': 'Pin'}, + '取消置顶': {'cn': '取消置顶', 'cn_t': '取消置頂', 'en': 'Unpin'}, + '标为未读': {'cn': '标为未读', 'cn_t': '標為未讀', 'en': 'Mark as unread'}, + '消息免打扰': {'cn': '消息免打扰', 'cn_t': '消息免打擾', 'en': 'Mute'}, + '在独立窗口打开': {'cn': '在独立窗口打开', 'cn_t': '在獨立窗口打開', 'en': 'Open in separate window'}, + '不显示聊天': {'cn': '不显示聊天', 'cn_t': '不顯示聊天', 'en': 'Hide chat'}, + '删除聊天': {'cn': '删除聊天', 'cn_t': '刪除聊天', 'en': 'Delete chat'}, + + # msg + '撤回': {'cn': '撤回', 'cn_t': '撤回', 'en': 'Recall'}, + '复制': {'cn': '复制', 'cn_t': '複製', 'en': 'Copy'}, + '放大阅读': {'cn': '放大阅读', 'cn_t': '放大閱讀', 'en': 'Enlarge'}, + '翻译': {'cn': '翻译', 'cn_t': '翻譯', 'en': 'Translate'}, + '转发': {'cn': '转发...', 'cn_t': '轉發...', 'en': 'Forward...'}, + '收藏': {'cn': '收藏', 'cn_t': '收藏', 'en': 'Favorite'}, + '多选': {'cn': '多选', 'cn_t': '多選', 'en': 'Select multiple'}, + '引用': {'cn': '引用', 'cn_t': '引用', 'en': 'Quote'}, + '搜一搜': {'cn': '搜一搜', 'cn_t': '搜一搜', 'en': 'Search'}, + '删除': {'cn': '删除', 'cn_t': '刪除', 'en': 'Delete'}, + '编辑': {'cn': '编辑', 'cn_t': '編輯', 'en': 'Edit'}, + '另存为': {'cn': '另存为...', 'cn_t': '另存為...', 'en': 'Save as...'}, + '语音转文字': {'cn': '语音转文字', 'cn_t': '語音轉文字', 'en': 'Transcribe'}, + '在文件夹中显示': {'cn': '在文件夹中显示', 'cn_t': '在文件夾中顯示', 'en': 'Show in folder'}, + + # edit + '剪切': {'cn': '剪切', 'cn_t': '剪切', 'en': 'Cut'}, + '粘贴': {'cn': '粘贴', 'cn_t': '粘貼', 'en': 'Paste'}, +} + +MOMENTS = { + '朋友圈': {'cn': '朋友圈', 'cn_t': '朋友圈', 'en': 'Moments'}, + '刷新': {'cn': '刷新', 'cn_t': '刷新', 'en': 'Refresh'}, + '评论': {'cn': '评论', 'cn_t': '評論', 'en': 'Comment'}, + '广告': {'cn': '广告', 'cn_t': '廣告', 'en': 'Advertisement'}, + '赞': {'cn': '赞', 'cn_t': '讚', 'en': 'Like'}, + '取消': {'cn': '取消', 'cn_t': '取消', 'en': 'Cancel'}, + '发送': {'cn': '发送', 'cn_t': '發送', 'en': 'Send'}, + '分隔符_点赞': {'cn': ',', 'cn_t': ',', 'en': ', '}, + 're_图片数': {'cn': r'包含\d+张图片', 'cn_t': r'包含\d+張圖片', 'en': r'Contains \d+ photos'}, +} + +MOMENT_PRIVACY = { + '谁可以看': {'cn': '谁可以看', 'cn_t': '誰可以看', 'en': 'Who can see'}, + '公开': {'cn': '公开', 'cn_t': '公開', 'en': 'Public'}, + '所有朋友可见': {'cn': '所有朋友可见', 'cn_t': '所有朋友可見', 'en': 'All friends'}, + '私密': {'cn': '私密', 'cn_t': '私密', 'en': 'Private'}, + '仅自己可见': {'cn': '仅自己可见', 'cn_t': '僅自己可見', 'en': 'Only me'}, + '白名单': {'cn': '谁可以看', 'cn_t': '誰可以看', 'en': 'Selected friends'}, + '黑名单': {'cn': '不给谁看', 'cn_t': '不給誰看', 'en': 'Exclude friends'}, + '完成': {'cn': '完成', 'cn_t': '完成', 'en': 'Done'}, + '确定': {'cn': '确定', 'cn_t': '確定', 'en': 'OK'}, + '取消': {'cn': '取消', 'cn_t': '取消', 'en': 'Cancel'}, +} + +IMAGE_WINDOW = { + '上一张': {'cn': '上一张', 'cn_t': '上一張', 'en': 'Previous'}, + '下一张': {'cn': '下一张', 'cn_t': '下一張', 'en': 'Next'}, + '预览': {'cn': '预览', 'cn_t': '預覽', 'en': 'Preview'}, + '放大': {'cn': '放大', 'cn_t': '放大', 'en': 'Zoom'}, + '缩小': {'cn': '缩小', 'cn_t': '縮小', 'en': 'Shrink'}, + '图片原始大小': {'cn': '图片原始大小', 'cn_t': '圖片原始大小', 'en': 'Original size'}, + '旋转': {'cn': '旋转', 'cn_t': '旋轉', 'en': 'Rotate'}, + '编辑': {'cn': '编辑', 'cn_t': '編輯', 'en': 'Edit'}, + '翻译': {'cn': '翻译', 'cn_t': '翻譯', 'en': 'Translate'}, + '提取文字': {'cn': '提取文字', 'cn_t': '提取文字', 'en': 'Extract text'}, + '识别图中二维码': {'cn': '识别图中二维码', 'cn_t': '識別圖中QR Code', 'en': 'Extract QR Code'}, + '另存为': {'cn': '另存为...', 'cn_t': '另存為...', 'en': 'Save as...'}, + '更多': {'cn': '更多', 'cn_t': '更多', 'en': 'More'}, + '复制': {'cn': '复制', 'cn_t': '複製', 'en': 'Copy'}, +} + +NEW_FRIEND_ELEMENT = { + '新的朋友': {'cn': '新的朋友', 'cn_t': '新的朋友', 'en': 'New friends'}, + '回复': {'cn': '回复', 'cn_t': '回覆', 'en': 'Reply'}, + '发送': {'cn': '发送', 'cn_t': '發送', 'en': 'Send'}, + '朋友圈': {'cn': '朋友圈', 'cn_t': '朋友圈', 'en': 'Moments'}, + '仅聊天': {'cn': '仅聊天', 'cn_t': '僅聊天', 'en': 'Chat only'}, + '聊天、朋友圈、微信运动等': { + 'cn': '聊天、朋友圈、微信运动等', + 'cn_t': '聊天、朋友圈、微信運動等', + 'en': 'Chats, Moments, WeRun, etc.', + }, + '备注名': {'cn': '备注名', 'cn_t': '備註名', 'en': 'Alias'}, + '标签': {'cn': '标签', 'cn_t': '標籤', 'en': 'Tags'}, +} + +PROFILE_WINDOW = { + '微信号': {'cn': '微信号:', 'cn_t': '微信號:', 'en': 'WeChat ID: '}, + '昵称': {'cn': '昵称:', 'cn_t': '暱稱:', 'en': 'Nickname: '}, + '地区': {'cn': '地区:', 'cn_t': '地區:', 'en': 'Region: '}, + '个性签名': {'cn': '个性签名', 'cn_t': '個性簽名', 'en': 'Signature'}, + '来源': {'cn': '来源', 'cn_t': '來源', 'en': 'Source'}, + '备注': {'cn': '备注', 'cn_t': '備註', 'en': 'Alias'}, + '共同群聊': {'cn': '共同群聊', 'cn_t': '共同群聊', 'en': 'Common groups'}, + '添加到通讯录': {'cn': '添加到通讯录', 'cn_t': '添加到通訊錄', 'en': 'Add to contacts'}, + '更多': {'cn': '更多', 'cn_t': '更多', 'en': 'More'}, +} + +WECHAT_BROWSER = { + '关闭': {'cn': '关闭', 'cn_t': '關閉', 'en': 'Close'}, + '更多': {'cn': '更多', 'cn_t': '更多', 'en': 'More'}, + '地址和搜索栏': {'cn': '地址和搜索栏', 'cn_t': '地址和搜索欄', 'en': 'Address and search bar'}, + '转发给朋友': {'cn': '转发给朋友', 'cn_t': '轉發給朋友', 'en': 'Forward to friend'}, + '复制链接': {'cn': '复制链接', 'cn_t': '複製鏈接', 'en': 'Copy link'}, +} + +CHATROOM_DETAIL_WINDOW = { + '聊天信息': {'cn': '聊天信息', 'cn_t': '聊天信息', 'en': 'Chat info'}, + '查看更多': {'cn': '查看更多', 'cn_t': '查看更多', 'en': 'View more'}, + '群聊名称': {'cn': '群聊名称', 'cn_t': '群聊名稱', 'en': 'Group name'}, + '仅群主或管理员可以修改': {'cn': '仅群主或管理员可以修改', 'cn_t': '僅群主或管理員可以修改', 'en': 'Only owner or admins can edit'}, + '我在本群的昵称': {'cn': '我在本群的昵称', 'cn_t': '我在本群的暱稱', 'en': 'My nickname in group'}, + '仅群主和管理员可编辑': {'cn': '仅群主和管理员可编辑', 'cn_t': '僅群主和管理員可編輯', 'en': 'Only owner and admins can edit'}, + '点击编辑群公告': {'cn': '点击编辑群公告', 'cn_t': '點擊編輯群公告', 'en': 'Tap to edit announcement'}, + '编辑': {'cn': '编辑', 'cn_t': '編輯', 'en': 'Edit'}, + '备注': {'cn': '备注', 'cn_t': '備註', 'en': 'Alias'}, + '群公告': {'cn': '群公告', 'cn_t': '群公告', 'en': 'Announcement'}, + '完成': {'cn': '完成', 'cn_t': '完成', 'en': 'Done'}, + '发布': {'cn': '发布', 'cn_t': '發佈', 'en': 'Publish'}, + '退出群聊': {'cn': '退出群聊', 'cn_t': '退出群聊', 'en': 'Leave group'}, + '聊天成员': {'cn': '聊天成员', 'cn_t': '聊天成員', 'en': 'Members'}, + '添加': {'cn': '添加', 'cn_t': '添加', 'en': 'Add'}, + '移出': {'cn': '移出', 'cn_t': '移出', 'en': 'Remove'}, +} + +ADD_NEW_FRIEND_WINDOW = { + '标签': {'cn': '标签', 'cn_t': '標籤', 'en': 'Tags'}, + '确定': {'cn': '确定', 'cn_t': '確定', 'en': 'OK'}, + '备注名': {'cn': '备注名', 'cn_t': '備註名', 'en': 'Alias'}, + '朋友圈': {'cn': '朋友圈', 'cn_t': '朋友圈', 'en': 'Moments'}, + '仅聊天': {'cn': '仅聊天', 'cn_t': '僅聊天', 'en': 'Chat only'}, + '聊天、朋友圈、微信运动等': { + 'cn': '聊天、朋友圈、微信运动等', + 'cn_t': '聊天、朋友圈、微信運動等', + 'en': 'Chats, Moments, WeRun, etc.', + }, + '你的联系人较多,添加新的朋友时需选择权限': { + 'cn': '你的联系人较多,添加新的朋友时需选择权限', + 'cn_t': '你的聯繫人較多,添加新的朋友時需選擇權限', + 'en': 'You have many contacts, choose permissions when adding friends', + }, + '发送添加朋友申请': {'cn': '发送添加朋友申请', 'cn_t': '發送添加朋友申請', 'en': 'Send friend request'}, +} + +ADD_GROUP_MEMBER_WINDOW = { + '搜索': {'cn': '搜索', 'cn_t': '搜索', 'en': 'Search'}, + '确定': {'cn': '确定', 'cn_t': '確定', 'en': 'OK'}, + '完成': {'cn': '完成', 'cn_t': '完成', 'en': 'Done'}, + '发送': {'cn': '发送', 'cn_t': '發送', 'en': 'Send'}, + '已选择联系人': {'cn': '已选择联系人', 'cn_t': '已選擇聯繫人', 'en': 'Selected contacts'}, + '请勾选需要添加的联系人': { + 'cn': '请勾选需要添加的联系人', + 'cn_t': '請勾選需要添加的聯繫人', + 'en': 'Please select contacts to add', + }, +} diff --git a/wechatauto/logger.py b/wechatauto/logger.py new file mode 100644 index 0000000..cf2cb33 --- /dev/null +++ b/wechatauto/logger.py @@ -0,0 +1,131 @@ +from .param import WxParam + +import logging +import colorama +from pathlib import Path +from datetime import datetime +import sys +import io + + +colorama.init() + +if hasattr(sys.stdout, 'buffer'): + try: + sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='ignore') + except Exception: + pass + +LOG_COLORS = { + 'DEBUG': colorama.Fore.CYAN, + 'INFO': colorama.Fore.GREEN, + 'WARNING': colorama.Fore.YELLOW, + 'ERROR': colorama.Fore.RED, + 'CRITICAL': colorama.Fore.MAGENTA +} + +class ColoredFormatter(logging.Formatter): + def format(self, record): + levelname = record.levelname + message = super().format(record) + return f"{LOG_COLORS[levelname]}{message}{colorama.Style.RESET_ALL}" + +class WechatautoLogger: + name: str = 'wechatauto' + + def __init__(self): + self.logger = self.setup_logger() + self.file_handler = None # 先不创建文件处理器 + self.set_debug(False) + + def setup_logger(self) -> logging.Logger: + """设置日志记录器""" + # 配置根记录器 + root_logger = logging.getLogger() + root_logger.setLevel(logging.DEBUG) + + # 添加asyncio日志过滤 + logging.getLogger('asyncio').setLevel(logging.WARNING) + + # 设置第三方库的日志级别 + logging.getLogger('comtypes').setLevel(logging.WARNING) + logging.getLogger('urllib3').setLevel(logging.WARNING) + logging.getLogger('requests').setLevel(logging.WARNING) + + # 清除现有处理器 + root_logger.handlers.clear() + + # 格式 + fmt = '%(asctime)s [%(name)s] [%(levelname)s] [%(filename)s:%(lineno)d] %(message)s' + + # 控制台处理器(带颜色) + self.console_handler = logging.StreamHandler() + console_formatter = ColoredFormatter( + fmt=fmt, + datefmt="%Y-%m-%d %H:%M:%S" + ) + self.console_handler.setFormatter(console_formatter) + self.console_handler.setLevel(logging.DEBUG) + + root_logger.addHandler(self.console_handler) + + return logging.getLogger(self.name) + + def setup_file_logger(self): + """根据WxParam.ENABLE_FILE_LOGGER决定是否创建文件日志处理器""" + if not WxParam.ENABLE_FILE_LOGGER or self.file_handler is not None: + return + + # 文件处理器(无颜色) + log_dir = Path("wechatauto_logs") + log_dir.mkdir(parents=True, exist_ok=True) + + # 使用当前时间创建日志文件 + current_time = datetime.now().strftime("%Y%m%d") + log_file = log_dir / f"app_{current_time}.log" + + self.file_handler = logging.FileHandler(log_file, encoding='utf-8') + file_formatter = logging.Formatter( + '%(asctime)s [%(name)s] [%(levelname)s] [%(filename)s:%(lineno)d] %(message)s', + datefmt="%Y-%m-%d %H:%M:%S" + ) + self.file_handler.setFormatter(file_formatter) + self.file_handler.setLevel(logging.DEBUG) + + # 将文件处理器添加到日志记录器 + logging.getLogger().addHandler(self.file_handler) + + def set_debug(self, debug=False): + """动态设置日志级别""" + if debug: + self.console_handler.setLevel(logging.DEBUG) + else: + self.console_handler.setLevel(logging.INFO) + + def _ensure_file_logger(self): + """确保文件日志处理器被初始化""" + if WxParam.ENABLE_FILE_LOGGER and self.file_handler is None: + self.setup_file_logger() + + def debug(self, msg: str, *args, stacklevel=2, **kwargs): + self._ensure_file_logger() # 确保文件日志初始化 + self.logger.debug(msg, *args, stacklevel=stacklevel, **kwargs) + + def info(self, msg: str, *args, stacklevel=2, **kwargs): + self._ensure_file_logger() # 确保文件日志初始化 + self.logger.info(msg, *args, stacklevel=stacklevel, **kwargs) + + def warning(self, msg: str, *args, stacklevel=2, **kwargs): + self._ensure_file_logger() # 确保文件日志初始化 + self.logger.warning(msg, *args, stacklevel=stacklevel, **kwargs) + + def error(self, msg: str, *args, stacklevel=2, **kwargs): + self._ensure_file_logger() # 确保文件日志初始化 + self.logger.error(msg, *args, stacklevel=stacklevel, **kwargs) + + def critical(self, msg: str, *args, stacklevel=2, **kwargs): + self._ensure_file_logger() # 确保文件日志初始化 + self.logger.critical(msg, *args, stacklevel=stacklevel, **kwargs) + +# wxlog实例化的地方不再创建文件日志 +wxlog = WechatautoLogger() diff --git a/wechatauto/media.py b/wechatauto/media.py new file mode 100644 index 0000000..5a2178d --- /dev/null +++ b/wechatauto/media.py @@ -0,0 +1,664 @@ +# -*- coding: utf-8 -*- +"""微信 4.x 媒体文件读取与下载(图片解密、语音、视频、文件)。 + +与 :mod:`wechatauto.db` 配合使用:``db`` 提供解密后的消息行(含 local_type、 +server_id、packed_info),本模块负责把媒体内容从本地取回/解密/落地。 + +支持的媒体(local_type 见 :data:`wechatauto.db.MSG_TYPE_NAMES`):: + + local_type 3 图片 → 会话目录 msg/attach/<会话md5>//Img/.dat + local_type 34 语音 → message/media_0.db VoiceInfo.voice_data(SILK 二进制) + local_type 43 视频 → msg/video//.mp4(未落地时返回 None) + local_type 49 文件 → msg/file//<原文件名>,原名取自 + message_resource.db MessageResourceDetail.packed_info + +图片加密(v2 格式,本库已在本机验证):: + + 结构: [6B sig 07 08 56 32 08 07][4B aes_size LE][4B xor_size LE][1B pad] + [aes 密文(ECB, PKCS7, 对齐 16B)][raw 明文][xor 密文] + + - AES 密钥: 16 字节 ASCII(字母/数字),仅在 Weixin.exe 进程内存中。 + 通过 AES-ECB 解首块密文、校验 JPEG/PNG 魔数反推出(内存正则扫描)。 + - XOR 密钥: 单字节,从同图缩略图 ``_t.dat`` 尾部 JPEG 结束标记 + ``FF D9`` 反推(``key = tail[0] ^ 0xFF``)。 + +用法:: + + from wechatauto import WeChatDB, MediaDownloader + db = WeChatDB() + md = MediaDownloader(db) + md.download_media(chat_user, msg_row["local_id"]) # 按类型自动分发 +""" + +from __future__ import annotations + +import ctypes +import glob +import hashlib +import json +import os +import re +import struct +import tempfile +import time +from typing import List, Optional, Tuple + +V1_MAGIC = b"\x07\x08\x05\x56\x02\x05" +V2_MAGIC = b"\x07\x08\x56\x32\x08\x07" +V1_HEADER_SZ = 22 # 6B sig + 16B xor key +AES16_RE = re.compile(rb"[0-9a-zA-Z]{16,32}") +DEFAULT_SAVE_PATH = os.path.join(os.path.expanduser("~"), "Documents", "wechatauto_media") + + +def _jpeg_like(pt: bytes) -> bool: + return ( + (pt[:3] == b"\xff\xd8\xff") + or pt[:4] in (b"\x89PNG", b"GIF8", b"RIFF") + or pt[:4] == b"wxgf" # 微信动画表情容器 + ) + + +def aligned_aes_block_size(aes_size: int) -> int: + return aes_size + (16 - aes_size % 16) if aes_size % 16 else aes_size + 16 + + +class MediaDownloader: + """微信 4.x 媒体下载器""" + + def __init__(self, db, save_dir: Optional[str] = None, + image_key: Optional[str] = None, + cfg_dword: Optional[int] = None): + self.db = db + self.save_dir = save_dir or DEFAULT_SAVE_PATH + self._image_key = image_key # 显式注入的图片 AES 密钥 + self._cfg_dword = cfg_dword # cfg+0x40, 派生图片密钥(最佳方案) + self._xor_key: Optional[int] = None + self._img_key: Optional[Tuple[str, int]] = None + self._key_probe: Optional[bytes] = None + + @staticmethod + def derive_image_keys(cfg_dword: int, wxid: str) -> Tuple[str, int]: + """cfgDword 派生图片密钥(微信 4.x 最佳方案, 实测 3000/3000 验证)。 + + imageXorKey = cfgDword & 0xFF + imageAesKey = MD5(str(cfgDword) + wxid)[:16] # 前 16 位即真 AES-128 密钥 + """ + xor_key = cfg_dword & 0xFF + aes_key = hashlib.md5( + ("%d" % cfg_dword + wxid).encode("utf-8")).hexdigest()[:16] + return aes_key, xor_key + + def _derive_cfg_key(self) -> Optional[Tuple[str, int]]: + """cfgDword 派生并验证; 优先显式注入, 否则用 db.cfg_dword(自动提取)。""" + cfg_dword = self._cfg_dword + if cfg_dword is None: + cfg_dword = getattr(self.db, "cfg_dword", None) + if not cfg_dword: + return None + aes_key, xor_key = self.derive_image_keys(cfg_dword, self.db.wxid) + if self._validate_key(aes_key): + return aes_key, xor_key + return None + + # ------------------------------------------------------------------ + # 图片密钥(内存扫描 + 缩略图反推) + # ------------------------------------------------------------------ + def _probe_ct(self, dat_path: Optional[str] = None) -> bytes: + """取一张 V2 图片的密文首块,作为密钥反测试样""" + if self._key_probe is not None: + return self._key_probe + if dat_path is None: + base = os.path.join(self.db.account_dir, "msg", "attach") + hits = glob.glob(os.path.join(base, "*", "*", "Img", "*.dat")) + if not hits: + return b"" + dat_path = hits[0] + with open(dat_path, "rb") as f: + head = f.read(32) + if head[:6] == V2_MAGIC: + self._key_probe = head[15:31] + else: + self._key_probe = head[V1_HEADER_SZ: V1_HEADER_SZ + 16] + return self._key_probe + + def _validate_key(self, aes_key: str) -> bool: + """用真实密文首块反测密钥是否有效""" + probe = self._probe_ct() + if not probe: + return False + try: + from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes + dec = Cipher(algorithms.AES(aes_key.encode()), modes.ECB()).decryptor() + return _jpeg_like(dec.update(probe) + dec.finalize()) + except Exception: + return False + + def _key_store(self) -> str: + return os.path.join(self.db.workdir, "image_keys.json") + + def _load_persisted_key(self) -> Optional[str]: + try: + with open(self._key_store(), "r", encoding="utf-8") as f: + saved = json.load(f) + key = saved.get(self.db.account) + except (OSError, ValueError, json.JSONDecodeError): + return None + if key and self._validate_key(key): + return key + return None + + def _persist_key(self, aes_key: str) -> None: + try: + with open(self._key_store(), "r", encoding="utf-8") as f: + saved = json.load(f) + except (OSError, ValueError, json.JSONDecodeError): + saved = {} + saved[self.db.account] = aes_key + try: + os.makedirs(os.path.dirname(self._key_store()), exist_ok=True) + with open(self._key_store(), "w", encoding="utf-8") as f: + json.dump(saved, f, indent=2) + except OSError: + pass + + def _collect_templates(self, limit: int = 32, keep: int = 16) -> List[str]: + """递归收集 *_t.dat 缩略图模板: 按修改时间降序取前 keep 个""" + base = os.path.join(self.db.account_dir, "msg", "attach") + hits = glob.glob(os.path.join(base, "*", "*", "Img", "*_t.dat")) + hits.sort(key=os.path.getmtime, reverse=True) + return hits[:keep] + + def _get_xor_key(self, templates: List[str]) -> Optional[int]: + """文件尾统计推 XOR 密钥: 缩略图明文为 JPEG, 尾部固定 FF D9。 + + 读每个模板最后 2 字节 (x, y), 统计出现最多的组合; + xorKey = x ^ 0xFF 且校验 y ^ 0xD9 == xorKey 才返回。 + """ + tails: Dict[Tuple[int, int], int] = {} + for p in templates: + try: + with open(p, "rb") as f: + f.seek(-2, 2) + tail = f.read(2) + except OSError: + continue + if len(tail) == 2: + tails[(tail[0], tail[1])] = tails.get((tail[0], tail[1]), 0) + 1 + for (x, y), _ in sorted(tails.items(), key=lambda kv: -kv[1]): + key = x ^ 0xFF + if y ^ 0xD9 == key: + return key + return None + + def _derive_xor_key(self, dat_path: str) -> Optional[int]: + """从单个 .dat 文件尾部反推 XOR 密钥(JPEG 尾 FF D9 被 XOR 加密)。 + + key = tail[0] ^ 0xFF,并校验 tail[1] ^ 0xD9 == key。 + """ + try: + with open(dat_path, "rb") as f: + f.seek(-2, 2) + tail = f.read(2) + except OSError: + return None + if len(tail) == 2: + key = tail[0] ^ 0xFF + if tail[1] ^ 0xD9 == key: + return key + return None + + def _dbg_last_dat(self) -> Optional[str]: + """返回最近修改的一张 .dat 图片缓存文件路径(用于 XOR 密钥兜底推导)。""" + base = os.path.join(self.db.account_dir, "msg", "attach") + hits = glob.glob(os.path.join(base, "*", "*", "Img", "*.dat")) + if not hits: + return None + hits.sort(key=os.path.getmtime, reverse=True) + return hits[0] + + def _scan_aes_key(self, monitor: bool = False, + monitor_timeout: float = 120.0) -> Optional[str]: + """扫描 Weixin.exe 内存穷举候选密钥, AES-ECB 解密探针验证。 + + 候选两类模式(YARA 思路): + - ASCII: 非字母数字 + 连续 32 个 [a-zA-Z0-9] + 非字母数字结尾, + 每候选取前 16 字节作 AES-128 key 解密探针, 明文为 JPEG SOI 命中; + - UTF-16LE: 字母数字与 0x00 交错形式。 + """ + probe = self._probe_ct() + if not probe: + return None + pids = self.db._find_weixin_pids() + if not pids: + return None + from . import db as _dbmod + k32 = _dbmod._k32 + MBI = _dbmod._MBI + + ASCII32_RE = re.compile(rb"[^a-zA-Z0-9]([a-zA-Z0-9]{32})[^a-zA-Z0-9]") + U16_RE = re.compile(rb"(?:[a-zA-Z0-9]\x00){32}") + + def read_mem(h, addr: int, n: int): + buf = ctypes.create_string_buffer(n) + br = ctypes.c_size_t(0) + if k32.ReadProcessMemory(h, ctypes.c_void_p(addr), buf, n, ctypes.byref(br)) and br.value: + return buf.raw[: br.value] + return None + + def _try_key(key16: bytes) -> bool: + try: + from cryptography.hazmat.primitives.ciphers import ( + Cipher, algorithms, modes, + ) + pt = Cipher(algorithms.AES(key16), modes.ECB()).decryptor() + out = pt.update(probe) + pt.finalize() + except Exception: + return False + return out[:3] == b"\xff\xd8\xff" or _jpeg_like(out) + + def _candidates(buf: bytes): + for m in ASCII32_RE.finditer(buf): + yield m.group(1)[:16].encode() if isinstance(m.group(1), str) else m.group(1)[:16] + for m in U16_RE.finditer(buf): + yield bytes(b for i, b in enumerate(m.group()) if i % 2 == 0)[:16] + + def _scan_once() -> Optional[str]: + # 保持微信进程原顺序扫描(主进程靠前, 命中率高) + for pid in pids: + h = k32.OpenProcess(0x0010 | 0x0400, False, pid) + if not h: + continue + try: + addr = 0 + while True: + mbi = MBI() + r = k32.VirtualQueryEx(h, ctypes.c_void_p(addr), ctypes.byref(mbi), ctypes.sizeof(mbi)) + if r == 0: + break + if ( + mbi.State == 0x1000 + and (mbi.Protect & 0xFF) & 0xE6 + and not (mbi.Protect & 0x100) + and 0 < mbi.RegionSize < 0x2000000 + ): + buf = read_mem(h, mbi.BaseAddress or 0, mbi.RegionSize) + if buf: + for key in _candidates(buf): + if _try_key(key): + return key.decode("ascii", "replace") + addr = (mbi.BaseAddress or 0) + mbi.RegionSize + finally: + k32.CloseHandle(h) + return None + + found = _scan_once() + if found or not monitor: + return found + + print( + "未在微信进程内存中找到图片 AES 密钥。\n" + "请现在打开微信,进入任意聊天,点击一张图片查看大图,\n" + f"本程序将在 {monitor_timeout:.0f} 秒内自动捕获密钥..." + ) + start = time.time() + while time.time() - start < monitor_timeout: + time.sleep(2.0) + found = _scan_once() + if found: + return found + return None + + def detect_image_key(self, refresh: bool = False) -> Optional[Tuple[str, int]]: + """返回 (AES 密钥, XOR 密钥);失败返回 None。结果缓存,refresh=True 强制重扫。 + + 总流程: + 定位缓存目录 → 收集 *_t.dat 模板 → 文件尾推 XOR 密钥(众数统计) + → 文件头取 AES 密文 → cfgDword 派生 / 扫描 Weixin.exe 内存穷举 + 候选密钥 → AES-ECB 解密验证(JPEG SOI)。 + + 密钥来源优先级:cfgDword 派生(确定性离线, 免看图驻留) → 显式注入 + image_key → 本地缓存 → 进程内存扫描。命中后持久化, 下次免扫。 + """ + if self._img_key and not refresh: + return self._img_key + probe = self._probe_ct() + if not probe: + return None + templates = self._collect_templates() + # 1) XOR: 模板文件尾众数统计 + xor_key = self._get_xor_key(templates) + if xor_key is None: + dat = self._dbg_last_dat() + xor_key = self._derive_xor_key(dat) if dat else 0x88 + # 2) AES: cfgDword 派生优先 + derived = self._derive_cfg_key() + if derived: + self._img_key = (derived[0], xor_key) + return self._img_key + aes_key = None + if self._image_key and self._validate_key(self._image_key): + aes_key = self._image_key + if not aes_key: + aes_key = self._load_persisted_key() + if not aes_key: + aes_key = self._scan_aes_key(monitor=True) + if aes_key: + self._persist_key(aes_key) + if not aes_key: + return None + self._img_key = (aes_key, xor_key) + return self._img_key + + # ------------------------------------------------------------------ + # 图片解密 + # ------------------------------------------------------------------ + def decrypt_image(self, dat_path: str, aes_key: Optional[str] = None, + xor_key: Optional[int] = None) -> bytes: + """解密单个 .dat 为图片字节(自动识别 v1/v2 格式)""" + with open(dat_path, "rb") as f: + data = f.read() + if not data: + raise ValueError("空文件: %s" % dat_path) + magic = data[:6] + if magic == V2_MAGIC: + return self._decrypt_v2(data, dat_path, aes_key, xor_key) + if magic == V1_MAGIC: + if xor_key is None: + xor_key = self._derive_xor_key(dat_path) + key = data[6:22] + body = data[22:] + return bytes(b ^ (xor_key & 0xFF) for b in body) + # 早期纯异或格式:逐字节 ^ 0xFF(无签名),按 JPEG/PNG 魔数回退判断 + for cand in (0x88, 0x30, 0xFF, 0xE9): + out = bytes(b ^ cand for b in data) + if out[:3] == b"\xff\xd8\xff" or out[:4] == b"\x89PNG": + return out + raise ValueError("无法识别的图片加密格式: %s" % dat_path) + + def _resolve_aes_key(self) -> Optional[str]: + """统一密钥解析:显式注入 → 本地缓存 → 内存扫描""" + if self._image_key and self._validate_key(self._image_key): + return self._image_key + cached = self._load_persisted_key() + if cached: + return cached + key = self._scan_aes_key(monitor=True) + if key: + self._persist_key(key) + return key + + def _decrypt_v2(self, data: bytes, dat_path: str, + aes_key: Optional[str], xor_key: Optional[int]) -> bytes: + from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes + + aes_size, xor_size = struct.unpack_from(" str: + import hashlib + return hashlib.md5(user.encode()).hexdigest() + + def _month_of(self, create_time: int) -> str: + return time.strftime("%Y-%m", time.localtime(create_time)) + + def _find_dat(self, user: str, md5: str, create_time: int, + thumbnail: bool = False) -> Optional[str]: + base = os.path.join(self.db.account_dir, "msg", "attach", self._chat_md5(user)) + target = md5 + ("_t.dat" if thumbnail else ".dat") + for root, _, files in os.walk(base): + for f in files: + if f == target: + return os.path.join(root, f) + return None + + # ------------------------------------------------------------------ + # 各类媒体下载 + # ------------------------------------------------------------------ + def _out(self, save_dir: Optional[str], name: str) -> str: + d = save_dir or self.save_dir + os.makedirs(d, exist_ok=True) + return os.path.join(d, name) + + # ------------------------------------------------------------------ + # WXAM (wxgf) 解码:微信 4.x 普通图片的新存储格式,内部为 HEVC 裸流 + # ------------------------------------------------------------------ + def _extract_hevc(self, data: bytes) -> Optional[bytes]: + """从 wxgf 容器提取 HEVC Annex-B 裸流(自首个 NALU 起始码起)。""" + start = data.find(b"\x00\x00\x00\x01") + return data[start:] if start >= 0 else None + + @staticmethod + def _ffmpeg_exe() -> Optional[str]: + import shutil + exe = shutil.which("ffmpeg") + if exe: + return exe + try: + import imageio_ffmpeg + return imageio_ffmpeg.get_ffmpeg_exe() + except Exception: + return None + + def _wxgf_to_jpg(self, data: bytes) -> Optional[bytes]: + """用 ffmpeg 把 wxgf 内的 HEVC 裸流转码为 jpg。失败返回 None。""" + exe = self._ffmpeg_exe() + if exe is None: + return None + hevc = self._extract_hevc(data) + if not hevc: + return None + import subprocess + import tempfile + with tempfile.TemporaryDirectory() as td: + src = os.path.join(td, "in.hevc") + dst = os.path.join(td, "out.jpg") + with open(src, "wb") as f: + f.write(hevc) + try: + r = subprocess.run( + [exe, "-y", "-v", "error", "-i", src, "-frames:v", "1", dst], + capture_output=True, timeout=30, + ) + except Exception: + return None + if r.returncode == 0: + try: + with open(dst, "rb") as f: + out = f.read() + return out if out[:3] == b"\xff\xd8\xff" else None + except OSError: + return None + return None + + def _img_md5(self, row: dict) -> Optional[str]: + pi = row.get("packed_info") + content = row.get("content") + for blob in (pi, content): + if isinstance(blob, bytes): + m = re.search(rb"([0-9a-fA-F]{32})", blob) + if m: + return m.group(1).decode().lower() + return None + + def download_image(self, user: str, local_id: int, save_dir: Optional[str] = None, + aes_key: Optional[str] = None, xor_key: Optional[int] = None) -> Optional[str]: + """下载图片消息并解密为 jpg/png/gif,返回落盘路径""" + row = self.db.get_message_row(user, local_id) + if not row or row["local_type"] != 3: + return None + md5 = self._img_md5(row) + if not md5: + return None + dat_path = self._find_dat(user, md5, row["create_time"]) + thumb = False + if not dat_path: + # 群聊图片默认只有缩略图(原图未在微信中点开查看时不下发),回退缩略图 + dat_path = self._find_dat(user, md5, row["create_time"], thumbnail=True) + if not dat_path: + return None + thumb = True + data = self.decrypt_image(dat_path, aes_key, xor_key) + suffix = "_thumb" if thumb else "" + if data[:3] == b"\xff\xd8\xff": + ext = "jpg" + elif data[:4] == b"\x89PNG": + ext = "png" + elif data[:3] == b"GIF": + ext = "gif" + elif data[:4] == b"wxgf": + # WXAM 格式:微信 4.x 普通图片也用 HEVC 编码存储(含动画表情)。 + # 优先用 ffmpeg 转码为 jpg;不可用时把原始解密数据落盘为 .wxgf 兜底。 + jpg = self._wxgf_to_jpg(data) + if jpg is not None: + out = self._out(save_dir, "%s_%s%s.%s" % (user, local_id, suffix, "jpg")) + with open(out, "wb") as f: + f.write(jpg) + return out + out = self._out(save_dir, "%s_%s%s.wxgf" % (user, local_id, suffix)) + with open(out, "wb") as f: + f.write(data) + return out + else: + ext = "img" + out = self._out(save_dir, "%s_%s%s.%s" % (user, local_id, suffix, ext)) + with open(out, "wb") as f: + f.write(data) + return out + + def download_voice(self, user: str, local_id: int, save_dir: Optional[str] = None) -> Optional[str]: + """语音:media_*.db VoiceInfo.voice_data(SILK 二进制),落盘 .silk + + 微信按账号/时间把语音分片存到多个 media_*.db,逐个搜索直到找到。 + """ + row = self.db.get_message_row(user, local_id) + if not row or row["local_type"] != 34 or not row["server_id"]: + return None + for rel, path, _ in self.db._db_files: + if not os.path.basename(path).startswith("media_"): + continue + conn = self.db._open(rel) + try: + cid = conn.execute( + "SELECT rowid FROM Name2Id WHERE user_name=?", (user,) + ).fetchone() + chat_id = cid[0] if cid else None + if chat_id is None: + continue + v = conn.execute( + "SELECT voice_data FROM VoiceInfo WHERE chat_name_id=? AND svr_id=? " + "ORDER BY create_time DESC LIMIT 1", + (chat_id, row["server_id"]), + ).fetchone() + finally: + conn.close() + if v and v["voice_data"]: + out = self._out(save_dir, "%s_%s.silk" % (user, local_id)) + with open(out, "wb") as f: + f.write(v["voice_data"]) + return out + return None + + def download_video(self, user: str, local_id: int, save_dir: Optional[str] = None) -> Optional[str]: + """视频:按 packed_info 中的 id 在 msg/video 下查找 .mp4""" + row = self.db.get_message_row(user, local_id) + if not row or row["local_type"] != 43: + return None + pi = row.get("packed_info") + if not isinstance(pi, bytes): + return None + m = re.search(rb"([0-9a-fA-F]{32})", pi) + vid = m.group(1).decode().lower() if m else None + base = os.path.join(self.db.account_dir, "msg", "video") + for root, _, files in os.walk(base): + for f in files: + if vid and f == vid + ".mp4": + out = self._out(save_dir, "%s_%s.mp4" % (user, local_id)) + with open(out, "wb") as w: + with open(os.path.join(root, f), "rb") as r: + w.write(r.read()) + return out + return None + + def _file_name(self, row: dict) -> Optional[str]: + if not row["server_id"]: + return None + for rel, path, _ in self.db._db_files: + if os.path.basename(path) != "message_resource.db": + continue + conn = self.db._open(rel) + try: + r = conn.execute( + "SELECT d.packed_info FROM MessageResourceDetail d " + "LEFT JOIN MessageResourceInfo i ON d.message_id=i.message_id " + "WHERE i.message_svr_id=? LIMIT 1", + (row["server_id"],), + ).fetchone() + finally: + conn.close() + if r and r["packed_info"]: + name = r["packed_info"].decode("utf-8", "replace").strip() + name = re.sub(r"[\r\n\x00]+", "", name) + if "/" in name or "\\" in name: + name = name.split("/")[-1].split("\\")[-1] + return name or None + break + return None + + def download_file(self, user: str, local_id: int, save_dir: Optional[str] = None) -> Optional[str]: + """文件:msg/file//<原文件名>,原文件名来自 message_resource""" + row = self.db.get_message_row(user, local_id) + if not row or row["local_type"] != 49: + return None + name = self._file_name(row) + if not name: + return None + base = os.path.join(self.db.account_dir, "msg", "file") + for root, _, files in os.walk(base): + for f in files: + if f == name: + out = self._out(save_dir, "%s_%s_%s" % (user, local_id, name)) + with open(out, "wb") as w: + with open(os.path.join(root, f), "rb") as r: + w.write(r.read()) + return out + return None + + def download_media(self, user: str, local_id: int, save_dir: Optional[str] = None) -> Optional[str]: + """按消息类型自动分发:3 图片 / 34 语音 / 43 视频 / 49 文件""" + row = self.db.get_message_row(user, local_id) + if not row: + return None + t = row["local_type"] + if t == 3: + return self.download_image(user, local_id, save_dir) + if t == 34: + return self.download_voice(user, local_id, save_dir) + if t == 43: + return self.download_video(user, local_id, save_dir) + if t == 49: + return self.download_file(user, local_id, save_dir) + return None diff --git a/wechatauto/moment.py b/wechatauto/moment.py new file mode 100644 index 0000000..26f9280 --- /dev/null +++ b/wechatauto/moment.py @@ -0,0 +1,811 @@ +"""朋友圈(Moments)相关接口实现。 + +本模块提供两类接口: + +- :class:`Moment`(UIA 路线,老架构):微信 4.x 自绘界面已不暴露 + UIA 节点,此路线在 4.x 上不可用,仅保留兼容; +- :class:`MomentDB`(数据库路线,4.x 推荐):直接读取微信本地 + ``sns.db`` 的 ``SnsTimeLine`` 表,内容为 ``SnsDataItem`` XML, + 可稳定获取全部朋友圈(含正文、图片/视频 md5、点赞、评论、定位)。 + +注:**发朋友圈(PublishMoments)功能已舍弃**——4.x 的发表为自绘 +界面操作,无法可靠自动化;本模块仅保留朋友圈读取/点赞/评论能力。 +""" + +from __future__ import annotations + +import html +import os +import re +import time +from dataclasses import dataclass +from typing import Dict, Iterable, List, Optional, Union + +from wechatauto import uia +from wechatauto.languages import MOMENTS, get_lang +from wechatauto.logger import wxlog +from wechatauto.param import WxParam, WxResponse +from wechatauto.ui.base import BaseUISubWnd +from wechatauto.utils.tools import find_all_windows_from_root +from wechatauto.utils.win32 import SetClipboardText + + +def _lang(table, key: str) -> str: + """根据当前语言环境返回对应文案。""" + return get_lang(table, key) + + +def _is_time_line(text: str) -> bool: + """粗略判断一行文本是否为时间信息。""" + + if not text: + return False + patterns = [ + r"\d{4}年\d{1,2}月\d{1,2}日", + r"\d{2}-\d{2}", + r"\d{1,2}:\d{2}", + r"昨[天日]", + r"星期[一二三四五六日天]", + ] + return any(re.search(pattern, text) for pattern in patterns) + + +def _split_like_names(text: str) -> List[str]: + """解析点赞字符串。""" + + if not text: + return [] + + like_prefix = _lang(MOMENTS, '赞') + text = text.strip() + if text.startswith(like_prefix): + text = text[len(like_prefix):].lstrip(':: ') + + sep = _lang(MOMENTS, '分隔符_点赞') + if sep: + parts = [part.strip() for part in text.split(sep) if part.strip()] + else: + parts = [name.strip() for name in re.split(r'[,:,]', text) if name.strip()] + return parts + + +@dataclass +class MomentComment: + """朋友圈评论数据结构。""" + + author: str + content: str + reply_to: Optional[str] = None + raw: str = '' + + @classmethod + def from_text(cls, text: str) -> 'MomentComment': + text = text.strip() + reply_to = None + author = '' + content = text + + # 格式示例:"张三 回复 李四:你好" 或 "张三: 哈喽" + match = re.match(r'^(?P[^::]+?)\s*(?:回复\s*(?P[^::]+?)\s*)?[::](?P.*)$', text) + if match: + author = match.group('author').strip() + reply_to = match.group('reply') + if reply_to: + reply_to = reply_to.strip() + content = match.group('content').strip() + else: + author = '' + content = text.strip() + + return cls(author=author, content=content, reply_to=reply_to, raw=text) + + +class MomentItem(BaseUISubWnd): + """朋友圈单条动态。""" + + def __init__(self, control: uia.Control, parent: 'MomentList'): + self.control = control + self.parent = parent + self.root = parent.root + self._parsed = False + self.nickname: str = '' + self.content: str = '' + self.location: Optional[str] = None + self.time: str = '' + self.likes: List[str] = [] + self.comments: List[MomentComment] = [] + self.image_count: int = 0 + self.is_advertisement: bool = False + self._comment_controls: Dict[str, uia.Control] = {} + + # ---------------------------------------------------------------------------------------------- + # 数据解析 + # ---------------------------------------------------------------------------------------------- + + def _ensure_parsed(self) -> None: + if self._parsed: + return + + raw_text = self.control.Name or '' + lines = [line.strip() for line in raw_text.splitlines() if line.strip()] + + if lines: + self.nickname = lines[0] + + body_lines = lines[1:] + content_lines: List[str] = [] + comment_lines: List[str] = [] + likes_line: Optional[str] = None + + for line in body_lines: + if not line: + continue + + if re.search(_lang(MOMENTS, 're_图片数'), line): + count = re.findall(r'\d+', line) + if count: + self.image_count = int(count[0]) + continue + + if line.startswith(_lang(MOMENTS, '赞')): + likes_line = line + continue + + if line == _lang(MOMENTS, '评论'): + # 后续均为评论 + comment_lines.extend(body_lines[body_lines.index(line) + 1:]) + break + + if _lang(MOMENTS, '广告') in line: + self.is_advertisement = True + continue + + if not self.time and _is_time_line(line): + self.time = line + continue + + content_lines.append(line) + + # 若未在循环中捕获评论,则继续检查剩余行 + if not comment_lines: + collecting = False + for line in body_lines: + if line == _lang(MOMENTS, '评论'): + collecting = True + continue + if collecting: + comment_lines.append(line) + + if likes_line: + self.likes = _split_like_names(likes_line) + + self.content = '\n'.join(content_lines).strip() + self.comments = [MomentComment.from_text(line) for line in comment_lines if line.strip()] + + # 记录可用于回复的控件 + for child in self.control.GetChildren(): + if child.ControlTypeName == 'TextControl': + text = (child.Name or '').strip() + if text: + self._comment_controls.setdefault(text, child) + + self._parsed = True + + # ---------------------------------------------------------------------------------------------- + # 对外属性访问 + # ---------------------------------------------------------------------------------------------- + + @property + def publisher(self) -> str: + self._ensure_parsed() + return self.nickname + + @property + def text(self) -> str: + self._ensure_parsed() + return self.content + + @property + def timestamp(self) -> str: + self._ensure_parsed() + return self.time + + @property + def like_users(self) -> List[str]: + self._ensure_parsed() + return list(self.likes) + + @property + def comment_list(self) -> List[MomentComment]: + self._ensure_parsed() + return list(self.comments) + + # ---------------------------------------------------------------------------------------------- + # 工具方法 + # ---------------------------------------------------------------------------------------------- + + def find_comment(self, author: str) -> Optional[MomentComment]: + self._ensure_parsed() + for comment in self.comments: + if comment.author == author: + return comment + return None + + def get_comment_control(self, comment: MomentComment) -> Optional[uia.Control]: + self._ensure_parsed() + key_candidates = [comment.raw, f"{comment.author}: {comment.content}", f"{comment.author}:{comment.content}"] + for key in key_candidates: + if key and key in self._comment_controls: + return self._comment_controls[key] + # fallback: 遍历匹配 + for text, ctrl in self._comment_controls.items(): + if comment.author and text.startswith(comment.author): + if comment.content in text: + return ctrl + return None + + +class MomentList(BaseUISubWnd): + """朋友圈时间线列表。""" + + def __init__(self, parent: 'Moment'): + self.parent = parent + self.root = parent.root + self.control = self._locate_list(parent) + self._items: Optional[List[MomentItem]] = None + + def _locate_list(self, parent: 'Moment') -> Optional[uia.Control]: + wxlog.debug('尝试定位朋友圈列表控件') + # 首先尝试通过常用 className 定位 + candidates: Iterable[uia.Control] = [] + try: + candidates = parent._api.control.GetChildren() + except Exception: + candidates = [] + + queue = list(candidates) + visited = set() + + while queue: + ctrl = queue.pop(0) + if ctrl in visited: + continue + visited.add(ctrl) + + class_name = getattr(ctrl, 'ClassName', '') or '' + automation_id = getattr(ctrl, 'AutomationId', '') or '' + if ctrl.ControlTypeName == 'ListControl' and ('Moment' in class_name or 'moment' in automation_id.lower()): + wxlog.debug(f'找到疑似朋友圈列表控件:{class_name}') + return ctrl + + # 朋友圈列表一般会包含"评论"按钮 + children = [] + try: + children = ctrl.GetChildren() + except Exception: + children = [] + + if ctrl.ControlTypeName == 'ListControl': + for child in children: + try: + if getattr(child, 'Name', '') == _lang(MOMENTS, '评论'): + wxlog.debug('通过子元素匹配到朋友圈列表控件') + return ctrl + except Exception: + continue + + queue.extend(children) + + wxlog.debug('未能定位到朋友圈列表控件') + return None + + def exists(self, wait: float = 0) -> bool: # type: ignore[override] + if not self.control: + return False + try: + return self.control.Exists(wait) + except Exception: + return False + + def refresh(self) -> None: + self._items = None + + def get_items(self, refresh: bool = False) -> List[MomentItem]: + if refresh or self._items is None: + self._items = [] + if not self.control: + return self._items + + try: + children = self.control.GetChildren() + except Exception: + children = [] + + for child in children: + try: + if child.ControlTypeName in {'ListItemControl', 'CustomControl'}: + text = getattr(child, 'Name', '') or '' + if text.strip(): + self._items.append(MomentItem(child, self)) + except Exception: + continue + return list(self._items) + + +class Moment: + """朋友圈接口封装。""" + + def __init__(self, wx_obj): + self._wx = wx_obj + self._api = wx_obj._api + self.root = wx_obj._api + self._list: Optional[MomentList] = None + + # ------------------------------------------------------------------------------------------ + # 内部工具 + # ------------------------------------------------------------------------------------------ + + def _ensure_list(self) -> Optional[MomentList]: + if self._list and self._list.exists(0): + return self._list + + try: + self._wx.SwitchToMoments() + time.sleep(0.2) + except Exception: + wxlog.debug('切换到朋友圈页面失败') + return None + + self._list = MomentList(self) + if not self._list.control: + return None + return self._list + + # ------------------------------------------------------------------------------------------ + # 对外接口 + # ------------------------------------------------------------------------------------------ + + def GetMoments(self, refresh: bool = False) -> List[MomentItem]: + """获取朋友圈动态列表。 + + Args: + refresh: 是否强制刷新控件缓存。 + + Returns: + List[MomentItem]: 朋友圈动态对象列表。 + """ + + moment_list = self._ensure_list() + if not moment_list: + return [] + return moment_list.get_items(refresh) + + def FindMomentByPublisher(self, nickname: str, refresh: bool = False) -> Optional[MomentItem]: + """根据发布者昵称查找朋友圈动态。""" + + nickname = nickname.strip() + for item in self.GetMoments(refresh=refresh): + if item.publisher == nickname: + return item + return None + + # ------------------------------------------------------------------------------------------ + # 点赞与评论(部分功能依赖 UI 结构,尽量保证稳健) + # ------------------------------------------------------------------------------------------ + + def _invoke_action_menu(self, item: MomentItem) -> Optional['MomentActionMenu']: + action_button = None + try: + for child in item.control.GetChildren(): + if child.ControlTypeName == 'ButtonControl': + action_button = child + break + except Exception: + action_button = None + + if action_button: + action_button.Click() + else: + try: + item.control.RightClick() + except Exception: + return None + + menu = MomentActionMenu(item) + if not menu.exists(0.5): + return None + return menu + + def Like(self, item: MomentItem, cancel: bool = False) -> WxResponse: + menu = self._invoke_action_menu(item) + if not menu: + return WxResponse.failure('未能打开朋友圈操作菜单') + try: + return menu.like(cancel) + finally: + menu.close() + + def Comment(self, item: MomentItem, content: str, reply_to: Optional[str] = None) -> WxResponse: + if reply_to: + comment = item.find_comment(reply_to) + if not comment: + return WxResponse.failure('未找到需要回复的评论') + ctrl = item.get_comment_control(comment) + if not ctrl: + return WxResponse.failure('未定位到评论控件') + ctrl.Click() + else: + menu = self._invoke_action_menu(item) + if not menu: + return WxResponse.failure('未能打开朋友圈操作菜单') + try: + result = menu.comment() + finally: + menu.close() + if not result: + return result + + dialog = MomentCommentDialog(self) + if not dialog.exists(0.5): + return WxResponse.failure('未弹出评论窗口') + return dialog.send(content) + + +class MomentActionMenu(BaseUISubWnd): + """朋友圈点赞/评论菜单。""" + + _win_cls_name: str = 'Qt51514QWindowToolSaveBits' + + def __init__(self, parent: MomentItem, timeout: float = 1.0): + self.parent = parent + self.root = parent.root + self.control = self._locate(timeout) + + def _locate(self, timeout: float) -> Optional[uia.Control]: + t0 = time.time() + while time.time() - t0 <= timeout: + wins = find_all_windows_from_root(classname=self._win_cls_name, pid=self.root.pid) + for win in wins: + try: + children = win.GetChildren() + except Exception: + children = [] + for child in children: + name = getattr(child, 'Name', '') + if name in {_lang(MOMENTS, '赞'), _lang(MOMENTS, '取消'), _lang(MOMENTS, '评论')}: + return win + time.sleep(0.05) + return None + + def exists(self, wait: float = 0) -> bool: # type: ignore[override] + if not self.control: + return False + try: + return self.control.Exists(wait) + except Exception: + return False + + def _find_button(self, names: Iterable[str]) -> Optional[uia.Control]: + if not self.control: + return None + target_names = list(names) + try: + children = self.control.GetChildren() + except Exception: + children = [] + for child in children: + if child.ControlTypeName != 'ButtonControl': + continue + name = getattr(child, 'Name', '') + if name in target_names: + return child + return None + + def like(self, cancel: bool = False) -> WxResponse: + target_names = [_lang(MOMENTS, '赞')] + if cancel: + target_names.insert(0, _lang(MOMENTS, '取消')) + + button = self._find_button(target_names) + if not button: + return WxResponse.failure('未找到点赞按钮') + button.Click() + return WxResponse.success('操作成功') + + def comment(self) -> WxResponse: + button = self._find_button([_lang(MOMENTS, '评论')]) + if not button: + return WxResponse.failure('未找到评论按钮') + button.Click() + return WxResponse.success('已触发评论') + + def close(self) -> None: + if not self.control: + return + try: + self.control.SendKeys('{Esc}') + except Exception: + pass + + +class MomentCommentDialog(BaseUISubWnd): + """朋友圈评论输入窗口。""" + + _win_cls_name: str = 'Qt51514QWindowToolSaveBits' + + def __init__(self, parent: Moment): + self.parent = parent + self.root = parent.root + self.control = self._locate() + if self.control: + self._init_controls() + + def _locate(self) -> Optional[uia.Control]: + wins = find_all_windows_from_root(classname=self._win_cls_name, pid=self.root.pid) + for win in wins: + try: + children = win.GetChildren() + except Exception: + children = [] + for child in children: + if child.ControlTypeName == 'ButtonControl' and getattr(child, 'Name', '') == _lang(MOMENTS, '发送'): + return win + return None + + def _init_controls(self) -> None: + self.edit: Optional[uia.Control] = None + self.send_button: Optional[uia.Control] = None + try: + children = self.control.GetChildren() + except Exception: + children = [] + for child in children: + if child.ControlTypeName == 'EditControl' and self.edit is None: + self.edit = child + elif child.ControlTypeName == 'ButtonControl' and getattr(child, 'Name', '') == _lang(MOMENTS, '发送'): + self.send_button = child + + def exists(self, wait: float = 0) -> bool: # type: ignore[override] + if not self.control: + return False + try: + return self.control.Exists(wait) + except Exception: + return False + + def send(self, content: str) -> WxResponse: + if not self.exists(0): + return WxResponse.failure('评论窗口不存在') + + if not content: + return WxResponse.failure('评论内容不能为空') + + if not self.edit or not self.edit.Exists(0): + return WxResponse.failure('未找到评论输入框') + + try: + self.edit.Click() + self.edit.SendKeys('{Ctrl}a') + SetClipboardText(content) + self.edit.SendKeys('{Ctrl}v') + + if self.send_button and self.send_button.Exists(0): + self.send_button.Click() + else: + self.edit.SendKeys('{Enter}') + except Exception as exc: # pragma: no cover - UI 交互异常仅记录日志 + wxlog.debug(f'发送朋友圈评论失败:{exc}') + return WxResponse.failure('发送评论失败') + + return WxResponse.success('评论成功') + + +# =========================================================================== +# 数据库路线(微信 4.x 推荐):读取 sns.db SnsTimeLine +# =========================================================================== + +def _parse_user_comment(block: str) -> dict: + """解析单个 ``...`` 块。""" + def tag(name: str) -> Optional[str]: + m = re.search(r"<%s>([^<]*)" % (name, name), block) + return m.group(1).strip() if m else None + + return { + "username": tag("username") or "", + "nickname": tag("nickname") or "", + "content": tag("content") or "", + "create_time": int(tag("create_time") or 0), + "type": int(tag("type") or 0), + "comment_id": tag("comment_id") or "", + "ref_comment_id": tag("ref_comment_id") or "", + "b_deleted": int(tag("b_deleted") or 0), + } + + +class MomentDB: + """微信 4.x 朋友圈数据库读取器(无需 UI/OCR)。 + + 数据来源:``sns.db`` 的 ``SnsTimeLine`` 表,``content`` 为 + ``SnsDataItem`` XML。支持解析正文、图片/视频 md5 与本地缓存路径、 + 点赞、评论、定位。 + + 用法:: + + from wechatauto import WeChatDB, MomentDB + md = MomentDB(WeChatDB()) + for feed in md.get_moments(limit=10): + print(feed["nickname"], feed["text"]) + """ + + def __init__(self, db): + self.db = db + + # ------------------------------------------------------------------ + # 数据访问 + # ------------------------------------------------------------------ + def _open_sns(self): + for rel, path, _ in self.db._db_files: + if os.path.basename(path) == "sns.db": + return self.db._open(rel) + raise RuntimeError("未找到 sns.db(朋友圈库)") + + def get_moments(self, limit: int = 20, offset: int = 0, + username: Optional[str] = None) -> List[dict]: + """读取朋友圈时间线(按 tid 倒序)。username 可过滤指定发布者。""" + conn = self._open_sns() + try: + if username: + rows = conn.execute( + "SELECT tid, user_name, content FROM SnsTimeLine " + "WHERE user_name=? ORDER BY tid DESC LIMIT ? OFFSET ?", + (username, limit, offset), + ).fetchall() + else: + rows = conn.execute( + "SELECT tid, user_name, content FROM SnsTimeLine " + "ORDER BY tid DESC LIMIT ? OFFSET ?", + (limit, offset), + ).fetchall() + finally: + conn.close() + return [self.parse_feed(r["content"], r["user_name"]) for r in rows] + + def get_moment(self, tid: int) -> Optional[dict]: + conn = self._open_sns() + try: + r = conn.execute( + "SELECT tid, user_name, content FROM SnsTimeLine WHERE tid=?", + (tid,), + ).fetchone() + finally: + conn.close() + return self.parse_feed(r["content"], r["user_name"]) if r else None + + def get_my_moments(self, limit: int = 20) -> List[dict]: + return self.get_moments(limit=limit, username=self.db.wxid) + + def count(self) -> int: + conn = self._open_sns() + try: + return conn.execute("SELECT count(*) FROM SnsTimeLine").fetchone()[0] + finally: + conn.close() + + # ------------------------------------------------------------------ + # XML 解析 + # ------------------------------------------------------------------ + def parse_feed(self, xml: str, fallback_user: str = "") -> dict: + if isinstance(xml, bytes): + xml = xml.decode("utf-8", "replace") + m = re.search(r"(\d+)", xml) + feed_id = m.group(1) if m else "" + m = re.search(r"([^<]+)", xml) + author = m.group(1) if m else (fallback_user or "") + m = re.search(r"(\d+)", xml) + create_time = int(m.group(1)) if m else 0 + m = re.search(r"([^<]*)", xml) + text = html.unescape(m.group(1)) if m else "" + m = re.search(r'.*?]*md5="([0-9a-fA-F]{32})"[^>]*>(.*?)', xml, re.S + ): + md5 = mm.group(1).lower() + url = mm.group(2).strip() + if any(ext in url.lower() for ext in (".mp4", ".mov", ".avi")): + videos.append({"md5": md5, "url": url}) + else: + images.append({"md5": md5, "url": url}) + + # 点赞 / 评论 + likes, comments = [], [] + lm = re.search(r"(.*?)", xml, re.S) + if lm: + for blk in re.findall(r"(.*?)", lm.group(1), re.S): + c = _parse_user_comment(blk) + if c["username"]: + likes.append(c) + cm = re.search(r"(.*?)", xml, re.S) + if cm: + for blk in re.findall(r"(.*?)", cm.group(1), re.S): + c = _parse_user_comment(blk) + if c["username"] and not c["b_deleted"]: + comments.append(c) + + return { + "id": feed_id, + "tid": fallback_user, + "username": author, + "nickname": self._nick(author), + "text": text, + "location": location, + "create_time": create_time, + "images": images, + "videos": videos, + "likes": likes, + "comments": comments, + } + + def _nick(self, username: str) -> str: + if not username: + return "" + try: + return self.db.get_nickname(username) + except Exception: + return username + + # ------------------------------------------------------------------ + # 媒体落地 + # ------------------------------------------------------------------ + @staticmethod + def _cache_root(db) -> str: + return os.path.join(db.account_dir, "cache") + + def find_local_media(self, md5: str, kind: str = "image") -> Optional[str]: + """在 cache/<月>/Sns/ 下按 md5 查找本地缓存文件。""" + if len(md5) < 2: + return None + sub = "Img" if kind == "image" else "Video" + for root, _, files in os.walk(self._cache_root(self.db)): + if os.sep + "Sns" + os.sep + sub not in os.sep + root + os.sep: + continue + for f in files: + if f.startswith(md5): + return os.path.join(root, f) + return None + + def download_media(self, media: dict, save_dir: Optional[str] = None, + kind: str = "image") -> Optional[str]: + """下载朋友圈图片/视频:优先本地缓存,否则从 URL 拉取。""" + save_dir = save_dir or os.path.join( + os.path.expanduser("~"), "Documents", "wechatauto_moments" + ) + os.makedirs(save_dir, exist_ok=True) + md5 = (media or {}).get("md5") + local = self.find_local_media(md5, kind) if md5 else None + ext = ".jpg" + if local: + src = local + data = open(src, "rb").read() + else: + url = (media or {}).get("url") + if not url: + return None + try: + import urllib.request + req = urllib.request.Request( + url, headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0)"} + ) + data = urllib.request.urlopen(req, timeout=20).read() + except Exception as e: + wxlog.debug(f'下载朋友圈媒体失败:{e}') + return None + if url.lower().endswith((".mp4", ".mov", ".avi")): + ext = ".mp4" + out = os.path.join(save_dir, "%s%s" % (md5 or os.path.basename(url or "media"), ext)) + with open(out, "wb") as f: + f.write(data) + return out diff --git a/wechatauto/msgs/__init__.py b/wechatauto/msgs/__init__.py new file mode 100644 index 0000000..e0efd1a --- /dev/null +++ b/wechatauto/msgs/__init__.py @@ -0,0 +1,81 @@ +from .base import Message, BaseMessage, HumanMessage +from .mattr import SystemMessage, FriendMessage, SelfMessage +from .mtype import ( + TextMessage, + QuoteMessage, + VoiceMessage, + ImageMessage, + VideoMessage, + FileMessage, + LinkMessage, + LocationMessage, + PersonalCardMessage, + OtherMessage, +) +from .friend import ( + FriendTextMessage, + FriendQuoteMessage, + FriendImageMessage, + FriendFileMessage, + FriendVideoMessage, + FriendVoiceMessage, + FriendLinkMessage, + FriendLocationMessage, + FriendPersonalCardMessage, + FriendOtherMessage, +) +from .self import ( + SelfTextMessage, + SelfQuoteMessage, + SelfImageMessage, + SelfFileMessage, + SelfVideoMessage, + SelfVoiceMessage, + SelfLinkMessage, + SelfLocationMessage, + SelfPersonalCardMessage, + SelfOtherMessage, +) +from .msg import parse_msg, parse_msg_attr, parse_msg_type + +__all__ = [ + "Message", + "BaseMessage", + "HumanMessage", + "SystemMessage", + "FriendMessage", + "SelfMessage", + "TextMessage", + "QuoteMessage", + "VoiceMessage", + "ImageMessage", + "VideoMessage", + "FileMessage", + "LinkMessage", + "LocationMessage", + "PersonalCardMessage", + "OtherMessage", + "FriendTextMessage", + "FriendQuoteMessage", + "FriendImageMessage", + "FriendFileMessage", + "FriendVideoMessage", + "FriendVoiceMessage", + "FriendLinkMessage", + "FriendLocationMessage", + "FriendPersonalCardMessage", + "FriendOtherMessage", + "SelfTextMessage", + "SelfQuoteMessage", + "SelfImageMessage", + "SelfFileMessage", + "SelfVideoMessage", + "SelfVoiceMessage", + "SelfLinkMessage", + "SelfLocationMessage", + "SelfPersonalCardMessage", + "SelfOtherMessage", + "parse_msg", + "parse_msg_attr", + "parse_msg_type", +] diff --git a/wechatauto/msgs/base.py b/wechatauto/msgs/base.py new file mode 100644 index 0000000..8310c5e --- /dev/null +++ b/wechatauto/msgs/base.py @@ -0,0 +1,285 @@ +from wechatauto import uia +from wechatauto.ui.component import ( + Menu, + SelectContactWnd +) +from wechatauto.utils import uilock +from wechatauto.param import WxParam, WxResponse, PROJECT_NAME +from abc import ABC, abstractmethod +from typing import ( + Dict, + List, + Union, + Any, + TYPE_CHECKING, + Iterator, + Tuple +) +from hashlib import md5 + +if TYPE_CHECKING: + from wechatauto.ui.chatbox import ChatBox + + +def truncate_string(s: str, n: int = 8) -> str: + s = s.replace('\n', '').strip() + return s if len(s) <= n else s[:n] + '...' + + +class Message: + """消息对象基类 + + 该类不会直接实例化,而是作为所有消息类型的基类提供 + 常用的工具方法。实际的属性均由子类在 ``__init__`` 中 + 动态注入。 + """ + + _EXCLUDE_FIELDS = {"control", "parent", "root"} + + # region --- 迭代/映射相关 ------------------------------------------------- + def _iter_public_items(self) -> Iterator[Tuple[str, Any]]: + """遍历当前消息可公开的字段""" + + if not hasattr(self, "__dict__"): + return + + seen = set() + for key, value in self.__dict__.items(): + if key.startswith("_") or key in self._EXCLUDE_FIELDS: + continue + if key == "hash" and not WxParam.MESSAGE_HASH: + continue + seen.add(key) + yield key, value + + # 补充类级字段(如 type/attr),保证 to_dict/match 可用 + for key in ('type', 'attr'): + if key in seen: + continue + if any(key in cls.__dict__ for cls in type(self).__mro__): + yield key, getattr(self, key) + + def __iter__(self) -> Iterator[str]: + for key, _ in self._iter_public_items(): + yield key + + def __len__(self) -> int: + return sum(1 for _ in self._iter_public_items()) + + def __getitem__(self, item: str) -> Any: + for key, value in self._iter_public_items(): + if key == item: + return value + raise KeyError(item) + + def __contains__(self, key: object) -> bool: + if not isinstance(key, str): + return False + return any(field == key for field, _ in self._iter_public_items()) + + # endregion ---------------------------------------------------------------- + + # region --- 字段访问 ------------------------------------------------------- + def keys(self) -> Tuple[str, ...]: + return tuple(key for key, _ in self._iter_public_items()) + + def values(self) -> Tuple[Any, ...]: + return tuple(value for _, value in self._iter_public_items()) + + def items(self) -> Tuple[Tuple[str, Any], ...]: + return tuple(self._iter_public_items()) + + def get(self, key: str, default: Any = None) -> Any: + for field, value in self._iter_public_items(): + if field == key: + return value + return default + + def to_dict(self) -> Dict[str, Any]: + return dict(self._iter_public_items()) + + def copy(self) -> Dict[str, Any]: + return self.to_dict().copy() + + # endregion ---------------------------------------------------------------- + + # region --- 状态判断 ------------------------------------------------------- + def match(self, **conditions: Any) -> bool: + """判断当前消息是否同时满足给定的字段条件""" + + data = self.to_dict() + return all(data.get(key) == value for key, value in conditions.items()) + + @property + def is_self(self) -> bool: + return getattr(self, "attr", None) == "self" + + @property + def is_friend(self) -> bool: + return getattr(self, "attr", None) == "friend" + + @property + def is_system(self) -> bool: + return getattr(self, "attr", None) == "system" + + # endregion ---------------------------------------------------------------- + + # region --- 魔术方法 ------------------------------------------------------- + def __str__(self) -> str: + content = getattr(self, "content", None) + if content is None: + return super().__str__() + return str(content) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, Message): + return NotImplemented + + self_id = getattr(self, "id", None) + other_id = getattr(other, "id", None) + if self_id is not None and other_id is not None: + return self_id == other_id + + if WxParam.MESSAGE_HASH: + return getattr(self, "hash", None) == getattr(other, "hash", None) + + return self is other + + def __hash__(self) -> int: + msg_id = getattr(self, "id", None) + if msg_id is not None: + return hash(msg_id) + + if WxParam.MESSAGE_HASH: + return hash(getattr(self, "hash", None)) + + return super().__hash__() + + # endregion ---------------------------------------------------------------- + +class BaseMessage(Message, ABC): + type: str = 'base' + attr: str = 'base' + control: uia.Control + + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + self.parent = parent + self.control = control + self.direction = additonal_attr.get('direction', None) + self.distince = additonal_attr.get('direction_distence', None) + self.root = parent.root + self.id = self.control.runtimeid + self.content = self.control.Name + rect = self.control.BoundingRectangle + self.hash_text = f'({rect.height()},{rect.width()}){self.content}' + self.hash = md5(self.hash_text.encode()).hexdigest() + + def __repr__(self): + cls_name = self.__class__.__name__ + content = truncate_string(self.content) + return f"<{PROJECT_NAME} - {cls_name}({content}) at {hex(id(self))}>" + + def roll_into_view(self): + if not self.exists(): + return WxResponse.failure('消息目标控件不存在,无法滚动至显示窗口') + if uia.RollIntoView( + self.parent.msgbox, + self.control + ) == 'not exist': + return WxResponse.failure('消息目标控件不存在,无法滚动至显示窗口') + return WxResponse.success('成功') + + def exists(self): + if self.control.Exists(0) and self.control.BoundingRectangle.height() > 0: + return True + return False + + +class HumanMessage(BaseMessage, ABC): + attr = 'human' + + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + @abstractmethod + def _click(self, x, y, right=False): ... + + @abstractmethod + def _bias(self): ... + + def click(self): + self._click(right=False, x=self._bias * 2, y=WxParam.DEFAULT_MESSAGE_YBIAS) + + def right_click(self): + self._click(right=True, x=self._bias, y=WxParam.DEFAULT_MESSAGE_YBIAS) + + @uilock + def select_option(self, option: str, timeout=2) -> WxResponse: + if not self.exists(): + return WxResponse.failure('消息对象已失效') + self._click(right=True, x=self._bias * 2, y=WxParam.DEFAULT_MESSAGE_YBIAS) + if menu := Menu(self, timeout): + return menu.select(option) + else: + return WxResponse.failure('操作失败') + + @uilock + def forward( + self, + targets: Union[List[str], str], + timeout: int = 3, + interval: float = 0.1 + ) -> WxResponse: + """转发消息 + + Args: + targets (Union[List[str], str]): 目标用户列表 + timeout (int, optional): 超时时间,单位为秒,若为None则不启用超时设置 + interval (float): 选择联系人时间间隔 + + Returns: + WxResponse: 调用结果 + """ + if not self.exists(): + return WxResponse.failure('消息对象已失效') + if not self.select_option('转发...', timeout=timeout): + return WxResponse.failure('当前消息无法转发') + + select_wnd = SelectContactWnd(self) + return select_wnd.send(targets, interval=interval) + + @uilock + def quote( + self, text: str, + at: Union[List[str], str] = None, + timeout: int = 3 + ) -> WxResponse: + """引用消息 + + Args: + text (str): 引用内容 + at (List[str], optional): @用户列表 + timeout (int, optional): 超时时间,单位为秒,若为None则不启用超时设置 + + Returns: + WxResponse: 调用结果 + """ + if not self.exists(): + return WxResponse.failure('消息对象已失效') + if not self.select_option('引用', timeout=timeout): + return WxResponse.failure('当前消息无法引用') + + if at: + self.parent.input_at(at) + + return self.parent.send_text(text) diff --git a/wechatauto/msgs/friend.py b/wechatauto/msgs/friend.py new file mode 100644 index 0000000..154fee1 --- /dev/null +++ b/wechatauto/msgs/friend.py @@ -0,0 +1,112 @@ +from .mattr import * +from .mtype import * + + +class FriendTextMessage(FriendMessage, TextMessage): + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + +class FriendQuoteMessage(FriendMessage, QuoteMessage): + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + +class FriendImageMessage(FriendMessage, ImageMessage): + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + +class FriendEmojiMessage(FriendMessage, EmojiMessage): + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + +class FriendFileMessage(FriendMessage, FileMessage): + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + +class FriendVideoMessage(FriendMessage, VideoMessage): + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + +class FriendVoiceMessage(FriendMessage, VoiceMessage): + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + +class FriendLinkMessage(FriendMessage, LinkMessage): + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + +class FriendLocationMessage(FriendMessage, LocationMessage): + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + +class FriendPersonalCardMessage(FriendMessage, PersonalCardMessage): + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + +class FriendOtherMessage(FriendMessage, OtherMessage): + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) diff --git a/wechatauto/msgs/mattr.py b/wechatauto/msgs/mattr.py new file mode 100644 index 0000000..e0b2495 --- /dev/null +++ b/wechatauto/msgs/mattr.py @@ -0,0 +1,79 @@ +from .base import ( + BaseMessage, + HumanMessage +) +from wechatauto import uia +from wechatauto.param import ( + WxParam, + WxResponse, + PROJECT_NAME +) + +from typing import ( + Dict, + List, + Any, + TYPE_CHECKING +) +if TYPE_CHECKING: + from wechatauto.ui.chatbox import ChatBox + + +class SystemMessage(BaseMessage): + attr = 'system' + + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + self.sender = 'system' + self.sender_remark = 'system' + + +class FriendMessage(HumanMessage): + attr = 'friend' + + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + def _click(self, x, y, right=False): + self.roll_into_view() + if right: + self.control.RightClick(x=x, y=y, ratioX=0, ratioY=0) + else: + self.control.Click(ratioX=0, ratioY=0) + + @property + def _bias(self): + return WxParam.DEFAULT_MESSAGE_XBIAS + + +class SelfMessage(HumanMessage): + attr = 'self' + + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + def _click(self, x, y, right=False): + self.roll_into_view() + if right: + self.control.RightClick(x=x, y=y, ratioX=1, ratioY=0) + else: + self.control.Click(x=x, y=y, ratioX=1, ratioY=0) + + @property + def _bias(self): + return -WxParam.DEFAULT_MESSAGE_XBIAS diff --git a/wechatauto/msgs/msg.py b/wechatauto/msgs/msg.py new file mode 100644 index 0000000..ee6ec45 --- /dev/null +++ b/wechatauto/msgs/msg.py @@ -0,0 +1,140 @@ +from wechatauto.utils.tools import ( + detect_message_direction +) +from wechatauto import uia +from .mattr import ( + SystemMessage, + FriendMessage, + SelfMessage +) +from .mtype import * +from . import self as selfmsg +from . import friend as friendmsg +from typing import ( + TYPE_CHECKING, + Literal, + Dict, + Any +) +import os +import re + +if TYPE_CHECKING: + from wechatauto.ui.chatbox import ChatBox + + +def parse_msg_attr( + control: uia.Control, + parent: 'ChatBox' +): + msg_direction_hash = { + 'left': 'friend', + 'right': 'self' + } + if control.AutomationId: + msg_screenshot = control.ScreenShot() + msg_direction, msg_direction_distence = detect_message_direction(msg_screenshot) + msg_attr = msg_direction_hash.get(msg_direction) + os.remove(msg_screenshot) + + additonal_attr = { + 'direction': msg_direction, + 'direction_distence': msg_direction_distence + } + + else: + msg_attr = 'system' + + if msg_attr == 'system': + return SystemMessage(control, parent) + elif msg_attr == 'friend': + return parse_msg_type(control, parent, 'Friend', additonal_attr) + elif msg_attr == 'self': + return parse_msg_type(control, parent, 'Self', additonal_attr) + + +def parse_msg_type( + control: uia.Control, + parent, + attr: Literal['Self', 'Friend'], + additonal_attr: Dict[str, Any] + ): + """ + 多层次消息类型识别算法 + 基于ClassName、Name等多重验证确保识别准确性 + """ + if attr == 'Friend': + msgtype = friendmsg + else: + msgtype = selfmsg + + msg_text = control.Name + msg_classname = control.ClassName + msg_automation_id = control.AutomationId + + # 第一层:ClassName强特征识别(最可靠) + classname_result = _classify_by_classname(msg_classname) + if classname_result: + return getattr(msgtype, f'{attr}{classname_result}')(control, parent, additonal_attr) + + # 第二层:基于ClassName分类后的详细识别 + if msg_classname == "mmui::ChatBubbleItemView": + # Name前缀特征识别 + prefix_result = _classify_by_name_prefix(msg_text) + if prefix_result: + return getattr(msgtype, f'{attr}{prefix_result}')(control, parent, additonal_attr) + + # 图片消息处理 + if msg_text == '图片': + return getattr(msgtype, f'{attr}ImageMessage')(control, parent, additonal_attr) + + # 如果都不匹配,归类为其他消息 + return getattr(msgtype, f'{attr}OtherMessage')(control, parent, additonal_attr) + + elif msg_classname == "mmui::ChatTextItemView": + # 第三层:引用消息处理 + if _is_quote_message(msg_text): + return getattr(msgtype, f'{attr}QuoteMessage')(control, parent, additonal_attr) + else: + return getattr(msgtype, f'{attr}TextMessage')(control, parent, additonal_attr) + + return getattr(msgtype, f'{attr}OtherMessage')(control, parent, additonal_attr) + + +def _classify_by_classname(classname: str) -> str: + classname_mapping = { + "mmui::ChatVoiceItemView": "VoiceMessage", + "mmui::ChatPersonalCardItemView": "PersonalCardMessage", + } + return classname_mapping.get(classname, "") + + +def _classify_by_name_prefix(name: str) -> str: + if name.startswith("[动画表情]") or name.startswith("[动画表情"): + return "EmojiMessage" + + if name.startswith("[链接]"): + return "LinkMessage" + + elif name.startswith("位置"): + return "LocationMessage" + + elif name.startswith("文件\n"): + return "FileMessage" + + elif name.startswith("视频"): + return "VideoMessage" + + return "" + + +def _is_quote_message(name: str) -> bool: + quote_pattern = r'^(.*?)\s*\n引用\s+(.+?)\s+的消息\s*:\s*(.*)$' + return bool(re.search(quote_pattern, name, re.DOTALL)) + + +def parse_msg( + control: uia.Control, + parent +): + return parse_msg_attr(control, parent) diff --git a/wechatauto/msgs/mtype.py b/wechatauto/msgs/mtype.py new file mode 100644 index 0000000..2afab03 --- /dev/null +++ b/wechatauto/msgs/mtype.py @@ -0,0 +1,1112 @@ +from .base import ( + BaseMessage, + HumanMessage, +) +from wechatauto import uia +from wechatauto.utils import uilock +from wechatauto.param import ( + WxParam, + WxResponse, + PROJECT_NAME +) + +from typing import ( + Dict, + List, + Any, + Optional, + TYPE_CHECKING +) +import os +import re +import time +import tempfile +if TYPE_CHECKING: + from wechatauto.ui.chatbox import ChatBox + + +class TextMessage(BaseMessage): + type = 'text' + + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + +class QuoteMessage(BaseMessage): + type = 'quote' + repattern = r"^(.*?) \n引用 (.*?) 的消息 : (.*?)$" + + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + self.content, self.quote_nickname, self.quote_content = \ + re.findall(self.repattern, self.content, re.DOTALL)[0] + + +class VoiceMessage(BaseMessage): + type = 'voice' + + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + @uilock + def forward_to(self, who: str, save_dir: str = None) -> WxResponse: + """转发语音:从本地媒体库提取 SILK 音频文件并发送给目标联系人。 + + 微信不支持直接右键转发语音消息(无转发入口),因此本方法改为 + 「找到本地语音文件 → 作为文件消息发送」: + + 1. 通过 ``MediaDownloader.download_voice`` 从 media_0.db 提取 + ``VoiceInfo.voice_data``(SILK 二进制)落盘为 ``.silk``; + 2. 调用 ``WeChatGUI.send_file`` 以文件消息发送给 ``who``。 + + Args: + who: 转发目标(联系人显示名/wxid) + save_dir: 语音文件临时保存目录,默认系统临时目录 + + Returns: + WxResponse + """ + chat = getattr(self.parent, 'root', None) + if chat is None: + return WxResponse.failure('消息缺少会话上下文,无法转发') + gui = getattr(chat, '_gui', None) + db = getattr(chat, '_db', None) + if gui is None or db is None: + return WxResponse.failure('消息缺少 GUI/DB 上下文,无法转发') + local_id = getattr(self, 'local_id', None) + if local_id is None: + return WxResponse.failure('消息缺少 local_id,无法定位语音文件') + # media_0.db 的 VoiceInfo 按「聊天对象」分组(chat_name_id), + # 因此 user 传会话 wxid(chat._wxid)而非 sender_id + user = getattr(chat, '_wxid', '') or getattr(self, 'wxid', '') + if not user: + return WxResponse.failure('无法确定语音所属会话') + from wechatauto.media import MediaDownloader + media = MediaDownloader(db, save_dir=save_dir) + path = media.download_voice(str(user), int(local_id), save_dir=save_dir) + if not path: + return WxResponse.failure(f'本地未找到该语音文件(local_id={local_id})') + return gui.send_file(path, who) + + +class ImageMessage(BaseMessage): + type = 'image' + + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + @property + def image(self): + """打开并返回图片预览窗口实例""" + from wechatauto.ui.component import WeChatImage + self.roll_into_view() + self.control.Click() + return WeChatImage(self) + + def save(self, dir_path=None, timeout=10): + """保存图片 + + Args: + dir_path (str): 保存文件夹路径 + timeout (int, optional): 保存超时时间,默认10秒 + + Returns: + Path: 文件保存路径 + """ + preview = self.image + if not preview.control: + return WxResponse.failure('未找到图片预览窗口') + return preview.save(dir_path, timeout) + + +class EmojiMessage(BaseMessage): + """表情包(动画表情)消息。 + + 微信 4.x 表情消息在本地数据库中 content 为加密数据,无法直接还原 + 表情图片;因此 ``capture()`` 采用「打开会话 → 滚动到底 → 对最后一条 + 消息区域截图」的屏幕截图方案,返回图片路径供上层(如 AI 视觉识别)使用。 + """ + type = 'emotion' + + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + def capture(self, save_dir: str = None) -> Optional[str]: + """截取当前表情包图片,返回保存路径;失败返回 None。 + + 方案:打开会话 → 滚动到表情消息可见 → 用 uia 元素 BoundingRectangle + 获取其精确屏幕坐标 → 截图该区域 → 裁剪掉空白边缘后保存。相比按 + 消息区固定高度截图,不会因表情超出截图区域而被截断。 + """ + from wechatauto.logger import wxlog + + chat = getattr(self.parent, 'root', None) + if chat is None: + wxlog.warning('表情截图失败:无法定位会话') + return None + gui = getattr(chat, '_gui', None) + if gui is None: + wxlog.warning('表情截图失败:无法定位 GUI') + return None + who = (getattr(self.parent, 'who', None) + or getattr(chat, 'who', None) + or getattr(chat, 'nickname', None)) + if not who: + wxlog.warning('表情截图失败:会话名称为空') + return None + try: + # ---- UIA 优先路径:直接定位表情消息行的精确屏幕坐标 ---- + # 热激活后消息列表暴露 mmui::ChatBubbleReferItemView(Name='动画表情') + # / ChatBubbleItemView 等控件,BoundingRectangle 即精确行坐标, + # 替代「截图全消息区+连通域猜气泡」的脆弱裁剪。 + uia_path = None + try: + eng = gui._get_uia() + if eng is not None and eng.ensure_window(): + if not eng.current_chat() == who: + eng.open_chat(who) + time.sleep(0.6) + found = eng.find_in_message_list( + lambda cn, nm: (nm == '动画表情' + or (cn == 'mmui::ChatBubbleItemView' + and '[动画表情' in nm)), + match_last=True, max_scrolls=60) + if found: + cn, nm, rect = found + # 消息行是全宽(含头像/空白),按方向裁出气泡本身 + attr = getattr(self, 'attr', 'friend') + row_img = gui._grab_screen( + (rect.left, rect.top, rect.right, rect.bottom)) + bubble = self._crop_bubble_from_row( + row_img, want_left=(attr != 'self')) + if bubble is None or min(bubble.size) < 50: + bubble = self._content_bbox_crop(row_img) + if bubble is not None and min(bubble.size) >= 50: + uia_path = bubble + except Exception as e: + wxlog.debug('UIA 表情定位失败,退回连通域方案:%s', e) + if uia_path is not None: + save_dir = save_dir or os.path.join( + tempfile.gettempdir(), PROJECT_NAME, 'emoji') + os.makedirs(save_dir, exist_ok=True) + path = os.path.join( + save_dir, 'emoji_%d.png' % int(time.time() * 1000)) + uia_path.save(path) + print(f'[CAP] uia attr={getattr(self, "attr", "?")} ' + f'crop={uia_path.size}') + return path + + # 会话已打开(主窗面板或独立聊天窗口)时跳过 open_chat: + # 重复 open_chat 会刷新消息列表/切换窗口,使消息控件失效。 + # 注意 _find_chat_window 未找到时返回 0 而非 None,需转 bool。 + opened = (gui._chat_is_open(who) + or bool(gui._find_chat_window(who))) + if not opened: + if not gui.open_chat(who): + wxlog.warning('表情截图失败:无法打开会话 %s', who) + return None + time.sleep(0.8) + save_dir = save_dir or os.path.join( + tempfile.gettempdir(), PROJECT_NAME, 'emoji') + # 滚动到底,让底部表情消息在消息列表中实例化(uia 可见) + box = gui.get_input_box() + if box: + self._scroll_to_bottom(gui, box[1]) + time.sleep(0.6) + # 微信 4.x 主窗口为 Qt,不暴露 uia 子树,无法用控件坐标定位; + # 直接走消息区截图 + 底部消息裁剪。 + img = self._pane_capture_img(gui) + if img is None: + wxlog.warning('表情截图失败:无法获取截图画面') + return None + # 诊断:保存原始消息区截图,便于跨电脑排查 + try: + img.save(os.path.join( + os.path.expanduser('~'), 'pane_diag_raw.png')) + except Exception: + pass + attr = getattr(self, 'attr', 'friend') + want_left = (attr != 'self') + # 主路径:连通域精确锁定最后一条消息的气泡内容。 + # 该算法会过滤细长竖条(滚动条/面板边框)并剔除头像类小元素, + # 避免右侧滚动条/边框被当成内容导致裁出大片空白;同时按方向 + # 取左侧(对方)或右侧(自己)的底部消息。 + crop = self._crop_last_bubble(img, want_left=want_left) + used = 'cc' + # 太小的结果(时间戳/文字等)视为误判,回退到其他方法 + if crop is None or min(crop.size) < 50: + crop = self._crop_bottom_message(img) + used = 'blank' + if crop is None or min(crop.size) < 50: + crop = self._crop_by_avatar(img) + used = 'avatar' + print(f'[CAP] attr={attr} img={img.size} ' + f'used={used} crop={crop.size if crop else None}') + if crop is None or min(crop.size) < 50: + wxlog.warning('表情截图失败:内容区域过小') + return None + crop = self._content_bbox_crop(crop) + if crop is None: + wxlog.warning('表情截图失败:内容边界裁剪失败') + return None + os.makedirs(save_dir, exist_ok=True) + path = os.path.join( + save_dir, 'emoji_%d.png' % int(time.time() * 1000)) + crop.save(path) + return path + except Exception as e: + wxlog.warning('表情截图异常:%s', e) + return None + + @staticmethod + def _content_bbox_crop(img) -> Optional[Any]: + """按内容边界裁剪,去掉空白边缘与相邻头像等无关元素。""" + try: + w, h = img.size + px = img.load() + minx, miny, maxx, maxy = w, h, -1, -1 + for y in range(0, h, 2): + for x in range(0, w, 2): + p = px[x, y] + if len(p) >= 3: + r, g, b = p[0], p[1], p[2] + else: + r = g = b = p + mxv = max(r, g, b) + mnv = min(r, g, b) + if not (mxv > 235 and (mxv - mnv) < 22): + if x < minx: + minx = x + if y < miny: + miny = y + if x > maxx: + maxx = x + if y > maxy: + maxy = y + if maxx < 0: + return None + pad = 4 + x0 = max(0, minx - pad) + y0 = max(0, miny - pad) + x1 = min(w, maxx + pad + 1) + y1 = min(h, maxy + pad + 1) + if x1 - x0 < 8 or y1 - y0 < 8: + return None + return img.crop((x0, y0, x1, y1)) + except Exception: + return None + + def _crop_bubble_from_row(self, img, want_left: bool = True) -> Optional[Any]: + """从 UIA 定位到的整行截图里按方向裁出气泡内容。 + + want_left=True 取左侧(对方)气泡,False 取右侧(自己)气泡。 + 表情行含头像与两侧空白,先按方向定位气泡起始列,再裁到内容边界。 + """ + try: + w, h = img.size + px = img.load() + content_cols = [] + for x in range(0, w, 2): + cnt = 0 + for y in range(0, h, 3): + p = px[x, y] + if len(p) >= 3: + r, g, b = p[0], p[1], p[2] + else: + r = g = b = p + mxv = max(r, g, b) + mnv = min(r, g, b) + if not (mxv > 235 and (mxv - mnv) < 22): + cnt += 1 + if cnt > 2: + content_cols.append(x) + if not content_cols: + return None + # 头像约 40-50px,按方向定位气泡: + # want_left(对方发) 气泡在左侧头像之后;False(自己发) 气泡在右侧。 + groups = [] + cur = [content_cols[0]] + for x in content_cols[1:]: + if x - cur[-1] <= 6: + cur.append(x) + else: + groups.append(cur) + cur = [x] + groups.append(cur) + # 过滤过窄毛边(<10px 视为滚动条/噪点) + groups = [g for g in groups if g[-1] - g[0] >= 10] + if not groups: + return None + if want_left: + # 左侧气泡:从头像右侧找第一个宽组 + bubble = groups[0] + if groups[0][0] < w * 0.15 and len(groups) > 1: + bubble = groups[1] + else: + # 右侧气泡:取最右侧的宽组 + bubble = groups[-1] + if not bubble: + return None + x0 = bubble[0] + x1 = bubble[-1] + # y 裁剪到内容边界 + content_rows = [] + for y in range(0, h, 2): + cnt = 0 + for x in range(x0, x1 + 1, 3): + p = px[x, y] + if len(p) >= 3: + r, g, b = p[0], p[1], p[2] + else: + r = g = b = p + mxv = max(r, g, b) + mnv = min(r, g, b) + if not (mxv > 235 and (mxv - mnv) < 22): + cnt += 1 + if cnt > 0: + content_rows.append(y) + if not content_rows: + return None + pad = 4 + x0 = max(0, x0 - pad) + x1 = min(w, x1 + pad + 1) + y0 = max(0, content_rows[0] - pad) + y1 = min(h, content_rows[-1] + pad + 1) + if x1 - x0 < 8 or y1 - y0 < 8: + return None + return img.crop((x0, y0, x1, y1)) + except Exception: + return None + + def _last_msg_rect(self, gui) -> Optional[tuple]: + """从主窗口 uia 树定位消息区最后一条消息的屏幕矩形。 + + DB 模式消息的 control 是伪控件(BoundingRectangle 恒为 0), + 无法用于定位。这里实时从微信主窗口构建 uia 树,找到消息列表 + 最后一项(即最新一条消息)读取真实坐标。 + """ + try: + main = uia.ControlFromHandle(gui.main_hwnd) + if main is None: + print('[DIAG uia] 主窗口控件为空') + return None + chatbox = main.GroupControl(ClassName="mmui::ChatMessagePage") \ + .CustomControl(ClassName="mmui::XSplitterView") + msgbox = chatbox.GroupControl(ClassName="mmui::MessageView") \ + .ListControl() + items = msgbox.GetChildren() + print(f'[DIAG uia] 消息项数量={len(items)}') + if not items: + return None + last = items[-1] + rect = last.BoundingRectangle + w, h = rect.width(), rect.height() + print(f'[DIAG uia] last rect=({rect.left},{rect.top},{rect.right},{rect.bottom}) ' + f'w={w} h={h} name={last.Name!r}') + if w <= 8 or h <= 8: + return None + return (rect.left, rect.top, rect.right, rect.bottom) + except Exception as e: + print(f'[DIAG uia] 异常 {type(e).__name__}: {e}') + return None + + def _uia_capture_img(self, gui) -> Optional[Any]: + """用 uia 元素坐标定位表情消息并截图(精确到单条消息)。 + + 从主窗口实时定位最后一条消息(滚动到底后即最新表情); + 定位失败返回 None,由调用方回退到消息区截图。 + """ + try: + rect = self._last_msg_rect(gui) + if rect is None: + return None + pad = 4 + return gui._grab_screen(( + rect[0] - pad, rect[1] - pad, + rect[2] + pad, rect[3] + pad)) + except Exception: + return None + + def _pane_capture_img(self, gui) -> Optional[Any]: + """截取消息区全宽画面(渲染顶部到输入框),供底部消息裁剪。""" + try: + box = gui.get_input_box() + if not box: + return None + ry0 = box[1] + rpl = gui.right_pane_left + render_w = gui.render_w + # 从渲染顶部开始,覆盖整个消息区,避免表情顶部超出固定高度被裁 + top = 110 + bottom = ry0 - 24 + if bottom <= top: + return None + screen_box = gui._rel_to_screen((rpl, top, render_w - 16, bottom)) + return gui._grab_screen(screen_box) + except Exception: + return None + + @staticmethod + def _crop_bottom_message(img) -> Optional[Any]: + """取最底部一条消息的完整内容(从底部内容行向上到消息分隔空白)。 + + 底部消息的顶部边界用「连续空白行超过阈值」判定。阈值自适应取 + 消息区高度的 2.5%(采样行),跨分辨率/DPI 保持一致:大于表情包 + 图片内部的小留白、小于消息列表相邻消息的分隔留白。 + + 同时裁掉左侧头像区域:从左向右扫描,找到内容起始列,跳过头像。 + """ + try: + w, h = img.size + rows = [] + for y in range(0, h, 2): + cnt = 0 + for x in range(0, w, 3): + p = img.getpixel((x, y)) + if len(p) >= 3: + r, g, b = p[0], p[1], p[2] + else: + r = g = b = p + mxv = max(r, g, b) + mnv = min(r, g, b) + if not (mxv > 235 and (mxv - mnv) < 22): + cnt += 1 + rows.append(cnt) + content = [i for i, c in enumerate(rows) if c > 3] + if not content: + return None + bottom = max(content) + gap = max(8, int(h * 0.025) // 2) # 采样行,每行=2px + blank = 0 + top_idx = 0 + for i in range(bottom, -1, -1): + if rows[i] <= 3: + blank += 1 + if blank > gap: + top_idx = i + gap + break + else: + blank = 0 + pad = 4 + y0 = max(0, top_idx * 2 - pad) + y1 = min(h, bottom * 2 + pad + 1) + if y1 - y0 < 8: + return None + # 水平裁剪:从左向右找内容起始列,跳过头像区域 + left_x = 0 + for x in range(0, w, 2): + cnt = 0 + for y in range(y0, y1, 3): + p = img.getpixel((x, y)) + if len(p) >= 3: + r, g, b = p[0], p[1], p[2] + else: + r = g = b = p + mxv = max(r, g, b) + mnv = min(r, g, b) + if not (mxv > 235 and (mxv - mnv) < 22): + cnt += 1 + if cnt > 2: + left_x = x + break + # 头像宽度约 40-50px(逻辑),跳过头像后再找内容空白间隔后的起始列 + if left_x < w * 0.15: + # 可能命中了头像,继续向右找内容空白间隔后的起始列 + in_avatar = False + avatar_end = left_x + int(w * 0.05) # 头像最小宽度约 5% 窗口宽 + for x in range(left_x, min(w, int(w * 0.30)), 2): + cnt = 0 + for y in range(y0, y1, 3): + p = img.getpixel((x, y)) + if len(p) >= 3: + r, g, b = p[0], p[1], p[2] + else: + r = g = b = p + mxv = max(r, g, b) + mnv = min(r, g, b) + if not (mxv > 235 and (mxv - mnv) < 22): + cnt += 1 + if cnt <= 2: + in_avatar = True + elif in_avatar: + # 从头像空白区进入内容区 + left_x = x + break + else: + # 未找到空白间隔(头像紧贴内容),按头像宽度跳过 + if left_x < avatar_end: + left_x = avatar_end + # 右侧裁剪:从右向左找内容结束列,裁掉右侧空白 + right_x = w + for x in range(w - 1, left_x, -2): + cnt = 0 + for y in range(y0, y1, 3): + p = img.getpixel((x, y)) + if len(p) >= 3: + r, g, b = p[0], p[1], p[2] + else: + r = g = b = p + mxv = max(r, g, b) + mnv = min(r, g, b) + if not (mxv > 235 and (mxv - mnv) < 22): + cnt += 1 + if cnt > 2: + right_x = x + break + return img.crop((left_x, y0, min(w, right_x + pad + 1), y1)) + except Exception: + return None + + @staticmethod + def _avatar_top(img) -> Optional[int]: + """在消息区左侧找最底部头像的顶部 y(相对截图坐标)。 + + 头像位于消息区左侧一条窄列内,是圆形彩色块;其顶部与消息气泡 + 顶部对齐。头像直径与屏幕缩放成正比,跨分辨率特征稳定。 + """ + try: + w, h = img.size + px = img.load() + x0 = max(0, int(w * 0.02)) + x1 = max(x0 + 20, int(w * 0.10)) + x1 = min(w, x1) + cols = [] + for y in range(0, h, 2): + cnt = 0 + for x in range(x0, x1): + r, g, b = px[x, y][:3] + mxv = max(r, g, b) + mnv = min(r, g, b) + if not (mxv > 235 and (mxv - mnv) < 22): + cnt += 1 + cols.append(cnt) + bottom = -1 + for y in range(len(cols) - 1, -1, -1): + if cols[y] > 2: + bottom = y + break + if bottom < 0: + return None + top = bottom + while top > 0 and cols[top - 1] > 2: + top -= 1 + height = (bottom - top + 1) * 2 + if not (8 <= height <= 220): + return None + return top * 2 + except Exception: + return None + + def _crop_by_avatar(self, img) -> Optional[Any]: + """对方消息:以左侧头像顶部为消息顶部,裁到消息区底部内容。""" + try: + w, h = img.size + top = self._avatar_top(img) + if top is None or top <= 0: + return None + px = img.load() + bottom = -1 + for y in range(h - 1, -1, -1): + cnt = 0 + for x in range(0, w, 3): + p = px[x, y] + if len(p) >= 3: + r, g, b = p[0], p[1], p[2] + else: + r = g = b = p + mxv = max(r, g, b) + mnv = min(r, g, b) + if not (mxv > 235 and (mxv - mnv) < 22): + cnt += 1 + if cnt > 3: + bottom = y + break + if bottom < 0: + return None + pad = 4 + y0 = max(0, top - pad) + y1 = min(h, bottom + pad + 1) + if y1 - y0 < 8: + return None + # 水平裁剪:跳过左侧头像,找内容真正起始列 + left_x = 0 + for x in range(0, w, 2): + cnt = 0 + for y in range(y0, y1, 3): + p = px[x, y] + if len(p) >= 3: + r, g, b = p[0], p[1], p[2] + else: + r = g = b = p + mxv = max(r, g, b) + mnv = min(r, g, b) + if not (mxv > 235 and (mxv - mnv) < 22): + cnt += 1 + if cnt > 2: + left_x = x + break + if left_x < w * 0.15: + in_avatar = False + avatar_end = left_x + int(w * 0.05) + for x in range(left_x, min(w, int(w * 0.30)), 2): + cnt = 0 + for y in range(y0, y1, 3): + p = px[x, y] + if len(p) >= 3: + r, g, b = p[0], p[1], p[2] + else: + r = g = b = p + mxv = max(r, g, b) + mnv = min(r, g, b) + if not (mxv > 235 and (mxv - mnv) < 22): + cnt += 1 + if cnt <= 2: + in_avatar = True + elif in_avatar: + left_x = x + break + else: + if left_x < avatar_end: + left_x = avatar_end + # 右侧裁剪:从右向左找内容结束列,裁掉右侧空白 + right_x = w + for x in range(w - 1, left_x, -2): + cnt = 0 + for y in range(y0, y1, 3): + p = px[x, y] + if len(p) >= 3: + r, g, b = p[0], p[1], p[2] + else: + r = g = b = p + mxv = max(r, g, b) + mnv = min(r, g, b) + if not (mxv > 235 and (mxv - mnv) < 22): + cnt += 1 + if cnt > 2: + right_x = x + break + return img.crop((left_x, y0, min(w, right_x + pad + 1), y1)) + except Exception: + return None + + @staticmethod + def _crop_remove_avatar(img) -> Any: + """裁掉左侧头像区域,只保留消息内容(气泡)。 + + 从左侧扫描,找到头像与气泡之间的空白列,裁掉该列左侧的头像。 + """ + try: + w, h = img.size + if w < 50: + return img + threshold = max(3, int(h * 0.15)) + cut_x = 0 + for x in range(min(w, int(w * 0.4))): + blank = 0 + for y in range(0, h, 3): + p = img.getpixel((x, y)) + if len(p) >= 3: + r, g, b = p[0], p[1], p[2] + else: + r = g = b = p + mxv = max(r, g, b) + mnv = min(r, g, b) + if not (mxv > 235 and (mxv - mnv) < 22): + blank += 1 + if blank <= threshold: + cut_x = x + break + if cut_x > 0: + img = img.crop((cut_x, 0, w, h)) + return img + except Exception: + return img + + def _scroll_to_bottom(self, gui, ry0: int) -> None: + """将鼠标悬停在消息区中部并向下滚动,确保最后一条消息可见。""" + try: + import win32api + mx = gui.origin_x + (gui.right_pane_left + gui.render_w) // 2 + my = gui.origin_y + (115 + ry0) // 2 + win32api.SetCursorPos((mx, my)) + for _ in range(3): + gui._input.wheel(-300) + except Exception: + pass + + @staticmethod + def _bottom_has_right_content(img, ratio=0.82) -> bool: + """底部区域右侧是否有内容(自己发的消息)。 + + 自己消息的气泡贴右边缘,内容会出现在截图右侧约 18% 内;对方 + 消息内容即使很宽也极少延伸到该区域。用于判断是否需要方向裁剪 + 来避开自己刚发的消息。 + """ + try: + w, h = img.size + x0 = int(w * ratio) + cnt = 0 + for y in range(int(h * 0.4), h, 3): + for x in range(x0, w, 3): + p = img.getpixel((x, y)) + if len(p) >= 3: + r, g, b = p[0], p[1], p[2] + else: + r = g = b = p + mxv = max(r, g, b) + mnv = min(r, g, b) + if not (mxv > 235 and (mxv - mnv) < 22): + cnt += 1 + return cnt > 15 + except Exception: + return False + + def _crop_last_bubble(self, img, want_left=None) -> Optional[Any]: + """从消息区截图自动裁剪到最后一条消息的气泡内容。 + + 聊天背景为近白/浅灰,气泡内为彩色内容、头像为小尺寸彩色圆图。 + 算法:建立「非背景内容掩码」→ 全图连通域 → 按 y 方向重叠分组 + (同一消息的头像与气泡同排重叠;不同消息被行距分隔成不同组)→ + 取最底部一组,并剔除边缘的类头像小元素。 + + want_left: True 取最底部一条左侧(对方)消息;False 取最底部 + 一条右侧(自己)消息;None 取整个最底部一条(原行为)。 + """ + try: + from PIL import Image as PILImage + except Exception: + return None + + w, h = img.size + scale = max(1, int((w * h) ** 0.5 // 350)) + sw, sh = max(1, w // scale), max(1, h // scale) + small = img.convert('RGB').resize((sw, sh), PILImage.LANCZOS) + px = small.load() + + # 1. 内容掩码:非「近白/浅灰」背景像素 + mask = bytearray(sw * sh) + for y in range(sh): + base = y * sw + for x in range(sw): + r, g, b = px[x, y] + mxv = max(r, g, b) + mnv = min(r, g, b) + if mxv > 235 and (mxv - mnv) < 22: + continue + mask[base + x] = 1 + + # 2. 全图连通域(扫描线 BFS) + from collections import deque + labels = [-1] * (sw * sh) + comps = [] + for y in range(sh): + for x in range(sw): + i = y * sw + x + if not mask[i] or labels[i] != -1: + continue + labels[i] = len(comps) + area = 0 + minx = maxx = x + miny = maxy = y + dq = deque([(x, y)]) + while dq: + cx, cy = dq.popleft() + area += 1 + if cx < minx: minx = cx + if cx > maxx: maxx = cx + if cy < miny: miny = cy + if cy > maxy: maxy = cy + if cx + 1 < sw and mask[cy * sw + cx + 1] and labels[cy * sw + cx + 1] == -1: + labels[cy * sw + cx + 1] = len(comps); dq.append((cx + 1, cy)) + if cx - 1 >= 0 and mask[cy * sw + cx - 1] and labels[cy * sw + cx - 1] == -1: + labels[cy * sw + cx - 1] = len(comps); dq.append((cx - 1, cy)) + if cy + 1 < sh and mask[(cy + 1) * sw + cx] and labels[(cy + 1) * sw + cx] == -1: + labels[(cy + 1) * sw + cx] = len(comps); dq.append((cx, cy + 1)) + if cy - 1 >= 0 and mask[(cy - 1) * sw + cx] and labels[(cy - 1) * sw + cx] == -1: + labels[(cy - 1) * sw + cx] = len(comps); dq.append((cx, cy - 1)) + comps.append((area, minx, miny, maxx, maxy)) + # 过滤细长竖条(滚动条/面板边框,非消息内容) + thin_h = max(8, int(60 / scale)) + thin_w = max(3, int(12 / scale)) + comps = [c for c in comps + if not (c[4] - c[2] + 1 >= thin_h and c[3] - c[1] + 1 <= thin_w)] + if not comps: + return None + + # 3. 按 y 重叠分组:同一消息的头像/气泡同排重叠,不同消息被行距分开 + comps.sort(key=lambda c: c[2]) # 按 miny 升序 + groups = [] + for c in comps: + placed = False + for g in groups: + if c[2] <= g[1]: # 该组件顶部不高于当前组底部 => 同组 + g[0].append(c) + if c[4] > g[1]: + g[1] = c[4] + placed = True + break + if not placed: + groups.append([[c], c[4]]) + if not groups: + return None + # 选择目标消息组:从底部向上找第一组目标方向的(气泡在左=对方、 + # 在右=自己);方向不明时取最底部一组。 + # 跳过太小的组(时间戳 / 系统文字等非消息内容): + # 在原图坐标下,宽 < 30 或高 < 20 的组视为噪声跳过。 + if want_left is None: + bottom = max(groups, key=lambda g: g[1]) + else: + # 方向判定加阈值:左侧(对方)消息中心应在左 45%,右侧(自己) + # 应在右 55%。聊天里居中的时间戳(≈50%)两边都不满足,不会 + # 被误当成消息截取。 + left_max = sw * 0.45 + right_min = sw * 0.55 + min_gw = 30 + min_gh = 20 + bottom = None + for g in sorted(groups, key=lambda g: g[1], reverse=True): + comps_list = g[0] + xs = [c[1] for c in comps_list] + xe = [c[3] for c in comps_list] + ys = [c[2] for c in comps_list] + ye = [c[4] for c in comps_list] + gw = (max(xe) - min(xs) + 1) * scale + gh = (max(ye) - min(ys) + 1) * scale + if gw < min_gw or gh < min_gh: + continue + center = (min(xs) + max(xe)) / 2.0 + if want_left: + if center < left_max: + bottom = g + break + else: + if center > right_min: + bottom = g + break + if bottom is None: + bottom = max(groups, key=lambda g: g[1]) + + # 4. 底部组内:核心 = 最大连通域;只取与其 y 重叠的组件求并集 + gcomps = bottom[0] + big = max(gcomps, key=lambda c: c[0]) + _, bminx, bminy, bmaxx, bmaxy = big + big_area = big[0] + keep = [c for c in gcomps if c[2] <= bmaxy and c[4] >= bminy] or gcomps + allminx = min(c[1] for c in keep) + allminy = min(c[2] for c in keep) + allmaxx = max(c[3] for c in keep) + allmaxy = max(c[4] for c in keep) + bbox = [allminx, allminy, allmaxx, allmaxy] + + # 5. 剔除左/右边缘的头像类小元素(面积 < 核心 40% 且较窄) + max_av = int(90 / scale) # 头像直径约 90 逻辑像素 + left_comp = min(keep, key=lambda c: c[1]) + right_comp = max(keep, key=lambda c: c[3]) + for is_left, comp in ((True, left_comp), (False, right_comp)): + if is_left and comp[1] != allminx: + continue + if not is_left and comp[3] != allmaxx: + continue + ea, eminx, eminy, emaxx, emaxy = comp + if ea < big_area * 0.4 and (emaxx - eminx + 1) <= max_av: + if is_left: + bbox[0] = max(bminx, emaxx + 1) + else: + bbox[2] = min(bmaxx, eminx - 1) + + # 6. 换算回原图并加边距 + # 圆形表情顶部/底部在缩放时因 LANCZOS 模糊丢失边缘像素; + # 缩放倍数越高丢失越多(约 2-5 个缩放像素),用 scale*5 补偿 + pad = max(10, scale * 5) + x0 = max(0, bbox[0] * scale - pad) + y0 = max(0, bbox[1] * scale - pad) + x1 = min(w, (bbox[2] + 1) * scale + pad) + y1 = min(h, (bbox[3] + 1) * scale + pad) + if x1 - x0 < 8 or y1 - y0 < 8: + return None + # 7. 全分辨率边缘扩展:找回缩放时丢失的边缘像素 + # 逐像素采样确保圆形窄边缘不被遗漏; + # 向上/向下遇连续空白行(消息间分隔)停止,避免吃进相邻消息 + try: + px = img.load() + gap_threshold = 3 + + def _is_bg(x, y): + p = px[x, y][:3] + mxv = max(p) + return mxv > 235 and (mxv - min(p)) < 22 + + def _row_cnt(y, ax0, ax1): + return sum(1 for x in range(ax0, ax1) if not _is_bg(x, y)) + + # 向上扩展:逐行上移,遇连续空白行则停 + for y in range(y0 - 1, max(0, y0 - pad * 4), -1): + if _row_cnt(y, x0, x1) > 2: + y0 = y + else: + blank = all(_row_cnt(yy, x0, x1) <= 2 + for yy in range(y, min(y0, y + gap_threshold))) + if blank: + break + # 向下扩展 + for y in range(y1, min(h, y1 + pad * 4)): + if _row_cnt(y, x0, x1) > 2: + y1 = y + 1 + else: + blank = all(_row_cnt(yy, x0, x1) <= 2 + for yy in range(max(y1, y - gap_threshold + 1), y + 1)) + if blank: + break + # 向左扩展 + for x in range(x0 - 1, max(0, x0 - pad * 4), -1): + cnt = sum(1 for y in range(y0, y1) if not _is_bg(x, y)) + if cnt > 2: + x0 = x + else: + break + # 向右扩展 + for x in range(x1, min(w, x1 + pad * 4)): + cnt = sum(1 for y in range(y0, y1) if not _is_bg(x, y)) + if cnt > 2: + x1 = x + 1 + else: + break + except Exception: + pass + if x1 - x0 < 8 or y1 - y0 < 8: + return None + return img.crop((x0, y0, x1, y1)) + + +class VideoMessage(BaseMessage): + type = 'video' + repattern = r'视频(\d+):(\d+)' + + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + @property + def video(self): + """打开并返回视频预览窗口实例""" + from wechatauto.ui.component import WeChatImage + self.roll_into_view() + self.control.Click() + return WeChatImage(self) + + def save(self, dir_path=None, timeout=10): + """保存视频 + + Args: + dir_path (str): 保存文件夹路径 + timeout (int, optional): 保存超时时间,默认10秒 + + Returns: + Path: 文件保存路径 + """ + preview = self.video + if not preview.control: + return WxResponse.failure('未找到视频预览窗口') + return preview.save(dir_path, timeout) + + +class FileMessage(BaseMessage): + type = 'file' + repattern = r"^文件\n([^\n]+)\n(\d+(\.\d+)?)(B|KB|MB|GB|TB)\n微信电脑版$" + + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + self._parse() + + def _parse(self): + match = re.search(self.repattern, self.content) + if match: + self.filename = match.group(1) + self.filesize = float(match.group(2)) + self.sizeunit = match.group(4) + else: + self.filename = None + self.filesize = None + self.sizeunit = None + + +class LinkMessage(BaseMessage): + type = 'link' + + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + +class LocationMessage(BaseMessage): + type = 'location' + + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + +class PersonalCardMessage(BaseMessage): + type = 'personal_card' + + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + +class OtherMessage(BaseMessage): + type = 'other' + + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) diff --git a/wechatauto/msgs/self.py b/wechatauto/msgs/self.py new file mode 100644 index 0000000..b20a79b --- /dev/null +++ b/wechatauto/msgs/self.py @@ -0,0 +1,112 @@ +from .mattr import * +from .mtype import * + + +class SelfTextMessage(SelfMessage, TextMessage): + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + +class SelfQuoteMessage(SelfMessage, QuoteMessage): + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + +class SelfImageMessage(SelfMessage, ImageMessage): + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + +class SelfEmojiMessage(SelfMessage, EmojiMessage): + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + +class SelfFileMessage(SelfMessage, FileMessage): + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + +class SelfVideoMessage(SelfMessage, VideoMessage): + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + +class SelfVoiceMessage(SelfMessage, VoiceMessage): + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + +class SelfLinkMessage(SelfMessage, LinkMessage): + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + +class SelfLocationMessage(SelfMessage, LocationMessage): + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + +class SelfPersonalCardMessage(SelfMessage, PersonalCardMessage): + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) + + +class SelfOtherMessage(SelfMessage, OtherMessage): + def __init__( + self, + control: uia.Control, + parent: "ChatBox", + additonal_attr: Dict[str, Any] = {} + ): + super().__init__(control, parent, additonal_attr) diff --git a/wechatauto/param.py b/wechatauto/param.py new file mode 100644 index 0000000..9a655d5 --- /dev/null +++ b/wechatauto/param.py @@ -0,0 +1,75 @@ +from typing import Literal +import os + +PROJECT_NAME = 'wechatauto' + +class WxParam: + # 语言设置 + LANGUAGE: Literal['cn', 'cn_t', 'en'] = 'cn' + + # 是否启用日志文件 + ENABLE_FILE_LOGGER: bool = True + + # 下载文件/图片默认保存路径 + DEFAULT_SAVE_PATH: str = os.path.join(os.getcwd(), 'wechatauto文件下载') + + # 是否启用消息哈希值用于辅助判断消息,开启后会稍微影响性能 + MESSAGE_HASH: bool = False + + # 头像到消息X偏移量,用于消息定位,点击消息等操作 + DEFAULT_MESSAGE_XBIAS = 51 + DEFAULT_MESSAGE_YBIAS = 30 + + # 是否强制重新自动获取X偏移量,如果设置为True,则每次启动都会重新获取 + FORCE_MESSAGE_XBIAS: bool = False + + # 监听消息时间间隔,单位秒 + LISTEN_INTERVAL: int = 1 + + # 监听执行器线程池大小 + LISTENER_EXCUTOR_WORKERS: int = 4 + + # 搜索聊天对象超时时间,单位秒 + SEARCH_CHAT_TIMEOUT: int = 2 + + # 微信笔记加载超时时间,单位秒 + NOTE_LOAD_TIMEOUT: int = 30 + + # 发送文件超时时间,单位秒 + SEND_FILE_TIMEOUT: int = 10 + +class WxResponse(dict): + def __init__(self, status: str, message: str, data: dict = None): + super().__init__(status=status, message=message, data=data) + + def __str__(self): + return str(self.to_dict()) + + def __repr__(self): + return str(self.to_dict()) + + def to_dict(self): + return { + 'status': self['status'], + 'message': self['message'], + 'data': self['data'] + } + + def __bool__(self): + return self.is_success + + @property + def is_success(self): + return self['status'] == '成功' + + @classmethod + def success(cls, message=None, data: dict = None): + return cls(status="成功", message=message, data=data) + + @classmethod + def failure(cls, message: str, data: dict = None): + return cls(status="失败", message=message, data=data) + + @classmethod + def error(cls, message: str, data: dict = None): + return cls(status="错误", message=message, data=data) diff --git a/wechatauto/py.typed b/wechatauto/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/wechatauto/sender.py b/wechatauto/sender.py new file mode 100644 index 0000000..863e435 --- /dev/null +++ b/wechatauto/sender.py @@ -0,0 +1,220 @@ +# -*- coding: utf-8 -*- +"""微信 4.x UI 自动化(发送消息) + +微信 4.x 主窗口是完全自绘的(MMUIRenderSubWindow*,不同版本后缀不同),UIA 树不可用, +因此采用坐标模拟:激活窗口 → 点击搜索框 → 输入联系人关键词 → Enter +打开会话 → 点击输入框 → 输入文本 → Enter 发送。 + +坐标是相对窗口的逻辑坐标(自绘 UI 版本差异可能导致偏移,可调整常量)。 +验证通过后,可通过读回数据库确认消息是否发送成功(sender_id=2)。 +""" + +from __future__ import annotations + +import ctypes +import time +from ctypes import wintypes + +_user32 = ctypes.WinDLL("user32", use_last_error=True) +_kernel32 = ctypes.WinDLL("kernel32", use_last_error=True) + +_user32.FindWindowW.restype = wintypes.HWND +_user32.FindWindowW.argtypes = [wintypes.LPCWSTR, wintypes.LPCWSTR] +_user32.GetWindowRect.argtypes = [wintypes.HWND, ctypes.POINTER(wintypes.RECT)] +_user32.GetWindowRect.restype = wintypes.BOOL +_user32.SetForegroundWindow.argtypes = [wintypes.HWND] +_user32.SetForegroundWindow.restype = wintypes.BOOL +_user32.ShowWindow.argtypes = [wintypes.HWND, ctypes.c_int] +_user32.ShowWindow.restype = wintypes.BOOL +_user32.SetCursorPos.argtypes = [ctypes.c_int, ctypes.c_int] +_user32.SetCursorPos.restype = wintypes.BOOL +_user32.GetDpiForWindow.argtypes = [wintypes.HWND] +_user32.GetDpiForWindow.restype = wintypes.UINT + +# WeChat 4.x 主窗口类名 +MAIN_WND_CLASS = "Qt51514QWindowIcon" + + +def _restore_keep_maximize(hwnd: int): + """取消最小化并显示窗口,同时保留其最大化状态。 + + ``ShowWindow(hwnd, SW_RESTORE)`` 会把最大化窗口恢复为普通大小(窗口被 + 缩小)。先用 ``GetWindowPlacement`` 记录最大化状态:原为最大化则用 + ``SW_SHOWMAXIMIZED`` 恢复,否则才走 ``SW_RESTORE``。 + """ + if not hwnd or not _user32.IsWindow(hwnd): + return + + class _POINT(ctypes.Structure): + _fields_ = [("x", wintypes.LONG), ("y", wintypes.LONG)] + + class _WINDOWPLACEMENT(ctypes.Structure): + _fields_ = [ + ("length", wintypes.UINT), + ("flags", wintypes.UINT), + ("showCmd", wintypes.UINT), + ("ptMinPosition", _POINT), + ("ptMaxPosition", _POINT), + ("rcNormalPosition", wintypes.RECT), + ] + + wp = _WINDOWPLACEMENT() + wp.length = ctypes.sizeof(_WINDOWPLACEMENT) + if _user32.GetWindowPlacement(hwnd, ctypes.byref(wp)): + if wp.showCmd == 3: # SW_SHOWMAXIMIZED + _user32.ShowWindow(hwnd, 3) # 保持/恢复最大化 + return + _user32.ShowWindow(hwnd, 9) # SW_RESTORE + +INPUT_EVENT = 0x0002 +KEYEVENTF_KEYUP = 0x0002 +KEYEVENTF_UNICODE = 0x0004 +VK_RETURN = 0x0D +WM_KEYUP = 0x0101 + + +def _ensure_dpi_aware(): + try: + _kernel32.SetProcessDpiAwarenessContext(ctypes.c_void_p(-4)) # PER_MONITOR_AWARE_V2 + except Exception: + pass + + +class KEYBDINPUT(ctypes.Structure): + _fields_ = [ + ("wVk", wintypes.WORD), + ("wScan", wintypes.WORD), + ("dwFlags", wintypes.DWORD), + ("time", wintypes.DWORD), + ("dwExtraInfo", ctypes.c_size_t), + ] + + +class MOUSEINPUT(ctypes.Structure): + _fields_ = [ + ("dx", wintypes.LONG), + ("dy", wintypes.LONG), + ("mouseData", wintypes.DWORD), + ("dwFlags", wintypes.DWORD), + ("time", wintypes.DWORD), + ("dwExtraInfo", ctypes.c_size_t), + ] + + +class _INPUT_UNION(ctypes.Union): + _fields_ = [ + ("ki", KEYBDINPUT), + ("mi", MOUSEINPUT), + ] + + +class _INPUT(ctypes.Structure): + _fields_ = [ + ("type", wintypes.DWORD), + ("union", _INPUT_UNION), + ] + + +def _send_input(scan: int = 0, unicode_char: str = "", flags: int = 0): + inp = _INPUT() + inp.type = INPUT_EVENT + inp.union.ki.wVk = 0 + inp.union.ki.wScan = ord(unicode_char) if unicode_char else scan + inp.union.ki.dwFlags = flags | KEYEVENTF_UNICODE if unicode_char else flags + inp.union.ki.time = 0 + inp.union.ki.dwExtraInfo = 0 + _user32.SendInput(1, ctypes.byref(inp), ctypes.sizeof(_INPUT)) + + +def type_text(text: str, delay: float = 0.01): + """用 Unicode 输入事件键入文本(含中文)""" + for ch in text: + _send_input(unicode_char=ch, flags=0) + _send_input(unicode_char=ch, flags=KEYEVENTF_KEYUP) + time.sleep(delay) + + +def press_enter(): + _send_input(scan=VK_RETURN, flags=0) + _send_input(scan=VK_RETURN, flags=KEYEVENTF_KEYUP) + + +def click(x: int, y: int): + _user32.SetCursorPos(x, y) + time.sleep(0.08) + _user32.mouse_event(0x0002, 0, 0, 0, 0) # LEFTDOWN + _user32.mouse_event(0x0004, 0, 0, 0, 0) # LEFTUP + + +def find_main_window(): + """返回主窗口句柄(或 None)。先按类名,失败再按标题兜底(兼容不同版本类名)。""" + hwnd = _user32.FindWindowW(MAIN_WND_CLASS, None) + if hwnd: + return hwnd + return _user32.FindWindowW(None, "微信") or None + + +def window_rect(hwnd): + r = wintypes.RECT() + _user32.GetWindowRect(hwnd, ctypes.byref(r)) + return (r.left, r.top, r.right, r.bottom) + + +def dpi_scale(hwnd) -> float: + return _user32.GetDpiForWindow(hwnd) / 96.0 + + +class WeChatUI: + """微信 4.x 发送工具(坐标模拟)""" + + # 逻辑坐标(相对窗口左上角),自绘 UI 版本差异可在此调整 + SEARCH_BOX = (140, 60) # 顶部搜索框 + INPUT_BOX = (0.55, 0.88) # 输入框(相对窗口宽/高比例) + + def __init__(self, hwnd=None): + _ensure_dpi_aware() + self.hwnd = hwnd or find_main_window() + if not self.hwnd: + raise RuntimeError("未找到微信主窗口") + + def activate(self): + _restore_keep_maximize(self.hwnd) + _user32.SetForegroundWindow(self.hwnd) + time.sleep(0.5) + + def _pt(self, lx, ly): + """逻辑坐标 → 屏幕物理坐标""" + left, top, right, bottom = window_rect(self.hwnd) + w, h = right - left, bottom - top + if isinstance(lx, float): + lx = w * lx + if isinstance(ly, float): + ly = h * ly + return int(left + lx), int(top + ly) + + def open_chat(self, keyword: str): + """通过顶部搜索框打开会话(搜索 → Enter 选中第一项)""" + self.activate() + x, y = self._pt(*self.SEARCH_BOX) + click(x, y) + time.sleep(0.6) + type_text(keyword) + time.sleep(0.8) + press_enter() + time.sleep(1.0) + + def send(self, text: str): + """向当前打开的会话发送文本""" + self.activate() + x, y = self._pt(*self.INPUT_BOX) + click(x, y) + time.sleep(0.4) + type_text(text) + time.sleep(0.2) + press_enter() + time.sleep(0.6) + + def send_to(self, keyword: str, text: str): + """搜索并打开会话后发送""" + self.open_chat(keyword) + self.send(text) diff --git a/wechatauto/ui/__init__.py b/wechatauto/ui/__init__.py new file mode 100644 index 0000000..149ecf7 --- /dev/null +++ b/wechatauto/ui/__init__.py @@ -0,0 +1,23 @@ +from wechatauto.ui.base import BaseUISubWnd, BaseUIWnd +from wechatauto.ui.main import WeChatMainWnd, WeChatSubWnd +from wechatauto.ui.navigationbox import NavigationBox +from wechatauto.ui.sessionbox import SessionBox, SessionElement, SearchResultElement +from wechatauto.ui.chatbox import ChatBox, AtMenu +from wechatauto.ui.component import Menu, SelectContactWnd, WeChatImage, UpdateWindow + +__all__ = [ + "BaseUISubWnd", + "BaseUIWnd", + "WeChatMainWnd", + "WeChatSubWnd", + "NavigationBox", + "SessionBox", + "SessionElement", + "SearchResultElement", + "ChatBox", + "AtMenu", + "Menu", + "SelectContactWnd", + "WeChatImage", + "UpdateWindow", +] diff --git a/wechatauto/ui/base.py b/wechatauto/ui/base.py new file mode 100644 index 0000000..1ce4f1d --- /dev/null +++ b/wechatauto/ui/base.py @@ -0,0 +1,64 @@ +from wechatauto import uia +from wechatauto.param import PROJECT_NAME +from wechatauto.logger import wxlog +from wechatauto.utils.lock import uilock +from abc import ABC, abstractmethod +import win32gui +from typing import Union +import time + + +class BaseUIWnd(ABC): + _ui_cls_name: str = None + _ui_name: str = None + control: uia.Control + + @abstractmethod + def _lang(self, text: str): pass + + def __repr__(self): + return f"<{PROJECT_NAME} - {self.__class__.__name__} at {hex(id(self))}>" + + def __eq__(self, other): + return self.control == other.control + + def __bool__(self): + return self.exists() + + def _show(self): + if not hasattr(self, 'HWND'): + self.HWND = self.control.GetTopLevelControl().NativeWindowHandle + win32gui.ShowWindow(self.HWND, 1) + win32gui.SetWindowPos(self.HWND, -1, 0, 0, 0, 0, 3) + win32gui.SetWindowPos(self.HWND, -2, 0, 0, 0, 0, 3) + self.control.Show() + + @property + def pid(self): + return self.control.ProcessId + + @uilock + def close(self): + try: + for i in range(2): + self.control.SendKeys('{Esc}') + except Exception: + pass + + def exists(self, wait=0): + try: + result = self.control.Exists(wait) + return result + except Exception: + return False + + +class BaseUISubWnd(BaseUIWnd): + root: BaseUIWnd + parent: None + + def _lang(self, text: str): + if getattr(self, 'parent'): + return self.parent._lang(text) + else: + return self.root._lang(text) diff --git a/wechatauto/ui/chatbox.py b/wechatauto/ui/chatbox.py new file mode 100644 index 0000000..ef7916d --- /dev/null +++ b/wechatauto/ui/chatbox.py @@ -0,0 +1,400 @@ +from wechatauto import uia +from wechatauto.param import ( + WxParam, + WxResponse, +) +from wechatauto.utils.win32 import ( + SetClipboardFiles, + SetClipboardData, + SetClipboardText +) +from wechatauto.ui.component import ( + Menu +) +from wechatauto.logger import wxlog +from .base import ( + BaseUISubWnd +) +from wechatauto.msgs.msg import parse_msg + +import time +import os +import re +from typing import Iterable, Optional, Sequence, Tuple, Union + +def truncate_string(s: str, n: int = 8) -> str: + s = s.replace('\n', '').strip() + return s if len(s) <= n else s[:n] + '...' + +USED_MSG_IDS = {} +LAST_MSG_COUNT = {} + +class ChatBox(BaseUISubWnd): + """聊天窗口区域""" + + def __init__(self, control: uia.Control, parent): + self.control: uia.Control = control + self.root = parent.root + self.parent = parent # `wx` or `chat` + self.init() + + def _lang(self, text: str): + return text + + @property + def id(self): + if self.msgbox.Exists(0): + return self.msgbox.runtimeid + return None + + @property + def used_msg_ids(self): + if self.id in USED_MSG_IDS: + return USED_MSG_IDS[self.id] + else: + USED_MSG_IDS[self.id] = tuple() + return USED_MSG_IDS[self.id] + + @property + def who(self): + if hasattr(self, '_who'): + return self._who + self._who = self.editbox.Name + return self._who + + def get_info(self): + chat_info = {} + chat_info_control = self.control.GetParentControl().GroupControl(ClassName="mmui::ChatInfoView") + aid_head = 'top_content_h_view.top_spacing_v_view.top_left_info_v_view.big_title_line_h_view.' + v_view = "top_content_h_view.top_spacing_v_view.top_left_info_v_view" + aids = { + 'chatname': "current_chat_name_label", + 'chat_count': "current_chat_count_label", + 'company': "current_chat_openim_name", + 'comicon': "openim_icon" + } + chat_info['chat_type'] = 'friend' + for aid in aids: + control = chat_info_control.TextControl( + AutomationId=aid_head + aids[aid] + ) + if control.Exists(0): + if aid == 'chatname': + chat_info['chat_name'] = control.Name + if ( + 'chat_remark' not in chat_info + and (cnc := chat_info_control.GroupControl(AutomationId=v_view).GroupControl().TextControl()).Exists(0) + ): + chat_info['chat_remark'] = chat_info['chat_name'] + chat_info['chat_name'] = cnc.Name + + elif aid == 'chat_count': + chat_info['group_member_count'] = int(re.findall(r'\d+', control.Name)[0]) + chat_info['chat_type'] = 'group' + elif aid == 'company': + chat_info['chat_type'] = 'service' + if chat_info_control.ButtonControl(Name="公众号主页").Exists(0): + chat_info['chat_type'] = 'official' + return chat_info + + def _activate_editbox(self): + if not self.editbox.HasKeyboardFocus: + self.editbox.MiddleClick() + + def init(self): + self.msgbox = self.control.GroupControl(ClassName="mmui::MessageView").ListControl() + self.editbox = self.control.EditControl(ClassName="mmui::ChatInputField") + self.sendbtn = self.control.ButtonControl(Name=self._lang('发送(S)')) + self.tools = self.control.ToolBarControl() + self._empty = False + if (cid := self.id) and cid not in USED_MSG_IDS: + USED_MSG_IDS[self.id] = tuple((i.runtimeid for i in self.msgbox.GetChildren())) + if not USED_MSG_IDS[cid]: + self._empty = True + + def clear_edit(self): + self._show() + self.editbox.Click() + self.editbox.SendKeys('{Ctrl}a', waitTime=0) + self.editbox.SendKeys('{DELETE}') + + def send_text(self, content: str): + self._show() + t0 = time.time() + while True: + if time.time() - t0 > 10: + return WxResponse.failure(f'Timeout --> {self.who} - {content}') + SetClipboardText(content) + self._activate_editbox() + self.editbox.SendKeys('{Ctrl}v') + if self.editbox.GetValuePattern().Value.replace('', '').strip(): + break + self.editbox.SendKeys('{Ctrl}v') + if self.editbox.GetValuePattern().Value.replace('', '').strip(): + break + self.editbox.RightClick() + menu = Menu(self) + menu.select('粘贴') + if self.editbox.GetValuePattern().Value.replace('', '').strip(): + break + t0 = time.time() + while self.editbox.GetValuePattern().Value: + if time.time() - t0 > 10: + return WxResponse.failure(f'Timeout --> {self.who} - {content}') + self._activate_editbox() + + self.sendbtn.Click() + if not self.editbox.GetValuePattern().Value: + return WxResponse.success(f"success") + elif not self.editbox.GetValuePattern().Value.replace('', '').strip(): + return self.send_text(content) + + def send_msg(self, content: str, clear: bool = True, at=None): + wxlog.debug(f"发送消息: {content}") + if not content and not at: + return WxResponse.failure(f"`content` and `at` can't be empty at the same time") + + if clear: + self.clear_edit() + if at: + self.input_at(at) + + return self.send_text(content) + + def send_file(self, file_path): + wxlog.debug(f"发送文件: {file_path}") + if isinstance(file_path, str): + file_path = [file_path] + file_path = [os.path.abspath(f) for f in file_path] + + self.clear_edit() + + SetClipboardFiles(file_path) + self.editbox.SendKeys('{Ctrl}v') + self.sendbtn.Click() + + def input_at(self, at_list): + if isinstance(at_list, str): + at_list = [at_list] + self._activate_editbox() + for friend in at_list: + self.editbox.SendKeys('@' + friend.replace(' ', '')) + atmenu = AtMenu(self) + atmenu.select(friend) + + def get_msgs(self): + if self.msgbox.Exists(0): + return [ + parse_msg(msg_control, self) + for msg_control in self._iter_message_controls() + if uia.IsElementInWindow(self.msgbox, msg_control) + ] + return [] + + def get_new_msgs(self): + if not self.msgbox.Exists(0): + return [] + msg_controls = self.msgbox.GetChildren() + now_msg_ids = tuple((i.runtimeid for i in msg_controls)) + current_msg_count = len(now_msg_ids) + + if not now_msg_ids: # 当前没有消息id + return [] + + # 确保used_msg_ids不为None + current_used_ids = self.used_msg_ids or tuple() + + if self._empty and current_used_ids: + self._empty = False + + # 获取上次记录的消息数量 + last_msg_count = LAST_MSG_COUNT.get(self.id, 0) + + # 如果没有历史消息id,初始化 + if not current_used_ids: + if not self._empty: + # 初始化时记录当前所有消息id和数量 + USED_MSG_IDS[self.id] = now_msg_ids[-100:] + LAST_MSG_COUNT[self.id] = current_msg_count + return [] + + # 关键改进:基于消息数量变化的检测机制 + msg_count_increased = current_msg_count > last_msg_count + + if msg_count_increased: + # 消息数量增加了,计算新消息数量 + new_msg_count = current_msg_count - last_msg_count + + # 取最后N条消息作为候选新消息 + candidate_new_ids = now_msg_ids[-new_msg_count:] + + # 验证这些ID确实是新的(排除可能的ID重用情况) + used_msg_ids_set = set(current_used_ids) + confirmed_new_ids = [] + + for msg_id in candidate_new_ids: + if msg_id not in used_msg_ids_set: + confirmed_new_ids.append(msg_id) + # 即使ID重复,如果消息数量确实增加了,也要包含这条消息 + # 这是处理快速重复消息的关键逻辑 + elif msg_count_increased and len(confirmed_new_ids) < new_msg_count: + # 对于疑似重复ID的情况,仍然当作新消息处理 + confirmed_new_ids.append(msg_id) + + if confirmed_new_ids: + # 更新记录 + USED_MSG_IDS[self.id] = now_msg_ids[-100:] + LAST_MSG_COUNT[self.id] = current_msg_count + + # 根据新消息id获取对应的控件 + new_controls = [i for i in msg_controls if i.runtimeid in confirmed_new_ids] + + return [ + parse_msg(msg_control, self) + for msg_control + in new_controls + if msg_control.ControlTypeName == 'ListItemControl' + ] + + # 如果消息数量没有增加,但可能有ID变化(处理消息刷新的情况) + used_msg_ids_set = set(current_used_ids) + new_ids = [msg_id for msg_id in now_msg_ids if msg_id not in used_msg_ids_set] + + if new_ids: + # 更新记录 + USED_MSG_IDS[self.id] = now_msg_ids[-100:] + LAST_MSG_COUNT[self.id] = current_msg_count + + # 根据新消息id获取对应的控件 + new_controls = [i for i in msg_controls if i.runtimeid in new_ids] + + return [ + parse_msg(msg_control, self) + for msg_control + in new_controls + if msg_control.ControlTypeName == 'ListItemControl' + ] + + return [] + + def _update_used_msg_ids(self): + if not self.msgbox.Exists(0): + USED_MSG_IDS[self.id] = tuple() + LAST_MSG_COUNT[self.id] = 0 + return + msg_controls = [ + ctrl for ctrl in self.msgbox.GetChildren() + if ctrl.ControlTypeName == 'ListItemControl' + ] + if not msg_controls: + USED_MSG_IDS[self.id] = tuple() + LAST_MSG_COUNT[self.id] = 0 + return + USED_MSG_IDS[self.id] = tuple(ctrl.runtimeid for ctrl in msg_controls[-100:]) + LAST_MSG_COUNT[self.id] = len(msg_controls) + + def _iter_message_controls(self) -> Iterable[uia.Control]: + if not self.msgbox.Exists(0): + return [] + return [ + ctrl + for ctrl in self.msgbox.GetChildren() + if ctrl.ControlTypeName == 'ListItemControl' + ] + + def _normalize_msg_id(self, msg_id: Union[Sequence[int], str, None]) -> Optional[str]: + """将用户传入的消息ID归一化为 runtimeid 字符串形式。 + + 兼容传入:字符串(如消息对象的 ``msg.id``)或 RuntimeId 整数序列。 + """ + if msg_id is None: + return None + if isinstance(msg_id, str): + parts = re.findall(r"\d+", msg_id) + if not parts: + return None + return ''.join(parts) + if isinstance(msg_id, (tuple, list)): + try: + return ''.join(str(int(p)) for p in msg_id) + except (TypeError, ValueError): + return None + return None + + def get_msg_by_id(self, msg_id: Union[Sequence[int], str]) -> Optional['Message']: + normalized_id = self._normalize_msg_id(msg_id) + if normalized_id is None: + return None + for msg_control in self._iter_message_controls(): + if msg_control.runtimeid == normalized_id: + return parse_msg(msg_control, self) + return None + + def get_msg_by_hash(self, msg_hash: str) -> Optional['Message']: + if not msg_hash: + return None + msg_hash = msg_hash.strip() + is_digest = bool(re.fullmatch(r"[0-9a-fA-F]{32}", msg_hash)) + controls = list(self._iter_message_controls()) + for msg_control in reversed(controls): + msg = parse_msg(msg_control, self) + candidate = msg.hash if is_digest else getattr(msg, 'hash_text', None) + if candidate == msg_hash: + return msg + return None + + def get_last_msg(self) -> Optional['Message']: + message_controls = list(self._iter_message_controls()) + if not message_controls: + return None + return parse_msg(message_controls[-1], self) + + +class AtEle: + def __init__(self, control): + self.name = control.Name + self.control = control + + +class AtMenu(BaseUISubWnd): + _ui_cls_name: str = "mmui::XPopover" + _ui_name: str = "Weixin" + _ui_automation_id = "MentionPopover" + + def __init__(self, parent): + self.root = parent.root + self.control = self.root.control.WindowControl( + ClassName=self._ui_cls_name, + Name=self._ui_name, + AutomationId=self._ui_automation_id + ) + + def clear(self, friend): + if self.exists(): + self.control.SendKeys('{ESC}') + for _ in range(len(friend) + 1): + self.root._chat_api.editbox.SendKeys('{BACK}') + + def select(self, friend): + friend_ = friend.replace(' ', '') + if self.exists(): + ateles = self.control.ListControl().GetChildren() + if len(ateles) == 1: + ateles[0].Click() + return WxResponse.success() + + else: + atele = self.control.ListItemControl(Name=friend) + if atele.Exists(0): + uia.RollIntoView(self.control, atele) + atele.Click() + return WxResponse.success() + else: + self.clear(friend_) + return WxResponse.failure('@对象不存在') + else: + self.clear(friend_) + return WxResponse.failure('@选择窗口不存在') + + def list(self): + return [AtEle(i) for i in self.control.ListControl().GetChildren()] diff --git a/wechatauto/ui/component.py b/wechatauto/ui/component.py new file mode 100644 index 0000000..8d60400 --- /dev/null +++ b/wechatauto/ui/component.py @@ -0,0 +1,305 @@ +from wechatauto import uia +from wechatauto.utils.win32 import ( + FindWindow, + GetAllWindows, + SetClipboardText, + ReadClipboardData +) +from wechatauto.utils.tools import ( + find_window_from_root, + find_all_windows_from_root, + is_valid_image, + get_file_dir, + now_time, +) +from .base import BaseUISubWnd +from wechatauto.param import WxParam, WxResponse +from wechatauto.logger import wxlog +from pathlib import Path +from typing import ( + List, + Literal +) +import traceback +import shutil +import time +import os + + +def _find_popup(ui_cls_name: str, win_cls_name: str, win_name: str = None, pid: int = None, timeout: float = 2): + """查找微信弹窗/浮层窗口。 + + 优先按 UIA 类名匹配(不受 Qt 版本影响),失败时回退到 win32 窗口类名匹配。 + """ + t0 = time.time() + while True: + if time.time() - t0 > timeout: + break + wins = find_all_windows_from_root(pid=pid, uiaclsname=ui_cls_name) + if len(wins) > 0: + return wins[0] + wins = find_all_windows_from_root(classname=win_cls_name, name=win_name, pid=pid) + if len(wins) > 0: + return wins[0] + time.sleep(0.05) + return None + + +class UpdateWindow(BaseUISubWnd): + """微信更新提示窗口""" + + _ui_cls_name: str = "mmui::XView" + _win_cls_name: str = "Qt51514QWindowIcon" + _win_name: str = "微信" + + def __init__(self): + wins = GetAllWindows(name=self._win_name, classname=self._win_cls_name) + for win in wins: + self.control = uia.ControlFromHandle(win[0]) + if ( + (text := self.control.TextControl()).Exists(0) + and text.Name == '新版本' + ): + break + + def ignore(self): + ignore_btn = self.control.ButtonControl( + ClassName="mmui::XOutlineButton", + Name="忽略本次更新" + ) + if ignore_btn.Exists(0): + ignore_btn.Click() + + +class Menu(BaseUISubWnd): + """右键菜单窗口""" + + _ui_cls_name: str = "mmui::XMenu" + _win_cls_name: str = "Qt51514QWindowToolSaveBits" + _win_name: str = "Weixin" + + def __init__(self, parent, timeout=2): + self.parent = parent + self.root = parent.root + self.control = _find_popup( + ui_cls_name=self._ui_cls_name, + win_cls_name=self._win_cls_name, + win_name=self._win_name, + pid=self.root.pid, + timeout=timeout, + ) + + @property + def option_controls(self): + if not self.control: + return [] + return [ + i for i in + self.control.GetChildren() + if i.ControlTypeName == 'MenuItemControl' + ] + + @property + def option_names(self): + return [c.Name for c in self.option_controls] + + def select(self, item): + if not self.control or not self.exists(0): + return WxResponse.failure('菜单窗口不存在') + if isinstance(item, int): + options = self.option_controls + if item >= len(options): + return WxResponse.failure(f'菜单选项越界:{item}') + options[item].Click() + return WxResponse.success() + + for c in self.option_controls: + if c.Name == item: + c.Click() + return WxResponse.success() + if self.exists(0): + self.close() + return WxResponse.failure(f'未找到选项:{item}') + + +class SelectContactWnd(BaseUISubWnd): + """转发消息时的联系人选择窗口""" + + _ui_cls_name: str = "mmui::SessionPickerWindow" + _ui_name: str = "微信发送给" + _win_cls_name: str = "Qt51514QWindowIcon" + _win_name: str = "微信发送给" + + def __init__(self, parent, timeout=2): + self.parent = parent + self.root = parent.root + self.control = _find_popup( + ui_cls_name=self._ui_cls_name, + win_cls_name=self._win_cls_name, + win_name=self._win_name, + pid=self.root.pid, + timeout=timeout, + ) + if self.control: + self.confirm_btn = self.control.ButtonControl(AutomationId="confirm_btn") + + def search(self, keyword, interval=0.1): + """搜索并选择,需完全匹配""" + search_control = self.control.EditControl(ClassName="mmui::XValidatorTextEdit") + SetClipboardText(keyword) + search_control.Click() + search_control.SendKeys('{Ctrl}a') + search_control.RightClick() + menu = Menu(self) + menu.select('粘贴') + time.sleep(interval) + all_controls = [] + for c, d in uia.WalkControl(self.control): + all_controls.append(c) + for target in all_controls: + if ( + target.ControlTypeName == 'CheckBoxControl' + and target.Name == keyword + ): + target.Click() + return True + + def confirm(self): + self.confirm_btn.Click() + + def send(self, target, interval=0.1): + if isinstance(target, str): + target = [target] + + for i in target: + self.search(i, interval) + + self.confirm() + + +class SearchNewFriendWnd(BaseUISubWnd): + """添加朋友窗口""" + + _win_cls_name: str = 'Qt51514QWindowIcon' + _win_name: str = "添加朋友" + + def __init__(self): + self.control = find_window_from_root(classname=self._win_cls_name, name=self._win_name) + if self.control: + self.init() + + def init(self): + self.apply_btn = self.control.ButtonControl( + AutomationId="fixed_height_v_view.content_v_view.ContactProfileBottomUi.add_friend_button", + Name="添加到通讯录", + ClassName="mmui::XOutlineButton", + searchDepth=9 + ) + self.search_edit = self.control.EditControl(ClassName="mmui::XValidatorTextEdit", Name="搜索") + self.search_btn = self.control.ButtonControl(ClassName="mmui::XOutlineButton", Name="搜索") + + def search(self, keyword): + self.search_edit.SendKeys('{Ctrl}a') + SetClipboardText(keyword) + self.search_edit.SendKeys('{Ctrl}v') + self.search_btn.Click() + + def apply(self): + if self.apply_btn.Exists(0): + self.apply_btn.Click() + return WxResponse.success() + else: + return WxResponse.failure('未找到添加按钮') + + +class WeChatImage(BaseUISubWnd): + """图片/视频预览窗口""" + + _win_cls_name: str = 'Qt51514QWindowIcon' + _win_name: str = "预览" + + def __init__(self, parent): + self.parent = parent + self.root = self.parent.root + self.control = find_window_from_root(classname=self._win_cls_name, name=self._win_name) + if self.control: + self.init() + + def init(self): + toolbar_control = self.control.GroupControl(ClassName="mmui::PreviewToolbarView") + self.tools = { + btn.Name: btn for ele in toolbar_control.GetChildren() + if (btn := ele.ButtonControl()).Exists(0) + } + if self.control.WindowControl(ClassName="mmui::XPlayerControlView").Exists(0): + self.type = 'video' + else: + self.type = 'image' + + def save(self, dir_path=None, timeout=10) -> Path: + """保存图片/视频 + + Args: + dir_path (str): 保存文件夹路径 + timeout (int, optional): 保存超时时间,默认10秒 + + Returns: + Path: 文件保存路径,即savepath + """ + image_sufix = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'pic'] + if dir_path is None: + dir_path = WxParam.DEFAULT_SAVE_PATH + t0 = time.time() + + n = 1 + SetClipboardText('') + while True: + if time.time() - t0 > timeout: + if self.control.Exists(0): + self.control.SendKeys('{Esc}') + return WxResponse.failure('下载超时') + if self.control.TextControl(Name="图片过期或已被清理").Exists(0): + return WxResponse.failure('图片过期或已被清理') + try: + self.tools['更多'].Click() + menu = Menu(self.root) + menu.select('复制') + if self.type == 'video': + for _ in range(30): + clipboard_data = ReadClipboardData() + wxlog.debug(f"读取到剪贴板数据:{clipboard_data.keys()}") + if '15' not in clipboard_data: + time.sleep(0.1) + continue + path = clipboard_data['15'][0] + break + else: + clipboard_data = ReadClipboardData() + path = clipboard_data['15'][0] + if not os.path.exists(path): + return WxResponse.failure('微信BUG无法获取该图片,请重新获取') + suffix = os.path.splitext(path)[1] + if ( + suffix in image_sufix + and not is_valid_image(path) + ) or not os.path.getsize(path): + wxlog.debug("图片格式不正确,删除文件") + os.remove(path) + continue + wxlog.debug(f"读取到图片/视频路径[{os.path.exists(path)}, {os.path.getsize(path)}]:{path}") + break + except Exception: + if n > 3: + return WxResponse.failure('微信BUG无法获取该图片,请重新获取') + n += 1 + wxlog.debug(traceback.format_exc()) + time.sleep(0.1) + filename = f"wechatauto_{self.type}_{now_time()}{suffix}" + filepath = get_file_dir(dir_path) / filename + wxlog.debug(f"保存到文件:{filepath}") + shutil.copyfile(path, filepath) + SetClipboardText('') + if self.control.Exists(0): + wxlog.debug("关闭图片窗口") + self.control.SendKeys('{Esc}') + return filepath diff --git a/wechatauto/ui/main.py b/wechatauto/ui/main.py new file mode 100644 index 0000000..446ac51 --- /dev/null +++ b/wechatauto/ui/main.py @@ -0,0 +1,268 @@ +from .base import BaseUISubWnd, BaseUIWnd +from .navigationbox import NavigationBox +from .sessionbox import SessionBox +from .chatbox import ChatBox +from wechatauto.utils.win32 import ( + FindWindow, + GetAllWindows, + GetPathByHwnd, + get_windows_by_pid +) +from wechatauto.param import WxParam, WxResponse, PROJECT_NAME +from wechatauto.logger import wxlog +from wechatauto import uia +from typing import ( + Union, + List, + Literal +) +import os +import re +import sys + + +def find_wechat_windows(ui_cls_name: str) -> List[uia.Control]: + """从所有顶层窗口中查找指定 UIA 类名的微信窗口控件。 + + Args: + ui_cls_name: 目标 UIA 类名,如 ``mmui::MainWindow`` + + Returns: + 匹配到的窗口控件列表 + """ + targets = [] + for hwnd, clsname, winname in GetAllWindows(): + # 跳过 Qt 内部消息泵等隐藏窗口,其 UIA 服务可能阻塞调用 + if clsname.startswith(uia.QT_INTERNAL_WIN_CLASS_PREFIX): + continue + if uia.GetUiClassNameWithTimeout(hwnd) != ui_cls_name: + continue + try: + control = uia.ControlFromHandle(hwnd) + except Exception: + continue + if control is not None: + targets.append(control) + return targets + + +class WeChatSubWnd(BaseUISubWnd): + """微信独立聊天子窗口""" + + _ui_cls_name: str = 'mmui::FramelessMainWindow' + _win_cls_name: str = 'Qt51514QWindowIcon' + _chat_api: ChatBox = None + nickname: str = '' + + def __init__( + self, + key: Union[str, int], + parent: 'WeChatMainWnd', + timeout: int = 3 + ): + self.root = self + self.parent = parent + if isinstance(key, str): + hwnd = FindWindow(classname=self._win_cls_name, name=key, timeout=timeout) + else: + hwnd = key + self.control = uia.ControlFromHandle(hwnd) + if self.control is not None: + chatbox_control = self.control.\ + GroupControl(ClassName="mmui::ChatMessagePage").\ + CustomControl(ClassName="mmui::XSplitterView") + self._chat_api = ChatBox(chatbox_control, self) + self.nickname = self.control.Name + + def __repr__(self): + return f'<{PROJECT_NAME} - {self.__class__.__name__} object("{self.nickname}")>' + + @property + def pid(self): + if not hasattr(self, '_pid'): + self._pid = self.control.ProcessId + return self._pid + + def _get_chatbox( + self, + nickname: str = None, + exact: bool = False + ) -> ChatBox: + return self._chat_api + + def _get_windows(self): + wins = [] + for hwnd in get_windows_by_pid(self.pid): + try: + wins.append(uia.ControlFromHandle(hwnd)) + except Exception: + pass + ignore_cls = ['basepopupshadow', 'popupshadow'] + return [win for win in wins if win.ClassName not in ignore_cls] + + def chat_info(self): + return self._chat_api.get_info() + + def send_msg( + self, + msg: str, + who: str = None, + clear: bool = True, + at: Union[str, List[str]] = None, + exact: bool = False, + ) -> WxResponse: + chatbox = self._get_chatbox(who, exact) + if chatbox is None: + return WxResponse.failure(f"未找到聊天窗口:{who}") + return chatbox.send_msg(msg, clear, at) + + def send_files( + self, + filepath, + who=None, + exact=False + ) -> WxResponse: + chatbox = self._get_chatbox(who, exact) + if chatbox is None: + return WxResponse.failure(f"未找到聊天窗口:{who}") + return chatbox.send_file(filepath) + + def get_msgs(self): + chatbox = self._get_chatbox() + if chatbox: + return chatbox.get_msgs() + return [] + + def get_new_msgs(self): + return self._get_chatbox().get_new_msgs() + + def get_msg_by_id(self, msg_id): + chatbox = self._get_chatbox() + if chatbox: + return chatbox.get_msg_by_id(msg_id) + + def get_msg_by_hash(self, msg_hash: str): + chatbox = self._get_chatbox() + if chatbox: + return chatbox.get_msg_by_hash(msg_hash) + + def get_last_msg(self): + chatbox = self._get_chatbox() + if chatbox: + return chatbox.get_last_msg() + + +class WeChatMainWnd(WeChatSubWnd): + """微信主窗口""" + + _ui_cls_name: str = 'mmui::MainWindow' + _win_cls_name: str = 'Qt51514QWindowIcon' + _ui_name: str = '微信' + + def __init__(self, nickname: str = None, hwnd: int = None): + self.root = self + self.parent = self + if hwnd: + self._setup_ui(hwnd) + else: + # 优先按 UIA 类名定位主窗口,兼容不同 Qt 版本的客户端 + controls = find_wechat_windows(self._ui_cls_name) + if not controls: + controls = find_wechat_windows(self._ui_cls_name.replace('MainWindow', 'FramelessMainWindow')) + if not controls: + raise Exception('未找到已登录的微信主窗口') + target = None + for control in controls: + if nickname and control.Name != nickname: + continue + target = control + break + if target is None: + target = controls[0] + self._setup_ui(target.NativeWindowHandle) + + print(f'初始化成功,获取到已登录窗口:{self.nickname}') + + def _setup_ui(self, hwnd: int): + self.HWND = hwnd + self.control = uia.ControlFromHandle(hwnd) + if self.control is not None: + navigation_control = self.control.\ + ToolBarControl(ClassName="mmui::MainTabBar", AutomationId='main_tabbar') + sessionbox_control = self.control.\ + GroupControl(ClassName="mmui::ChatMasterView") + chatbox_control = self.control.\ + GroupControl(ClassName="mmui::ChatMessagePage").\ + CustomControl(ClassName="mmui::XSplitterView") + self._navigation_api = NavigationBox(navigation_control, self) + self._session_api = SessionBox(sessionbox_control, self) + self._chat_api = ChatBox(chatbox_control, self) + self.nickname = self.control.Name + + def __repr__(self): + return f'<{PROJECT_NAME} - {self.__class__.__name__} object("{self.nickname}")>' + + def _get_wx_path(self): + return GetPathByHwnd(self.HWND) + + def _get_wx_dir(self): + wxdir = os.path.dirname(self._get_wx_path()) + for d in os.listdir(wxdir): + if re.match(r'\d+\.\d+\.\d+\.\d+', d): + return os.path.join(wxdir, d) + + def _get_chatbox( + self, + nickname: str = None, + exact: bool = False + ) -> ChatBox: + if nickname and (chatbox := WeChatSubWnd(nickname, self, timeout=0)).control: + return chatbox._chat_api + else: + if nickname: + switch_result = self._session_api.switch_chat(keywords=nickname, exact=exact) + if not switch_result: + return None + if self._chat_api.msgbox.Exists(0.5): + return self._chat_api + + def switch_chat( + self, + keywords: str, + exact: bool = True, + force: bool = False, + force_wait: Union[float, int] = 0.5 + ): + return self._session_api.switch_chat(keywords, exact, force, force_wait) + + def get_all_sub_wnds(self): + sub_wxs = GetAllWindows(classname=WeChatSubWnd._win_cls_name) + return [ + sub_win + for i in sub_wxs + if ( + uia.ControlFromHandle(i[0]).ClassName == WeChatSubWnd._ui_cls_name + and (sub_win := WeChatSubWnd(i[0], self)).pid == self.pid + ) + ] + + def get_sub_wnd(self, who: str): + subwins = self.get_all_sub_wnds() + for subwin in subwins: + if subwin.nickname == who: + return subwin + + def open_separate_window(self, keywords: str) -> WeChatSubWnd: + if subwin := self.get_sub_wnd(keywords): + wxlog.debug(f"{keywords} 获取到已存在的子窗口: {subwin}") + return subwin + if nickname := self._session_api.switch_chat(keywords): + wxlog.debug(f"{keywords} 切换到聊天窗口: {nickname}") + if subwin := self.get_sub_wnd(nickname): + wxlog.debug(f"{nickname} 获取到已存在的子窗口: {subwin}") + return subwin + else: + keywords = nickname + if result := self._session_api.open_separate_window(keywords): + find_nickname = result['data'].get('nickname', keywords) + return WeChatSubWnd(find_nickname, self) diff --git a/wechatauto/ui/navigationbox.py b/wechatauto/ui/navigationbox.py new file mode 100644 index 0000000..af2ffc7 --- /dev/null +++ b/wechatauto/ui/navigationbox.py @@ -0,0 +1,62 @@ +from wechatauto import uia +from wechatauto.languages import WECHAT_NAVIGATION_BOX, get_lang +from wechatauto.param import WxParam + + +class NavigationBox: + """微信左侧导航栏""" + + def __init__(self, control, parent): + self.control: uia.Control = control + self.root = parent.root + self.parent = parent + self.init() + + def _lang(self, text): + return get_lang(WECHAT_NAVIGATION_BOX, text) + + def init(self): + self.chat_icon = self.control.ButtonControl(Name=self._lang('聊天')) + self.contact_icon = self.control.ButtonControl(Name=self._lang('通讯录')) + self.favorites_icon = self.control.ButtonControl(Name=self._lang('收藏')) + self.files_icon = self.control.ButtonControl(Name=self._lang('聊天文件')) + self.moments_icon = self.control.ButtonControl(Name=self._lang('朋友圈')) + self.browser_icon = self.control.ButtonControl(Name=self._lang('搜一搜')) + self.video_icon = self.control.ButtonControl(Name=self._lang('视频号')) + self.stories_icon = self.control.ButtonControl(Name=self._lang('看一看')) + self.mini_program_icon = self.control.ButtonControl(Name=self._lang('小程序面板')) + self.phone_icon = self.control.ButtonControl(Name=self._lang('手机')) + self.settings_icon = self.control.ButtonControl(Name=self._lang('更多')) + + def switch_to_chat_page(self): + self.chat_icon.Click() + + def switch_to_contact_page(self): + self.contact_icon.Click() + + def switch_to_favorites_page(self): + self.favorites_icon.Click() + + def switch_to_files_page(self): + self.files_icon.Click() + + def switch_to_moments_page(self): + self.moments_icon.Click() + + def switch_to_browser_page(self): + self.browser_icon.Click() + + def switch_to_video_page(self): + self.video_icon.Click() + + def switch_to_stories_page(self): + self.stories_icon.Click() + + def switch_to_mini_program_page(self): + self.mini_program_icon.Click() + + def switch_to_phone_page(self): + self.phone_icon.Click() + + def switch_to_settings_page(self): + self.settings_icon.Click() diff --git a/wechatauto/ui/sessionbox.py b/wechatauto/ui/sessionbox.py new file mode 100644 index 0000000..e41949a --- /dev/null +++ b/wechatauto/ui/sessionbox.py @@ -0,0 +1,276 @@ +from __future__ import annotations +from wechatauto import uia +from wechatauto.param import ( + WxParam, + WxResponse, +) +from wechatauto.languages import MENU_OPTIONS, get_lang +from wechatauto.ui.component import Menu +from wechatauto.utils.win32 import SetClipboardText +from wechatauto.logger import wxlog +import time +from typing import ( + Union, + List +) +import re + + +class SessionBox: + """会话列表区域""" + + def __init__(self, control, parent): + self.control: uia.Control = control + self.root = parent.root + self.parent = parent + self.init() + + def init(self): + self.searchbox = self.control.GroupControl(ClassName="mmui::XSearchField").EditControl() + self.session_list = self.control.GroupControl(ClassName="mmui::ChatSessionList").\ + ListControl(ClassName="mmui::XTableView", Name="会话") + self.search_content = self.parent.control.WindowControl(ClassName="mmui::SearchContentPopover") + + def roll_up(self, n: int = 5): + self.control.MiddleClick() + self.control.WheelUp(wheelTimes=n) + + def roll_down(self, n: int = 5): + self.control.MiddleClick() + self.control.WheelDown(wheelTimes=n) + + def get_session(self) -> List['SessionElement']: + if self.session_list.Exists(0): + return [SessionElement(i, self) for i in self.session_list.GetChildren()] + else: + return [] + + def search( + self, + keywords: str, + force: bool = False, + force_wait: Union[float, int] = 0.5 + ): + self.searchbox.RightClick() + SetClipboardText(keywords) + menu = Menu(self) + menu.select('粘贴') + self.searchbox.MiddleClick() + + search_result = self.search_content.ListControl() + + if force: + time.sleep(force_wait) + + return [SearchResultElement(i) for i in search_result.GetChildren()] + + def switch_chat( + self, + keywords: str, + exact: bool = True, + force: bool = False, + force_wait: Union[float, int] = 0.5 + ): + wxlog.debug(f"切换聊天窗口: {keywords}, {exact}, {force}, {force_wait}") + search_box = self.search_content.ListControl() + search_result = self.search(keywords, force, force_wait) + t0 = time.time() + while time.time() - t0 < WxParam.SEARCH_CHAT_TIMEOUT: + results = [] + search_result_items = search_box.GetChildren() + for search_result_item in search_result_items: + text: str = search_result_item.Name + if exact: + if text == keywords: + search_result_item.Click() + return keywords + elif ( + ' 微信号: ' in text + and (split := text.split(' 微信号: '))[-1].lower() == keywords.lower() + ): + search_result_item.Click() + return split[0] + elif ( + ' 昵称: ' in text + and (split := text.split(' 昵称: '))[-1].lower() == keywords.lower() + ): + search_result_item.Click() + return split[0] + else: + if keywords in text: + search_result_item.Click() + return text + + if self.search_content.Exists(0): + self.control.MiddleClick() + + def open_separate_window(self, name: str): + wxlog.debug(f"打开独立窗口: {name}") + realname = self.switch_chat(name) + if not realname: + return WxResponse.failure('未找到会话') + time.sleep(0.3) + while True: + session = [i for i in self.get_session() if uia.IsElementInWindow(self.session_list, i.control)][0] + if session.content.startswith(realname): + break + session.double_click() + return WxResponse.success(data={'nickname': realname}) + + def go_top(self): + wxlog.debug("回到会话列表顶部") + self.control.MiddleClick() + self.control.SendKeys('{Home}') + + def go_bottom(self): + wxlog.debug("回到会话列表底部") + self.control.MiddleClick() + self.control.SendKeys('{End}') + + +class SessionElement: + """会话列表中的单条会话""" + + def __init__( + self, + control: uia.Control, + parent: SessionBox, + ): + self.root = parent.root + self.parent = parent + self.control = control + self.content = control.Name + + @property + def texts(self) -> List[str]: + """拆分当前会话控件中的文本行""" + + return [ + line for line in str(self.content).split('\n') + if line and line.strip() + ] + + @property + def name(self) -> str: + """会话名称""" + + if self.texts: + return self.texts[0] + return '' + + @property + def unread_count(self) -> int: + """未读消息数量""" + + unread_pattern = re.compile(r'\[(\d+)条\]') + for text in self.texts: + if match := unread_pattern.search(text): + return int(match.group(1)) + return 0 + + def _menu_option_text(self, option_key: str) -> str: + return get_lang(MENU_OPTIONS, option_key) + + def select_menu_option(self, option_key: str, wait=0.3): + """根据配置语言选择菜单项""" + + option_text = self._menu_option_text(option_key) + return self.select_option(option_text, wait) + + def __repr__(self): + content = str(self.content).replace('\n', ' ') + if len(content) > 5: + content = content[:5] + '...' + return f"" + + def roll_into_view(self): + uia.RollIntoView(self.control.GetParentControl(), self.control) + + def _click(self, right: bool = False, double: bool = False): + self.roll_into_view() + if right: + self.control.RightClick() + elif double: + self.control.DoubleClick() + else: + self.control.Click() + + def click(self): + self._click() + + def right_click(self): + self._click(right=True) + + def double_click(self): + self._click() + self._click(double=True) + + def select_option(self, option: str, wait=0.3): + self.roll_into_view() + self.control.RightClick() + time.sleep(wait) + menu = Menu(self.parent) + return menu.select(option) + + def pin(self): + """置顶聊天""" + + return self.select_menu_option('置顶') + + def unpin(self): + """取消置顶聊天""" + + return self.select_menu_option('取消置顶') + + def mark_unread(self): + """标记为未读""" + + return self.select_menu_option('标为未读') + + def toggle_mute(self): + """切换消息免打扰状态""" + + return self.select_menu_option('消息免打扰') + + def open_in_separate_window(self): + """在独立窗口中打开会话""" + + return self.select_menu_option('在独立窗口打开') + + def hide(self): + """不显示聊天""" + + return self.select_menu_option('不显示聊天') + + def delete(self): + """删除聊天""" + + return self.select_menu_option('删除聊天') + + +class SearchResultElement: + """搜索结果中的单条结果""" + + def __init__(self, control): + self.control = control + self.content = control.Name + self.type = control.ClassName + + def __repr__(self): + content = str(self.content).replace('\n', ' ') + if len(content) > 5: + content = content[:5] + '...' + return f"" + + def get_all_text(self): + return [ + line for line in str(self.content).split('\n') + if line and line.strip() + ] + + def click(self): + uia.RollIntoView(self.control.GetParentControl(), self.control) + self.control.Click() + + def close(self): + self.control.SendKeys('{Esc}') diff --git a/wechatauto/uia/__init__.py b/wechatauto/uia/__init__.py new file mode 100644 index 0000000..315ae21 --- /dev/null +++ b/wechatauto/uia/__init__.py @@ -0,0 +1,356 @@ +"""UIA 兼容适配层。 + +基于 PyPI ``uiautomation`` 封装,并补充 wechatauto 依赖的扩展能力: + +- :attr:`Control.runtimeid` —— 控件 RuntimeId 的字符串形式,用于消息去重/定位 +- :meth:`Control.ScreenShot` —— 截取控件区域保存为图片文件 +- :func:`RollIntoView` —— 将目标元素滚动到窗口可见区域内 +- :func:`CheckElementPosition` / :func:`IsElementInWindow` —— 元素与窗口位置关系判断 + +Windows 微信 4.x 客户端为 Qt 应用(UIA 类名前缀 ``mmui::``), +仅暴露 UIA 标准接口,因此本层不依赖具体微信版本。 +""" + +from __future__ import annotations + +import os +import queue +import tempfile +import threading +import time +from typing import Any + +from PIL import Image as _PILImage + +# uiautomation 和 comtypes 初始化(COM + UIA)可能在部分系统上阻塞 +# (如微信或其他 Qt 应用占用 COM),改为延迟导入:仅在首次访问本包属性时 +# 才加载,避免 ``import wechatauto`` 时卡死。 +_uia_loaded = False +_UiaControl = None +_control_from_handle = None +_CoInitializeEx = None + + +def _ensure_uia(): + """延迟加载 uiautomation 并完成 monkey-patch,只执行一次。""" + global _uia_loaded, _UiaControl, _control_from_handle, _CoInitializeEx + if _uia_loaded: + return + _uia_loaded = True + + from comtypes import CoInitializeEx as _ci + from uiautomation import Control as _uc, ControlFromHandle as _cfh + + _CoInitializeEx = _ci + _UiaControl = _uc + _control_from_handle = _cfh + + _uc.runtimeid = property(_get_runtimeid) + _uc.ScreenShot = _screen_shot + + # 把 __all__ 中的名称绑定到模块全局,让 from uiautomation import * 的 + # 等效访问能直接命中,不再触发 __getattr__ 回退查找 + import uiautomation as _mod + for _n in __all__: + if _n not in globals(): + _v = getattr(_mod, _n, None) + if _v is not None: + globals()[_n] = _v + + +def __getattr__(name: str) -> Any: + """延迟导入:首次访问时加载 uiautomation。""" + _ensure_uia() + try: + return globals()[name] + except KeyError: + # 从 uiautomation 星号导入的名称,首次访问时从实际模块取回 + import uiautomation as _mod + val = getattr(_mod, name, _SENTINEL) + if val is _SENTINEL: + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") + globals()[name] = val + return val + + +_SENTINEL = object() + +__all__ = [ + 'ControlFromHandle', + 'GetUiClassNameWithTimeout', + 'WalkControl', + 'RollIntoView', + 'CheckElementPosition', + 'IsElementInWindow', + 'GetElementPositionDescription', +] + +# UIA 类名以 Qt 内部消息泵开头的隐藏窗口(如 WPS 等 Qt 应用), +# 其 UIA 服务可能长时间无响应导致调用阻塞,扫描时应直接跳过 +QT_INTERNAL_WIN_CLASS_PREFIX = 'QEventDispatcherWin32_Internal_' + + +def GetUiClassNameWithTimeout(hwnd, timeout: float = 3.0) -> 'str | None': + """带超时保护地获取窗口的 UIA 类名。 + + 部分 Qt 应用的隐藏窗口(如 ``QEventDispatcherWin32_Internal_*``)UIA 服务异常, + 直接调用会无限阻塞。本函数在守护线程中调用底层接口,超时后放弃该窗口。 + + Args: + hwnd: 窗口句柄 + timeout: 超时时间,单位秒 + + Returns: + str: 窗口的 UIA 类名;超时/失败时返回 None + """ + result_queue = queue.Queue() + _ensure_uia() + + def _probe(): + try: + _CoInitializeEx() + control = _control_from_handle(hwnd) + result_queue.put(control.ClassName if control is not None else None) + except Exception as e: # noqa: BLE001 + result_queue.put(e) + + worker = threading.Thread(target=_probe, daemon=True) + worker.start() + worker.join(timeout) + if worker.is_alive(): + # 底层 UIA 调用被异常进程阻塞,放弃等待(守护线程随进程退出) + return None + try: + result = result_queue.get_nowait() + except queue.Empty: + return None + if isinstance(result, Exception): + return None + return result + +# ---------------------------------------------------------------------------- +# Control 扩展:runtimeid +# ---------------------------------------------------------------------------- + +def _get_runtimeid(self) -> str: + """返回控件 RuntimeId 的字符串形式,用于唯一标识控件。""" + return ''.join(str(i) for i in self.GetRuntimeId()) + +# ---------------------------------------------------------------------------- +# Control 扩展:ScreenShot +# ---------------------------------------------------------------------------- + +def _screen_shot(self, savePath: str = None, crop: tuple = (0, 0, 0, 0), + crop_percentage: bool = False, return_img=False): + """截取控件区域并保存/返回图片。 + + Args: + savePath: 保存路径,不指定则使用临时文件 + crop: 裁剪量 (left, top, right, bottom) + crop_percentage: crop 值是否为百分比 + return_img: 为 True 时直接返回 PIL Image 对象 + + Returns: + str: 图片保存路径;return_img=True 时返回 PIL Image + """ + rect = self.BoundingRectangle + w, h = rect.width(), rect.height() + + if crop_percentage: + crop = ( + int(w * crop[0] / 100), + int(h * crop[1] / 100), + int(w * crop[2] / 100), + int(h * crop[3] / 100), + ) + + cw = max(w - crop[0] - crop[2], 1) + ch = max(h - crop[1] - crop[3], 1) + + if savePath is None: + fd, savePath = tempfile.mkstemp(prefix='wechatauto_image_', suffix='.png') + os.close(fd) + os.remove(savePath) + + ok = self.CaptureToImage(savePath, x=crop[0], y=crop[1], width=cw, height=ch) + if not ok: + raise RuntimeError(f'截图失败: {self}') + + if return_img: + img = _PILImage.open(savePath) + try: + os.remove(savePath) + except Exception: + pass + return img + return savePath + +# ---------------------------------------------------------------------------- +# 模块级工具函数 +# ---------------------------------------------------------------------------- + +def RollIntoView(win, ele, equal=True, bias=0): + """将目标元素滚动到主窗口内可见区域。 + + Args: + win: 主窗口元素 (Control对象) + ele: 目标元素 (Control对象) + bias: 偏移量,元素边缘需要超过这个量才算完全在窗口内 (默认为0) + """ + # 获取窗口和元素的边界矩形 + win_rect = win.BoundingRectangle + ele_rect = ele.BoundingRectangle + + # 计算窗口的有效显示区域(考虑bias偏移) + win_top = win_rect.top + bias + win_bottom = win_rect.bottom - bias + win_height = win_bottom - win_top + + # 获取元素的位置信息 + ele_top = ele_rect.top + ele_bottom = ele_rect.bottom + ele_height = ele_rect.height() + ele_ycenter = ele_rect.ycenter() + + # 如果元素高度超过窗口高度,只需要确保元素中心在窗口内 + if ele_height > win_height: + # 元素太高,只需要中心点在窗口内即可 + target_top = ele_ycenter + target_bottom = ele_ycenter + else: + # 元素高度适中,需要整个元素都在窗口内 + target_top = ele_top + target_bottom = ele_bottom + + # 执行滚动操作 + max_attempts = 100 # 防止无限循环 + attempt = 0 + + while attempt < max_attempts: + # 重新获取当前位置(滚动后位置会变化) + current_ele_rect = ele.BoundingRectangle + + if ele_height > win_height: + # 元素太高的情况,检查中心点 + current_ycenter = current_ele_rect.ycenter() + if win_top <= current_ycenter <= win_bottom: + break # 中心点已在窗口内,停止滚动 + + if current_ycenter < win_top: + # 中心点在窗口上方,需要向下滚动 + win.WheelUp() + time.sleep(0.1) + elif current_ycenter > win_bottom: + # 中心点在窗口下方,需要向上滚动 + win.WheelDown() + time.sleep(0.1) + else: + # 元素高度适中的情况,检查整个元素 + current_top = current_ele_rect.top + current_bottom = current_ele_rect.bottom + + # 检查是否已经完全在窗口内 + if win_top <= current_top and current_bottom <= win_bottom: + break # 元素已完全在窗口内,停止滚动 + + if current_top < win_top: + # 元素顶部在窗口上方,需要向下滚动 + win.WheelUp() + time.sleep(0.1) + elif current_bottom > win_bottom: + # 元素底部在窗口下方,需要向上滚动 + win.WheelDown() + time.sleep(0.1) + else: + # 理论上不应该到达这里 + break + + attempt += 1 + + if attempt >= max_attempts: + print(f"Warning: 滚动操作达到最大尝试次数({max_attempts}),可能元素无法完全滚动到视图内") + + +def CheckElementPosition(win, ele, bias=0) -> dict: + """判断目标元素相对于主窗口的位置关系。 + + Returns: + dict: 包含各种位置关系判断结果的字典 + """ + win_rect = win.BoundingRectangle + ele_rect = ele.BoundingRectangle + + win_top = win_rect.top + bias + win_bottom = win_rect.bottom - bias + win_left = win_rect.left + bias + win_right = win_rect.right - bias + + ele_top = ele_rect.top + ele_bottom = ele_rect.bottom + ele_left = ele_rect.left + ele_right = ele_rect.right + + result = { + 'ele_top_above_win_top': ele_top < win_top, + 'ele_bottom_below_win_bottom': ele_bottom > win_bottom, + 'ele_completely_above_win': ele_bottom <= win_top, + 'ele_completely_below_win': ele_top >= win_bottom, + 'ele_vertically_inside_win': win_top <= ele_top and ele_bottom <= win_bottom, + 'win_vertically_inside_ele': ele_top <= win_top and win_bottom <= ele_bottom, + + 'ele_left_before_win_left': ele_left < win_left, + 'ele_right_after_win_right': ele_right > win_right, + 'ele_completely_left_of_win': ele_right <= win_left, + 'ele_completely_right_of_win': ele_left >= win_right, + 'ele_horizontally_inside_win': win_left <= ele_left and ele_right <= win_right, + 'win_horizontally_inside_ele': ele_left <= win_left and win_right <= ele_right, + + 'ele_completely_inside_win': False, + 'win_completely_inside_ele': False, + 'ele_and_win_overlap': False, + 'ele_and_win_separate': False, + } + + result['ele_completely_inside_win'] = ( + result['ele_vertically_inside_win'] and result['ele_horizontally_inside_win']) + result['win_completely_inside_ele'] = ( + result['win_vertically_inside_ele'] and result['win_horizontally_inside_ele']) + + vertical_overlap = not (result['ele_completely_above_win'] or result['ele_completely_below_win']) + horizontal_overlap = not (result['ele_completely_left_of_win'] or result['ele_completely_right_of_win']) + result['ele_and_win_overlap'] = vertical_overlap and horizontal_overlap + result['ele_and_win_separate'] = not result['ele_and_win_overlap'] + + return result + + +def IsElementInWindow(win, ele, bias=0) -> bool: + """简化版本:判断元素是否在窗口内(仅垂直方向)""" + position_info = CheckElementPosition(win, ele, bias) + return position_info['ele_vertically_inside_win'] + + +def GetElementPositionDescription(win, ele, bias=0) -> str: + """获取元素位置的文字描述""" + result = CheckElementPosition(win, ele, bias) + + if result['ele_completely_inside_win']: + return "元素完全在窗口内部" + elif result['win_completely_inside_ele']: + return "窗口完全在元素内部" + elif result['ele_completely_above_win']: + return "元素完全在窗口上方" + elif result['ele_completely_below_win']: + return "元素完全在窗口下方" + elif result['ele_completely_left_of_win']: + return "元素完全在窗口左侧" + elif result['ele_completely_right_of_win']: + return "元素完全在窗口右侧" + elif result['ele_vertically_inside_win']: + return "元素在窗口内,但水平方向超出范围" + elif result['ele_horizontally_inside_win']: + return "元素在窗口内,但垂直方向超出范围" + elif result['ele_and_win_overlap']: + return "元素与窗口部分重叠" + else: + return "元素与窗口完全分离" diff --git a/wechatauto/uia_driver.py b/wechatauto/uia_driver.py new file mode 100644 index 0000000..f339e79 --- /dev/null +++ b/wechatauto/uia_driver.py @@ -0,0 +1,1300 @@ +# -*- coding: utf-8 -*- +"""wechatauto.uia_driver —— 基于 UI Automation 的微信 4.x 混合驱动引擎(可选路径) + +背景 +---- +微信 4.1.12+ 的聊天区域使用自绘渲染,冷启动时对 UIAutomation 只暴露 +``Qt51514QWindowIcon`` 空壳(2 个子节点),看不到任何 ``mmui::`` 控件—— +这是旧版 wxauto 的 UIA 方案失效的原因。 + +实测(微信 4.1.12.26 / WMPF)发现:**热激活 Qt accessibility gate 后**, +UIA 树会立即物化为 ``mmui::MainWindow``,其中: + * 搜索框 ``mmui::XValidatorTextEdit``(Name=「搜索」)可定位; + * 输入关键词后下拉 ``AutomationId=search_list`` 暴露结果列表 + (真实结果 aid 前缀 ``search_item_*``),点击可打开会话; + * 打开会话后 ``AutomationId=chat_input_field`` 输入框可定位, + 其 ``.Name`` 即当前聊天对象(三重校验依据)。 + +相比坐标 + OCR(``wechatauto.guia``),UIA 路径更准(无 OCR 抖动/生僻字 +问题)、更快(无放大/多轮投票)。本模块将其封装为与 guia 相同的调用面, +供 :meth:`WeChatGUI.open_chat` / 发送方法**优先尝试、失败自动降级到 OCR** +(见 guia.py 的混合驱动逻辑)。 + +热激活安全性:只写运行中 Weixin 进程的 1 个 Qt accessibility byte +(从 Weixin.dll 扫描 RVA,字节码模式匹配 + qt.accessibility.core 引用 +距离过滤),不注入代码、不重启进程;该 byte 本就是系统读屏器会写入的 +状态位。微信升级后扫描逻辑通常仍有效,硬编码版本表仅作兜底。 + +使用前提:``pip install uiautomation pywin32``。 +""" + +from __future__ import annotations + +import ctypes +import os +import re +import struct +import time +from ctypes import wintypes +from functools import lru_cache +from typing import List, Optional, Tuple + +import uiautomation as auto + +try: + import win32gui, win32con, win32process, win32api + _HAS_WIN32 = True +except Exception: # pragma: no cover + _HAS_WIN32 = False + +from wechatauto.logger import wxlog + +# --------------------------------------------------------------------------- +# 控件锚点 +# --------------------------------------------------------------------------- +MAIN_CLASS = "mmui::MainWindow" +LOGIN_CLASS = "mmui::LoginWindow" +MAIN_NAMES = ("微信", "Weixin") +LOGIN_BTN_NAMES = ("进入微信", "登录", "进入") +LOGIN_OUTLINE_CLASS = "mmui::XOutlineButton" +SEARCH_EDIT_CLASS = "mmui::XValidatorTextEdit" +SEARCH_EDIT_NAME = "搜索" +SESSION_LIST_AID = "session_list" +SEARCH_LIST_AID = "search_list" +RESULT_AID_PREFIX = "search_item_" # 真实可打开结果的 aid 前缀 +CHAT_INPUT_AID = "chat_input_field" # 输入框;其 .Name == 当前聊天对象 +DEFAULT_EXE = r"C:\Program Files\Tencent\Weixin\Weixin.exe" + +# 搜索结果分区标题(aid 为空且名字命中此集合的才算分区头,其余空 aid 视为建议项) +SECTION_HEADERS = { + "最常使用", "最近使用", "联系人", "群聊", "公众号", "服务号", "订阅号", + "聊天记录", "收藏", "功能", "小程序", "最近使用过的小程序", "视频号", + "企业微信联系人", "朋友圈", "搜索网络结果", "企业微信", +} + +# --------------------------------------------------------------------------- +# 无障碍“屏幕阅读器”系统标志 / Qt accessibility gate +# --------------------------------------------------------------------------- +SPI_GETSCREENREADER = 0x0046 +SPI_SETSCREENREADER = 0x0047 +SPIF_SENDCHANGE = 0x02 + +# 微信内置 Qt accessibility gate:QAccessible 查询前会检查一个运行时 active +# byte。冷启动未启用读屏时该 byte 为 0,WM_GETOBJECT 只能拿到 Qt 外壳; +# 热写为 1 后当前进程立即返回 mmui provider,无需重启微信。优先从 Weixin.dll +# 自动扫描该 byte 的 RVA,下面的版本表仅作扫描失败时的兜底。 +QACCESSIBLE_ACTIVE_RVA_BY_VERSION = { + "4.1.11.22": 0x0A1E7DB8, +} +QACCESSIBLE_CORE_STRING = b"qt.accessibility.core" +QACCESSIBLE_GATE_PATTERN = re.compile( + rb"\x48\x85\xc9\x0f\x84....\x80\x3d(?P.{4})" + rb"\x00\x0f\x84", + re.DOTALL, +) +IMAGE_SCN_MEM_EXECUTE = 0x20000000 +IMAGE_SCN_MEM_WRITE = 0x80000000 +PROCESS_VM_OPERATION = 0x0008 +PROCESS_VM_READ = 0x0010 +PROCESS_VM_WRITE = 0x0020 +PROCESS_QUERY_INFORMATION = 0x0400 +TH32CS_SNAPMODULE = 0x00000008 +TH32CS_SNAPMODULE32 = 0x00000010 +INVALID_HANDLE_VALUE = ctypes.c_void_p(-1).value +MAX_MODULE_NAME32 = 255 +MAX_PATH = 260 + + +class MODULEENTRY32W(ctypes.Structure): + _fields_ = [ + ("dwSize", ctypes.c_ulong), + ("th32ModuleID", ctypes.c_ulong), + ("th32ProcessID", ctypes.c_ulong), + ("GlblcntUsage", ctypes.c_ulong), + ("ProccntUsage", ctypes.c_ulong), + ("modBaseAddr", ctypes.POINTER(ctypes.c_ubyte)), + ("modBaseSize", ctypes.c_ulong), + ("hModule", ctypes.c_void_p), + ("szModule", ctypes.c_wchar * (MAX_MODULE_NAME32 + 1)), + ("szExePath", ctypes.c_wchar * MAX_PATH), + ] + + +# --------------------------------------------------------------------------- +# 异常 +# --------------------------------------------------------------------------- + +class UIATimeout(Exception): + """UIA 操作超时。""" + + +class UIANotAvailable(Exception): + """UIA 树不可用(热激活失败 / 微信未运行等),调用方应降级到 OCR。""" + + +# --------------------------------------------------------------------------- +# 引擎 +# --------------------------------------------------------------------------- + +class WeChatUIA: + """基于 UIAutomation 的微信 4.x 驱动引擎(混合驱动首选路径)。 + + 用法(一般通过 WeChatGUI 自动切换,也可独立使用):: + + from wechatauto.uia_driver import WeChatUIA + uia = WeChatUIA() + uia.ensure_window() + uia.open_chat('文件传输助手') + uia.send_text('你好') + """ + + def __init__(self, timeout: float = 15.0, search_timeout: float = 2.0): + self.timeout = timeout + self._win = None + # 线程安全:WeChatBot 等宿主可能在后台线程实例化本驱动,COM 未初始化 + # 时 uiautomation 会报「尚未调用 CoInitialize / 无法加载 + # UIAutomationCore.dll」。CoInitializeEx 幂等,主线程重复调用无害。 + try: + auto.InitializeUIAutomationInCurrentThread() + except Exception: + pass + try: + auto.SetGlobalSearchTimeout(search_timeout) + except Exception: + pass + + # ------------------------------------------------------------------ 基础 + @staticmethod + def is_running() -> bool: + try: + import subprocess + out = subprocess.run(["tasklist", "/fi", "imagename eq Weixin.exe", + "/nh"], capture_output=True, text=True, + timeout=10).stdout or "" + return "Weixin.exe" in out + except Exception: + return False + + def wake(self) -> None: + """weixin:// 协议唤起/显示窗口(托盘态也能拉起);失败则拉起 exe。""" + try: + os.startfile("weixin://") + return + except Exception: + pass + try: + import subprocess + subprocess.Popen([DEFAULT_EXE]) + except Exception: + wxlog.warning("拉起微信失败") + + # ------------------------------------------------------------------ 热激活 + @staticmethod + def _set_screen_reader_flag(enable: bool) -> None: + try: + ctypes.windll.user32.SystemParametersInfoW( + SPI_SETSCREENREADER, 1 if enable else 0, 0, SPIF_SENDCHANGE) + except Exception: + pass + + @staticmethod + def _pid_from_hwnd(hwnd: int) -> Optional[int]: + if _HAS_WIN32: + try: + return win32process.GetWindowThreadProcessId(hwnd)[1] + except Exception: + return None + pid = wintypes.DWORD() + try: + ctypes.windll.user32.GetWindowThreadProcessId( + wintypes.HWND(hwnd), ctypes.byref(pid)) + return int(pid.value) or None + except Exception: + return None + + @staticmethod + def _process_modules(pid: int): + kernel32 = ctypes.windll.kernel32 + kernel32.CreateToolhelp32Snapshot.argtypes = [wintypes.DWORD, wintypes.DWORD] + kernel32.CreateToolhelp32Snapshot.restype = wintypes.HANDLE + kernel32.Module32FirstW.argtypes = [wintypes.HANDLE, ctypes.POINTER(MODULEENTRY32W)] + kernel32.Module32FirstW.restype = wintypes.BOOL + kernel32.Module32NextW.argtypes = [wintypes.HANDLE, ctypes.POINTER(MODULEENTRY32W)] + kernel32.Module32NextW.restype = wintypes.BOOL + kernel32.CloseHandle.argtypes = [wintypes.HANDLE] + kernel32.CloseHandle.restype = wintypes.BOOL + snapshot = kernel32.CreateToolhelp32Snapshot( + TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, pid) + if snapshot == INVALID_HANDLE_VALUE: + return + try: + entry = MODULEENTRY32W() + entry.dwSize = ctypes.sizeof(entry) + if not kernel32.Module32FirstW(snapshot, ctypes.byref(entry)): + return + while True: + base = ctypes.cast(entry.modBaseAddr, ctypes.c_void_p).value or 0 + yield base, int(entry.modBaseSize), entry.szModule, entry.szExePath + if not kernel32.Module32NextW(snapshot, ctypes.byref(entry)): + break + finally: + kernel32.CloseHandle(snapshot) + + @classmethod + def _weixin_dll_module(cls, pid: int): + for base, size, name, path in cls._process_modules(pid) or (): + if name.lower() == "weixin.dll": + return base, size, path + return None + + @staticmethod + def _pe_sections(data: bytes): + try: + pe_off = struct.unpack_from(" Optional[int]: + for sec in sections: + if sec["raw_ptr"] <= offset < sec["raw_ptr"] + sec["raw_size"]: + return sec["rva"] + offset - sec["raw_ptr"] + return None + + @staticmethod + def _rip_xrefs_to_rva(data: bytes, sections, target_rva: int) -> List[int]: + xrefs: List[int] = [] + for sec in sections: + if not (sec["chars"] & IMAGE_SCN_MEM_EXECUTE): + continue + start = sec["raw_ptr"] + end = min(len(data), start + sec["raw_size"]) + raw = data[start:end] + for i in range(0, max(0, len(raw) - 7)): + if 0x40 <= raw[i] <= 0x4F and raw[i + 1] == 0x8D and (raw[i + 2] & 0xC7) == 0x05: + disp = struct.unpack_from(" Optional[int]: + try: + with open(dll_path, "rb") as f: + data = f.read() + except OSError: + return None + + sections = WeChatUIA._pe_sections(data) + if not sections: + return None + + core_off = data.find(QACCESSIBLE_CORE_STRING) + core_rva = WeChatUIA._offset_to_rva(sections, core_off) if core_off >= 0 else None + core_xrefs = (WeChatUIA._rip_xrefs_to_rva(data, sections, core_rva) + if core_rva is not None else []) + + candidates: List[Tuple[int, int]] = [] + for match in QACCESSIBLE_GATE_PATTERN.finditer(data): + match_rva = WeChatUIA._offset_to_rva(sections, match.start()) + disp_rva = WeChatUIA._offset_to_rva(sections, match.start("disp")) + if match_rva is None or disp_rva is None: + continue + match_sec = WeChatUIA._section_for_rva(sections, match_rva) + if not match_sec or not (match_sec["chars"] & IMAGE_SCN_MEM_EXECUTE): + continue + + cmp_rva = disp_rva - 2 # 80 3d 00 + disp = struct.unpack(" 0x20000: + continue + else: + distance = 0x7FFFFFFF + candidates.append((distance, target_rva)) + + if not candidates: + return None + candidates.sort(key=lambda item: item[0]) + return candidates[0][1] + + @staticmethod + def _qaccessible_active_rva(dll_path: str) -> Optional[int]: + scanned = WeChatUIA._scan_qaccessible_active_rva(dll_path) + if scanned is not None: + return scanned + version = os.path.basename(os.path.dirname(dll_path)) + return QACCESSIBLE_ACTIVE_RVA_BY_VERSION.get(version) + + @staticmethod + def _read_process_byte(handle, address: int) -> Optional[int]: + ctypes.windll.kernel32.ReadProcessMemory.argtypes = [ + wintypes.HANDLE, ctypes.c_void_p, ctypes.c_void_p, + ctypes.c_size_t, ctypes.POINTER(ctypes.c_size_t)] + ctypes.windll.kernel32.ReadProcessMemory.restype = wintypes.BOOL + buf = (ctypes.c_ubyte * 1)() + read = ctypes.c_size_t(0) + ok = ctypes.windll.kernel32.ReadProcessMemory( + handle, ctypes.c_void_p(address), buf, 1, ctypes.byref(read)) + return int(buf[0]) if ok and read.value == 1 else None + + @staticmethod + def _write_process_byte(handle, address: int, value: int) -> bool: + ctypes.windll.kernel32.WriteProcessMemory.argtypes = [ + wintypes.HANDLE, ctypes.c_void_p, ctypes.c_void_p, + ctypes.c_size_t, ctypes.POINTER(ctypes.c_size_t)] + ctypes.windll.kernel32.WriteProcessMemory.restype = wintypes.BOOL + buf = (ctypes.c_ubyte * 1)(value & 0xFF) + written = ctypes.c_size_t(0) + ok = ctypes.windll.kernel32.WriteProcessMemory( + handle, ctypes.c_void_p(address), buf, 1, ctypes.byref(written)) + return bool(ok and written.value == 1) + + def _hot_activate_accessibility(self, hwnd: int) -> bool: + """运行中热激活 Qt accessibility gate,不重启微信进程。""" + pid = self._pid_from_hwnd(hwnd) + if not pid: + return False + mod = self._weixin_dll_module(pid) + if not mod: + wxlog.warning("热激活 UIA 失败:PID %s 未找到 Weixin.dll。", pid) + return False + base, _size, dll_path = mod + rva = self._qaccessible_active_rva(dll_path) + if rva is None: + wxlog.warning("热激活 UIA 失败:不支持的 Weixin.dll 版本路径 %s。", dll_path) + return False + + access = (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | + PROCESS_VM_WRITE | PROCESS_VM_OPERATION) + kernel32 = ctypes.windll.kernel32 + kernel32.OpenProcess.argtypes = [wintypes.DWORD, wintypes.BOOL, wintypes.DWORD] + kernel32.OpenProcess.restype = wintypes.HANDLE + kernel32.CloseHandle.argtypes = [wintypes.HANDLE] + kernel32.CloseHandle.restype = wintypes.BOOL + handle = kernel32.OpenProcess(access, False, pid) + if not handle: + wxlog.warning("热激活 UIA 失败:无法打开 Weixin.exe PID %s。", pid) + return False + try: + address = int(base) + int(rva) + current = self._read_process_byte(handle, address) + if current == 1: + return True + if current is None: + wxlog.warning("热激活 UIA 失败:无法读取 active byte。") + return False + if not self._write_process_byte(handle, address, 1): + wxlog.warning("热激活 UIA 失败:无法写入 active byte。") + return False + wxlog.info("已热激活微信 UIA 树:PID=%s Weixin.dll+0x%x: %s -> 1", + pid, rva, current) + return True + finally: + kernel32.CloseHandle(handle) + + def _wake_accessibility(self) -> bool: + ok = False + for hwnd in self._wechat_hwnds(): + ok = self._hot_activate_accessibility(hwnd) or ok + if ok: + self._win = None + time.sleep(0.2) + return ok + + # ------------------------------------------------------------------ 窗口定位 + def _wechat_hwnds(self): + if not _HAS_WIN32: + return [] + res = [] + + def cb(h, _): + try: + if win32gui.IsWindowVisible(h) and win32gui.GetWindowText(h) in MAIN_NAMES: + # 只保留加载了 Weixin.dll 的主进程窗口,过滤掉无 DLL 的 + # 辅助进程窗口(其热激活必然失败,只会产生噪音警告) + pid = self._pid_from_hwnd(h) + if pid and self._weixin_dll_module(pid): + l, t, r, b = win32gui.GetWindowRect(h) + res.append(((r - l) * (b - t), h)) + except Exception: + pass + return True + try: + win32gui.EnumWindows(cb, None) + except Exception: + pass + res.sort(reverse=True) + return [h for _, h in res] + + def _anchor(self, hwnd): + try: + return auto.ControlFromHandle(hwnd) + except Exception: + return None + + def _find_main(self): + for h in self._wechat_hwnds(): + c = self._anchor(h) + if c is not None and (c.ClassName or "") == MAIN_CLASS: + return c + return None + + def _login_window(self): + for h in self._wechat_hwnds(): + c = self._anchor(h) + if c is not None and (c.ClassName or "") == LOGIN_CLASS: + return c + return None + + # ------------------------------------------------------------------ 前台/登录 + @staticmethod + def _force_foreground(hwnd) -> bool: + if not _HAS_WIN32 or not hwnd: + return False + try: + if win32gui.IsIconic(hwnd): + win32gui.ShowWindow(hwnd, win32con.SW_RESTORE) + except Exception: + pass + if win32gui.GetForegroundWindow() == hwnd: + return True + cur = win32api.GetCurrentThreadId() + fg = win32gui.GetForegroundWindow() + fgt = win32process.GetWindowThreadProcessId(fg)[0] if fg else 0 + try: + if fgt: + win32process.AttachThreadInput(cur, fgt, True) + except Exception: + pass + ok = False + for _ in range(3): + try: + win32gui.ShowWindow(hwnd, win32con.SW_SHOW) + win32gui.BringWindowToTop(hwnd) + win32gui.SetForegroundWindow(hwnd) + if win32gui.GetForegroundWindow() == hwnd: + ok = True + break + except Exception: + pass + time.sleep(0.1) + try: + if fgt: + win32process.AttachThreadInput(cur, fgt, False) + except Exception: + pass + return ok + + def _activate(self, win) -> None: + if not self._force_foreground(win.NativeWindowHandle): + try: + win.ShowWindow(9) + except Exception: + pass + try: + win.SetActive() + except Exception: + pass + time.sleep(0.25) + + def _wait_main(self, timeout: float, allow_login: bool = True, + allow_accessibility_wake: bool = True): + deadline = time.time() + max(timeout, 15) + last_wake = time.time() + accessibility_woke = False + while time.time() < deadline: + if allow_login: + self._auto_login() + w = self._find_main() + if w is not None: + self._win = w + self._activate(w) + return w + if (allow_accessibility_wake and not accessibility_woke + and self._login_window() is None and self._wechat_hwnds() + and time.time() - last_wake > 3): + self._wake_accessibility() + accessibility_woke = True + last_wake = time.time() + continue + if self._login_window() is None and time.time() - last_wake > 6: + self.wake() + last_wake = time.time() + time.sleep(0.8) + raise UIATimeout("等待微信主窗口超时(客户端未就绪)。") + + def ensure_window(self, wake: bool = True, timeout: Optional[float] = None) -> bool: + """确保可访问的主窗口存在并置前,返回是否成功。 + + 优先 ControlFromHandle 按句柄锚定拿 mmui 树;若树未物化(只剩 Qt + 外壳)则对当前 Weixin 进程热激活,不重启微信。任一环节失败返回 + False,由调用方降级到 OCR。 + """ + timeout = timeout or self.timeout + w = self._find_main() + if w is not None: + self._win = w + self._activate(w) + return True + if not wake: + return False + try: + if self._login_window() is not None: + self._auto_login() + elif self._wechat_hwnds(): + self._wake_accessibility() + else: + self._set_screen_reader_flag(True) + self.wake() + self._wait_main(timeout) + return self._win is not None + except UIATimeout: + return False + except Exception as e: + wxlog.debug("ensure_window 失败:%s", e) + return False + + def _auto_login(self) -> bool: + lw = self._login_window() + if lw is None: + return False + self._force_foreground(lw.NativeWindowHandle) + time.sleep(0.3) + for nm in LOGIN_BTN_NAMES: + btn = lw.ButtonControl(Name=nm) + if btn.Exists(0.2, 0.1): + btn.Click() + time.sleep(1.2) + return True + ob = lw.ButtonControl(ClassName=LOGIN_OUTLINE_CLASS) + if ob.Exists(0.2, 0.1) and (ob.Name or "").strip(): + ob.Click() + time.sleep(1.2) + return True + return False + + # ------------------------------------------------------------------ 剪贴板 + @staticmethod + def _clip_get() -> str: + try: + import pyperclip + return pyperclip.paste() + except Exception: + pass + try: + return auto.GetClipboardText() + except Exception: + return "" + + @staticmethod + def _clip_set(text: str) -> None: + try: + import pyperclip + pyperclip.copy(text) + return + except Exception: + pass + try: + auto.SetClipboardText(text) + except Exception: + pass + + @staticmethod + def _set_cursor(x: int, y: int) -> None: + try: + import ctypes + ctypes.windll.user32.SetCursorPos(int(x), int(y)) + except Exception: + pass + + @staticmethod + def _mouse_wheel(delta: int) -> None: + try: + import ctypes + ctypes.windll.user32.mouse_event(0x0800, 0, 0, int(delta), 0) + except Exception: + pass + + @staticmethod + def _left_click() -> None: + try: + import ctypes + ctypes.windll.user32.mouse_event(0x0002, 0, 0, 0, 0) # down + time.sleep(0.05) + ctypes.windll.user32.mouse_event(0x0004, 0, 0, 0, 0) # up + except Exception: + pass + + @staticmethod + def _right_click() -> None: + try: + import ctypes + ctypes.windll.user32.mouse_event(0x0008, 0, 0, 0, 0) # down + time.sleep(0.05) + ctypes.windll.user32.mouse_event(0x0010, 0, 0, 0, 0) # up + except Exception: + pass + + # ------------------------------------------------------------------ 控件定位 + def _search_box(self, win): + for kw in (dict(ClassName=SEARCH_EDIT_CLASS, Name=SEARCH_EDIT_NAME), + dict(Name=SEARCH_EDIT_NAME), + dict(ClassName=SEARCH_EDIT_CLASS)): + e = win.EditControl(**kw) + if e.Exists(1.0, 0.2): + return e + return None + + def _chat_input(self, win=None): + win = win or self._win + if win is None: + return None + e = win.EditControl(AutomationId=CHAT_INPUT_AID) + return e if e.Exists(1.0, 0.2) else None + + def current_chat(self) -> Optional[str]: + e = self._chat_input() + return (e.Name or None) if e else None + + def _find_search_list(self, timeout: float = 3.0): + deadline = time.time() + timeout + while time.time() < deadline: + lst = auto.ListControl(searchDepth=0xFFFFFFFF, AutomationId=SEARCH_LIST_AID) + if lst.Exists(0.2, 0.1): + return lst + time.sleep(0.2) + return None + + def _collect_results(self, keyword: str, settle: float = 1.5) -> List[dict]: + """采集去重后的候选 [{name, section, aid, cell}]。""" + lst = self._find_search_list() + if lst is None: + return [] + deadline = time.time() + settle + raw = [] + while time.time() < deadline: + section = None + raw = [] + for c in lst.GetChildren(): + name = c.Name or "" + aid = c.AutomationId or "" + if not aid: + head = name.strip() + if head in SECTION_HEADERS: + section = head + continue + if not aid.startswith(RESULT_AID_PREFIX): + continue + raw.append({ + "cell": c, + "name": name.split("\n", 1)[0].strip(), + "section": section, + "aid": aid, + }) + if raw: + break + time.sleep(0.2) + + kw = keyword.strip() + matched = [r for r in raw if r["name"] == kw] + if not matched: + matched = raw[:] + + # 最常使用/最近使用中重复出现的同一 aid 去重 + non_freq = {r["aid"] for r in matched + if r["section"] not in ("最常使用", "最近使用")} + pruned = [r for r in matched + if not (r["section"] in ("最常使用", "最近使用") + and r["aid"] in non_freq)] + for i, r in enumerate(pruned): + r["index"] = i + return pruned + + # ------------------------------------------------------------------ 高层动作 + @staticmethod + def _resolve_search_keyword(keyword: str) -> List[str]: + """把账号/username 解析成微信搜索框能命中的关键词列表。 + + 微信搜索框不认 wxid(系统账号),只认昵称/备注/微信号(alias)。 + 优先返回直接命中词(原样),再尝试 DB 映射:username 精确 → 昵称/备注/微信号。 + """ + candidates = [keyword] + try: + from wechatauto.db import WeChatDB + db = WeChatDB() + for hit in db.search_contact(keyword): + for k in (hit.get("remark"), hit.get("nick_name")): + if k and k not in candidates: + candidates.append(k) + except Exception: + pass + return candidates + + def open_chat(self, keyword: str, index: Optional[int] = None, + section: Optional[str] = None, retries: int = 2) -> bool: + """搜索并打开联系人/群聊,成功后校验输入框 Name。返回是否成功。 + + 传入 username/wxid 时自动映射为昵称/备注/微信号再搜索(微信搜索框 + 不认 wxid)。搜索框残留会影响命中,每次打开前先清空重试。 + """ + if not self.ensure_window(): + return False + win = self._win + box = self._search_box(win) + if box is None: + return False + + keywords = self._resolve_search_keyword(keyword) + results = [] + used_kw = keyword + for kw in keywords: + got = False + for attempt in range(max(1, retries)): + self._paste_into(box, kw, clear=True) + time.sleep(0.8) + got = self._collect_results(kw) + if got: + break + time.sleep(0.4) + if got: + results = got + used_kw = kw + break + + if not results: + return False + + if section: + filtered = [r for r in results + if (r["section"] or "") == section] + if filtered: + results = filtered + if len(results) > 1 and index is not None: + filtered = [r for r in results if r["index"] == index] + if filtered: + results = filtered + elif len(results) > 1: + # 有精确名称命中时优先精确命中,否则用第一个 + exact = [r for r in results if r["name"] == used_kw] + if exact: + results = exact + + chosen = results[0] + chosen["cell"].Click() + time.sleep(0.7) + + name = self.current_chat() + if name and (name == chosen["name"] or name == used_kw): + return True + return False + + def send_text(self, text: str) -> bool: + """在已打开会话的输入框发送文本。返回是否成功。""" + if not self.ensure_window(): + return False + e = self._chat_input() + if e is None: + return False + self._paste_into(e, text, clear=True) + time.sleep(0.2) + try: + e.SendKeys("{Enter}", waitTime=0.05) + except Exception: + return False + return True + + def send_text_to(self, text: str, who: str) -> bool: + """打开会话并发送文本(组合动作)。""" + if self.current_chat() == who: + return self.send_text(text) + if not self.open_chat(who): + return False + return self.send_text(text) + + def voice_call(self, who: Optional[str] = None, video: bool = False) -> bool: + """发起语音/视频通话(点击标题栏通话按钮 → 选择菜单项)。 + + 微信 4.x 标题栏暴露 ``mmui::ChatVoIPView`` 下的 ``voip_button`` + (aid=voip_button)。点击后弹出 ``mmui::XMenuView`` 菜单,含 + 「语音通话」「视频通话」两个 ``MenuItemControl``(aid=XMenuItem); + 需再点击目标菜单项才真正发起通话。video=True 时选「视频通话」, + 否则选「语音通话」。 + """ + if not self.ensure_window(): + return False + if who and not self.current_chat() == who: + if not self.open_chat(who): + return False + win = self._win + if win is None: + return False + # voip_button 控件树会动态重建,需重试定位 + btn = None + for _ in range(6): + try: + btn = win.ButtonControl(AutomationId="voip_button") + if btn.Exists(0.6, 0.2): + break + except Exception: + pass + time.sleep(0.5) + if not btn or not btn.Exists(0): + return False + try: + btn.Click() + time.sleep(0.8) + except Exception: + return False + # 菜单里选择 语音/视频 通话项 + target_name = "视频通话" if video else "语音通话" + for _ in range(4): + try: + item = win.MenuItemControl(AutomationId="XMenuItem", Name=target_name) + if item.Exists(0.5, 0.2): + item.Click() + time.sleep(0.5) + return True + except Exception: + pass + # 菜单可能延迟出现或树重建,重试 + time.sleep(0.4) + return False + + def _find_friend_row(self): + """找一条对方(friend)消息行控件,供右键头像触发拍一拍。 + + 消息行 rect 是全宽,方向需按行内内容重心判断(friend 内容靠左, + self 靠右)。返回 friend 消息行控件。 + """ + lst = self._message_list() + if lst is None: + return None + try: + from PIL import ImageGrab as IG + import numpy as np + except Exception: + return None + # 可视区(消息列表内部矩形),过滤掉滚出可视区的行 + lr = lst.BoundingRectangle + vis_top, vis_bottom = lr.top, lr.bottom + # 优先文字行,其次其他内容行(动画表情/图片/引用等) + rows = list(lst.GetChildren()) + for ch in sorted(rows, key=lambda c: c.ClassName != "mmui::ChatTextItemView"): + try: + cn = ch.ClassName or "" + if not cn.startswith("mmui::Chat"): + continue + if cn in ("mmui::ChatItemView", "mmui::ChatSystemInfoItemView"): + continue + r = ch.BoundingRectangle + if r.bottom - r.top < 40: + continue + # 行必须在可视区内(含部分露出),排除被遮挡/滚出的行 + if r.top >= vis_bottom or r.bottom <= vis_top: + continue + img = IG.grab(bbox=(r.left, r.top, r.right, r.bottom)) + arr = np.array(img.convert("RGB")) + bg = (arr.max(axis=2) > 235) & ((arr.max(axis=2) - arr.min(axis=2)) < 22) + colc = (~bg).sum(axis=0) + total = int(colc.sum()) + if total < 20: + continue + weighted = sum(x * colc[x] for x in range(len(colc))) / total + if weighted < arr.shape[1] * 0.5: + return ch + except Exception: + continue + return None + + def poke(self, who: Optional[str] = None) -> bool: + """对联系人发起「拍一拍」(右键头像 → 点击拍一拍菜单项)。 + + 微信 4.x 的拍一拍只能通过右键聊天中对方头像触发,菜单为自绘 + 不暴露 UIA;因此用「右键头像 + 全屏 OCR 定位拍一拍文字」实现。 + 需要 winsdk OCR 可用。 + """ + if not self.ensure_window(): + return False + if who and not self.current_chat() == who: + if not self.open_chat(who): + return False + row = self._find_friend_row() + if row is None: + return False + try: + r = row.BoundingRectangle + except Exception: + return False + # 头像位于消息行最左侧约 40-50px 处 + ax = r.left + 70 + ay = (r.top + r.bottom) // 2 + try: + from wechatauto.guia import ScreenOCR + import PIL.ImageGrab as IG + except Exception: + return False + for attempt in range(2): + self._set_cursor(ax, ay) + time.sleep(0.2) + self._right_click() + time.sleep(1.0) + img = IG.grab() + res = ScreenOCR.recognize(img) + for text, x, y, w, h in res: + t = (text or "").replace(" ", "") + if "拍一拍" in t or t == "拍一" or t.startswith("拍一"): + # 点击该文字中心 + cx = x + w // 2 + cy = y + h // 2 + self._set_cursor(cx, cy) + time.sleep(0.2) + self._left_click() + time.sleep(0.5) + return True + return False + + def _right_click_latest_row(self, who: Optional[str] = None) -> Optional[Tuple[int, int]]: + """打开会话并右键最新一条消息行,返回气泡内右键坐标 (x, y);失败返回 None。""" + if not self.ensure_window(): + return None + if who and not self.current_chat() == who: + if not self.open_chat(who): + return None + lst = self._message_list() + if lst is None: + return None + rows = list(lst.GetChildren()) + # 取可视区内最底部(最新)的消息行;时间分隔行 ChatItemView 跳过 + candidates = [] + for ch in rows: + try: + cn = ch.ClassName or "" + if not cn.startswith("mmui::Chat"): + continue + if cn in ("mmui::ChatItemView", "mmui::ChatSystemInfoItemView"): + continue + r = ch.BoundingRectangle + if r.bottom - r.top < 40: + continue + candidates.append((ch, r)) + except Exception: + continue + if not candidates: + return None + # 最新消息在可视区底部(消息列表打开即定位在最新),取 bottom 最大者 + target = max(candidates, key=lambda t: t[1].bottom) + ch, r = target + # 消息行内取内容重心 x(self 靠右、friend 靠左),y 取行垂直中心 + try: + from PIL import ImageGrab as IG + img = IG.grab(bbox=(r.left, r.top, r.right, r.bottom)) + import numpy as np + arr = np.array(img.convert("RGB")) + bg = (arr.max(axis=2) > 235) & ((arr.max(axis=2) - arr.min(axis=2)) < 22) + colc = (~bg).sum(axis=0) + total = int(colc.sum()) + if total >= 20: + cx = sum(x * colc[x] for x in range(len(colc))) / total + cx = int(r.left + cx) + else: + cx = (r.left + r.right) // 2 + except Exception: + cx = (r.left + r.right) // 2 + cy = (r.top + r.bottom) // 2 + self._set_cursor(cx, cy) + time.sleep(0.2) + self._right_click() + time.sleep(1.0) + return (cx, cy) + + def _uia_find_menu_item(self, name_sub: str, max_depth: int = 6): + """在主窗口树内查找菜单项控件(UIA 方案)。 + + 微信 4.x 右键菜单在热激活后物化为 UIA 节点:``mmui::XMenu`` 下挂 + ``mmui::XMenuView``(Name 即菜单文字)。只遍历主窗口子树,避免 + 触发 Windows UIA 根遍历的系统挂起 bug。返回匹配的控件或 None。 + """ + w = self._win + if w is None: + return None + found = [None] + + def walk(c, d=0): + if found[0] is not None or d > max_depth: + return + try: + children = c.GetChildren() + except Exception: + return + for ch in children: + try: + nm = ch.Name or "" + cn = ch.ClassName or "" + except Exception: + nm = cn = "" + if cn == "mmui::XMenuView" and name_sub in nm: + found[0] = ch + return + walk(ch, d + 1) + + try: + walk(w) + except Exception: + return None + return found[0] + + def _uia_click_menu_item(self, ctrl) -> bool: + """通过 UIA Invoke/LegacyIAccessible 或鼠标点击菜单项控件。""" + for method in ("Invoke", "Select", "Expand"): + try: + getattr(ctrl, method)() + time.sleep(0.3) + return True + except Exception: + continue + try: + r = ctrl.BoundingRectangle + cx = (r.left + r.right) // 2 + cy = (r.top + r.bottom) // 2 + self._set_cursor(cx, cy) + time.sleep(0.2) + self._left_click() + time.sleep(0.3) + return True + except Exception: + return False + + def recall_last_message(self, who: Optional[str] = None) -> bool: + """撤回当前会话最新一条自己发送的消息。 + + UIA 方案优先:右键消息行后,主窗口树内 ``mmui::XMenuView`` 已物化 + 菜单项(Name 含「撤回」),直接定位点击;若菜单项为「删除」(消息 + 超过 2 分钟撤回时限)则返回失败。UIA 不可用/未命中时降级到 OCR + (全屏识别「撤回」文字定位点击)。两者都失败返回 False。 + """ + pos = self._right_click_latest_row(who) + if pos is None: + return False + # UIA 方案 + item = self._uia_find_menu_item("撤回") + if item is not None: + if self._uia_click_menu_item(item): + return True + # OCR 兜底 + try: + from wechatauto.guia import ScreenOCR + import PIL.ImageGrab as IG + except Exception: + return False + for attempt in range(2): + if attempt > 0: + cx, cy = pos + self._set_cursor(cx, cy) + time.sleep(0.2) + self._right_click() + time.sleep(1.0) + img = IG.grab() + res = ScreenOCR.recognize(img) + for text, x, y, w, h in res: + t = (text or "").replace(" ", "") + if "撤回" in t or t == "撤回": + cxx = x + w // 2 + cyy = y + h // 2 + self._set_cursor(cxx, cyy) + time.sleep(0.2) + self._left_click() + time.sleep(0.5) + return True + return False + + # ------------------------------------------------------------------ 剪贴板粘贴 + def _paste_into(self, ctrl, text: str, clear: bool = True) -> None: + ctrl.Click() + time.sleep(0.1) + if clear: + try: + ctrl.SendKeys("{Ctrl}a{Delete}", waitTime=0.05) + except Exception: + pass + self._clip_set(text) + try: + ctrl.SendKeys("{Ctrl}v", waitTime=0.05) + except Exception: + pass + + # ------------------------------------------------------------------ 消息列表定位 + def _message_list(self, win=None): + """定位当前会话的消息列表控件(RecyclerListView / chat_message_list)。""" + win = win or self._win + if win is None: + return None + + def walk(c, d=0): + if d > 15: + return None + for ch in c.GetChildren(): + try: + cn = ch.ClassName or "" + except Exception: + continue + if cn == "mmui::RecyclerListView": + return ch + r = walk(ch, d + 1) + if r is not None: + return r + return None + + return walk(win) + + def find_in_message_list(self, predicate, match_last: bool = False, + max_scrolls: int = 40) -> Optional[Tuple]: + """在消息列表中按谓词查找消息控件,返回 (className, name, rect)。 + + RecyclerListView 是虚拟化列表,只实例化可视区约 12 条;历史消息需 + 滚动。ScrollPattern 不可用(返回空),改用鼠标滚轮驱动列表滚动。 + match_last=True 时滚到底后从底部向上找,用于取最新表情/消息。 + """ + lst = self._message_list() + if lst is None: + return None + + def scroll(direction: str, times: int = 1) -> None: + # direction: 'up'=滚向最新(底部), 'down'=滚向历史(更早) + # 实测(微信4.1.12.26):open_chat 后消息列表定位在底部(最新), + # 滚轮 +120 滚向历史(更早),-120 滚向最新。 + try: + r = lst.BoundingRectangle + cx = (r.left + r.right) // 2 + cy = (r.top + r.bottom) // 2 + self._set_cursor(cx, cy) + delta = -120 if direction == 'up' else 120 + for _ in range(times): + self._mouse_wheel(delta) + time.sleep(0.2) + except Exception: + pass + + def visible(): + out = [] + for ch in lst.GetChildren(): + try: + cn = ch.ClassName or "" + nm = ch.Name or "" + if cn == "mmui::ChatItemView": # 时间分隔行跳过 + continue + if predicate(cn, nm): + out.append((cn, nm, ch)) + except Exception: + continue + return out + + # 列表定位在底部(最新)。match_last 直接取当前可视区最匹配的一条 + # (最新消息已实例化),没有才向上(滚向历史)翻找。 + if match_last: + got = visible() + if got: + ch = got[-1][2] + try: + r = ch.BoundingRectangle + return (got[-1][0], got[-1][1], r) + except Exception: + pass + for _ in range(max_scrolls): + got = visible() + if got: + ch = got[-1][2] + try: + r = ch.BoundingRectangle + return (got[-1][0], got[-1][1], r) + except Exception: + pass + scroll('down', 2) # 滚向历史找更早匹配 + return None + + # 非 match_last:从底部(最新)向历史逐屏扫描 + seen = set() + for _ in range(max_scrolls): + for cn, nm, ch in visible(): + try: + r = ch.BoundingRectangle + key = (r.left, r.top, r.right, r.bottom) + except Exception: + continue + if key in seen: + continue + seen.add(key) + if predicate(cn, nm): + return (cn, nm, r) + scroll('down', 2) + return None + + # ------------------------------------------------------------------ 调试 + def dump(self, max_depth: int = 16, max_nodes: int = 1500): + """打印主窗口 UIA 树(控件名失效时重新勘察)。""" + if not self.ensure_window(): + print("UIA 树不可用") + return + win = self._win + cnt = [0] + + def walk(c, d=0): + if d > max_depth or cnt[0] > max_nodes: + return + for k in c.GetChildren(): + if cnt[0] > max_nodes: + break + cnt[0] += 1 + try: + print(" " * d + f"{k.ControlTypeName} class={k.ClassName!r} " + f"name={(k.Name or '')[:30]!r} aid={k.AutomationId!r}") + except Exception: + continue + walk(k, d + 1) + + walk(win) diff --git a/wechatauto/utils/__init__.py b/wechatauto/utils/__init__.py new file mode 100644 index 0000000..7d895fc --- /dev/null +++ b/wechatauto/utils/__init__.py @@ -0,0 +1,34 @@ +from wechatauto.utils.win32 import ( + GetAllWindows, + GetCursorWindow, + GetPathByHwnd, + FindWindow, + FindWinEx, + SetClipboardText, + SetClipboardFiles, + SetClipboardData, + ReadClipboardData, + PasteFile, + get_windows_by_pid, + GetText, + GetAllWindowExs, +) +from wechatauto.utils.lock import LockManager, uilock + +__all__ = [ + "GetAllWindows", + "GetCursorWindow", + "GetPathByHwnd", + "FindWindow", + "FindWinEx", + "SetClipboardText", + "SetClipboardFiles", + "SetClipboardData", + "ReadClipboardData", + "PasteFile", + "get_windows_by_pid", + "GetText", + "GetAllWindowExs", + "LockManager", + "uilock", +] diff --git a/wechatauto/utils/lock.py b/wechatauto/utils/lock.py new file mode 100644 index 0000000..ce40fcc --- /dev/null +++ b/wechatauto/utils/lock.py @@ -0,0 +1,127 @@ +"""线程、进程与异步环境下的全局 UI 锁。""" + +from __future__ import annotations + +import asyncio +import functools +import inspect +import multiprocessing +import threading +from contextlib import asynccontextmanager, contextmanager +from typing import Any, Awaitable, Callable, TypeVar, overload + + +F = TypeVar("F", bound=Callable[..., Any]) +AsyncReturn = TypeVar("AsyncReturn") + + +class LockManager: + """提供跨线程/进程/异步的锁。 + + ``process_lock``(multiprocessing.Lock)不可重入:同一线程内嵌套 + ``acquire`` 会永久阻塞。因此用线程局部计数实现**同线程重入**——同一 + 线程重复获取时跳过进程锁(只需重入线程锁),保证 + ``@uilock`` 修饰的函数互相调用(如 ``Chat.ForwardVoiceMessage`` + 内部调用 ``VoiceMessage.forward_to``)不会死锁。 + """ + + process_lock = multiprocessing.Lock() + thread_lock = threading.RLock() + _async_lock: asyncio.Lock | None = None + _local = threading.local() + + @classmethod + def _get_async_lock(cls) -> asyncio.Lock: + """返回与当前事件循环绑定的 ``asyncio.Lock``。""" + + loop = None + try: + loop = asyncio.get_running_loop() + except RuntimeError: + pass + + lock = cls._async_lock + if lock is None or (loop and getattr(lock, "_loop", loop) is not loop): + lock = asyncio.Lock() + cls._async_lock = lock + return lock + + @classmethod + @contextmanager + def acquire(cls): + """同步环境下获取锁(同线程可重入)。""" + + depth = getattr(cls._local, "depth", 0) + if depth > 0: + # 同线程嵌套:进程锁已被本线程持有,跳过它,只重入线程锁 + with cls.thread_lock: + cls._local.depth = depth + 1 + try: + yield + finally: + cls._local.depth = depth + return + with cls.process_lock: + with cls.thread_lock: + cls._local.depth = 1 + try: + yield + finally: + cls._local.depth = 0 + + @classmethod + @asynccontextmanager + async def acquire_async(cls): + """异步环境下获取锁(同线程可重入)。""" + + depth = getattr(cls._local, "depth", 0) + if depth > 0: + async with cls._get_async_lock(): + with cls.thread_lock: + cls._local.depth = depth + 1 + try: + yield + finally: + cls._local.depth = depth + return + async with cls._get_async_lock(): + with cls.process_lock: + with cls.thread_lock: + cls._local.depth = 1 + try: + yield + finally: + cls._local.depth = 0 + + +@overload +def uilock(func: Callable[..., Awaitable[AsyncReturn]]) -> Callable[..., Awaitable[AsyncReturn]]: + ... + + +@overload +def uilock(func: F) -> F: + ... + + +def uilock(func: F): # type: ignore[misc] + """确保 UI 自动化操作串行执行的装饰器。""" + + if inspect.iscoroutinefunction(func): + + @functools.wraps(func) + async def async_wrapper(*args: Any, **kwargs: Any): + async with LockManager.acquire_async(): + return await func(*args, **kwargs) + + return async_wrapper + + @functools.wraps(func) + def sync_wrapper(*args: Any, **kwargs: Any): + with LockManager.acquire(): + return func(*args, **kwargs) + + return sync_wrapper # type: ignore[return-value] + + +__all__ = ["LockManager", "uilock"] diff --git a/wechatauto/utils/tools.py b/wechatauto/utils/tools.py new file mode 100644 index 0000000..28de353 --- /dev/null +++ b/wechatauto/utils/tools.py @@ -0,0 +1,340 @@ +from __future__ import annotations + +from datetime import datetime, timedelta +from pathlib import Path +import math +import re +import shutil +import time + +from PIL import Image + +from wechatauto.uia import ControlFromHandle, GetUiClassNameWithTimeout, QT_INTERNAL_WIN_CLASS_PREFIX +from wechatauto.utils.win32 import GetAllWindows + + +def get_file_dir(dir_path=None) -> Path: + if dir_path is None: + dir_path = Path('.').absolute() + elif isinstance(dir_path, str): + dir_path = Path(dir_path) + dir_path.mkdir(parents=True, exist_ok=True) + return dir_path + + +def find_window_from_root(classname=None, name=None, pid: int = None, uiaclsname: str = None, timeout=1): + t0 = time.time() + while True: + wins = find_all_windows_from_root(classname, name, pid, uiaclsname) + if len(wins) > 0: + return wins[0] + if time.time() - t0 > timeout: + return None + + +def find_all_windows_from_root(classname: str = None, name: str = None, pid: int = None, uiaclsname: str = None): + """从全部顶层窗口中找到满足条件的 UIA 控件。 + + Args: + classname: win32 窗口类名 + name: win32 窗口标题 + pid: 进程ID + uiaclsname: UIA 类名(如 mmui::MainWindow),优先于 win32 类名使用 + """ + windows = GetAllWindows() + targets = [] + for window in windows: + # 跳过 Qt 内部消息泵等隐藏窗口,其 UIA 服务可能阻塞调用 + if window[1].startswith(QT_INTERNAL_WIN_CLASS_PREFIX): + continue + if ( + (all((classname, name)) and classname == window[1] and name == window[2]) + or (all((classname, not name)) and classname == window[1]) + or (all((not classname, name)) and name == window[2]) + or (all((not classname, not name))) + ): + try: + if uiaclsname is not None: + if GetUiClassNameWithTimeout(window[0]) != uiaclsname: + continue + targets.append(ControlFromHandle(window[0])) + except Exception: + continue + if pid: + targets = [w for w in targets if w and w.ProcessId == pid] + if uiaclsname: + targets = [w for w in targets if w and w.ClassName == uiaclsname] + return targets + + +def now_time(fmt='%Y%m%d%H%M%S%f') -> str: + return datetime.now().strftime(fmt) + + +def parse_wechat_time(time_str: str) -> str: + """微信消息时间格式转换函数 + + Args: + time_str: 输入的时间字符串 + + Returns: + 转换后的时间字符串 + """ + time_str = time_str.replace('星期天', '星期日') + match = re.match(r'^(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$', time_str) + if match: + month, day, hour, minute, second = match.groups() + current_year = datetime.now().year + return datetime(current_year, int(month), int(day), int(hour), int(minute), int(second)).strftime('%Y-%m-%d %H:%M:%S') + + match = re.match(r'^(\d{1,2}):(\d{1,2})$', time_str) + if match: + hour, minute = match.groups() + return datetime.now().strftime('%Y-%m-%d') + f' {hour}:{minute}:00' + + match = re.match(r'^昨天 (\d{1,2}):(\d{1,2})$', time_str) + if match: + hour, minute = match.groups() + yesterday = datetime.now() - timedelta(days=1) + return yesterday.strftime('%Y-%m-%d') + f' {hour}:{minute}:00' + + match = re.match(r'^星期([一二三四五六日]) (\d{1,2}):(\d{1,2})$', time_str) + if match: + weekday, hour, minute = match.groups() + weekday_num = ['一', '二', '三', '四', '五', '六', '日'].index(weekday) + today_weekday = datetime.now().weekday() + delta_days = (today_weekday - weekday_num) % 7 + target_day = datetime.now() - timedelta(days=delta_days) + return target_day.strftime('%Y-%m-%d') + f' {hour}:{minute}:00' + + match = re.match(r'^(\d{4})年(\d{1,2})月(\d{1,2})日 (\d{1,2}):(\d{1,2})$', time_str) + if match: + year, month, day, hour, minute = match.groups() + return datetime(*[int(i) for i in [year, month, day, hour, minute]]).strftime('%Y-%m-%d %H:%M:%S') + + match = re.match(r'^(\d{2})-(\d{2}) (上午|下午) (\d{1,2}):(\d{2})$', time_str) + if match: + month, day, period, hour, minute = match.groups() + current_year = datetime.now().year + hour = int(hour) + if period == '下午' and hour != 12: + hour += 12 + elif period == '上午' and hour == 12: + hour = 0 + return datetime(current_year, int(month), int(day), hour, int(minute)).strftime('%Y-%m-%d %H:%M:%S') + + return time_str + + +def is_valid_image(file_path) -> bool: + path = Path(file_path) + + if not path.exists() or not path.is_file(): + return False + + try: + with Image.open(path) as img: + img.verify() # 只验证图像,不会完全解码 + return True + except Exception: + return False + + +def delete_update_files(): + """清理微信更新缓存,避免更新弹窗干扰自动化操作""" + home = Path.home() + update_dir = home / 'AppData' / 'Roaming' / 'Tencent' / 'xwechat' / 'update' + if update_dir.exists(): + for file in update_dir.iterdir(): + try: + shutil.rmtree(file) if file.is_dir() else file.unlink() + except Exception: + pass + + +# ============================================================================================================================================ +# 消息解析方法 +# ============================================================================================================================================ + +def detect_message_direction( + image_path: str, + avatar_height_ratio: float = 0.8, + tolerance: int = 0, +) -> tuple[str, float]: + """通过截图判断消息气泡的方向。 + + Args: + image_path: 消息截图路径。 + avatar_height_ratio: 头像在截图中占据的高度比例。 + tolerance: 像素颜色比较的容忍度。 + + Returns: + Tuple[str, float]: ``("left", distance)`` 或 ``("right", distance)``, + ``distance`` 表示从对应方向开始出现气泡的列索引,便于后续定位。 + """ + + img = Image.open(image_path) + if img.mode != 'RGB': + img = img.convert('RGB') + w, h = img.size + + # 仅取中间 band 区域 + band_h = int(h * avatar_height_ratio) + y0 = (h - band_h) // 2 + y1 = y0 + band_h + + pixels = img.load() # 获取像素访问对象 + + def is_uniform_column(x: int) -> bool: + base = pixels[x, y0] # 以 band 顶部像素作为参考 + for y in range(y0, y1): + r, g, b = pixels[x, y] + if (abs(r - base[0]) > tolerance or + abs(g - base[1]) > tolerance or + abs(b - base[2]) > tolerance): + return False + return True + + # 从左边扫描 + left_idx = math.inf + for x in range(w): + if not is_uniform_column(x): + left_idx = x + break + + # 从右边扫描 + right_idx = math.inf + for offset, x in enumerate(range(w - 1, -1, -1)): + if not is_uniform_column(x): + right_idx = offset # 距右边界的列数 + break + + if left_idx == math.inf and right_idx == math.inf: + # 都没找到变化列,兜底 + return 'right', math.inf + if left_idx <= right_idx: + return 'left', float(left_idx) + return 'right', float(right_idx) + + +def calculate_pixel_variance(region) -> float: + """计算图像区域的像素变化程度""" + if region.size[0] == 0 or region.size[1] == 0: + return 0 + + # 获取所有像素值 + pixels = list(region.getdata()) + + if not pixels: + return 0 + + # 分别计算R、G、B通道的方差 + r_values = [p[0] for p in pixels] + g_values = [p[1] for p in pixels] + b_values = [p[2] for p in pixels] + + r_variance = calculate_variance(r_values) + g_variance = calculate_variance(g_values) + b_variance = calculate_variance(b_values) + + return r_variance + g_variance + b_variance + + +def calculate_variance(values) -> float: + """计算数值列表的方差""" + if not values: + return 0 + + # 计算平均值 + mean = sum(values) / len(values) + + # 计算方差 + variance = sum((x - mean) ** 2 for x in values) / len(values) + + return variance + + +def calculate_color_diversity(region) -> float: + """计算区域颜色多样性(备用方法)""" + pixels = list(region.getdata()) + + if not pixels: + return 0 + + # 统计不同颜色的数量 + color_set = set(pixels) + unique_colors = len(color_set) + + # 计算颜色多样性比例 + diversity_ratio = unique_colors / len(pixels) + + return diversity_ratio + + +def detect_message_direction_enhanced( + image_path: str, + avatar_width_ratio: float = 0.15, + avatar_height_ratio: float = 0.8, +) -> tuple[str, float]: + """增强版检测,结合方差和颜色多样性""" + + img = Image.open(image_path).convert('RGB') + width, height = img.size + + avatar_width = int(width * avatar_width_ratio) + avatar_height = int(height * avatar_height_ratio) + avatar_start_y = (height - avatar_height) // 2 + avatar_end_y = avatar_start_y + avatar_height + + # 截取左右头像区域 + left_box = (0, avatar_start_y, avatar_width, avatar_end_y) + right_box = (width - avatar_width, avatar_start_y, width, avatar_end_y) + + left_region = img.crop(left_box) + right_region = img.crop(right_box) + + # 计算方差和颜色多样性 + left_variance = calculate_pixel_variance(left_region) + right_variance = calculate_pixel_variance(right_region) + + left_diversity = calculate_color_diversity(left_region) + right_diversity = calculate_color_diversity(right_region) + + # 综合评分(方差权重0.7,多样性权重0.3) + left_score = left_variance * 0.7 + left_diversity * 1000 * 0.3 + right_score = right_variance * 0.7 + right_diversity * 1000 * 0.3 + + if left_score > right_score: + return 'left', float(left_score) + return 'right', float(right_score) + + +def batch_detect_messages(image_paths, method='basic', **kwargs): + """批量检测多条消息的方向""" + results = [] + + detect_func = detect_message_direction if method == 'basic' else detect_message_direction_enhanced + + for path in image_paths: + try: + result = detect_func(path, **kwargs) + if isinstance(result, tuple): + direction, distance = result + else: + direction, distance = result, None + sender = '对方' if direction == 'left' else '自己' + results.append({ + 'path': path, + 'direction': direction, + 'sender': sender, + 'distance': distance, + }) + except Exception as e: + results.append({ + 'path': path, + 'direction': 'unknown', + 'sender': '未知', + 'error': str(e) + }) + + return results diff --git a/wechatauto/utils/win32.py b/wechatauto/utils/win32.py new file mode 100644 index 0000000..172cf9c --- /dev/null +++ b/wechatauto/utils/win32.py @@ -0,0 +1,402 @@ +import os +import time +import struct +import shutil +import traceback +import ctypes +from typing import List, Optional, Sequence, Tuple, Union + +import win32ui +import win32gui +import win32api +import win32con +import win32process +import win32clipboard +import pyperclip +import psutil +from PIL import Image + + +def GetAllWindows(name=None, classname=None) -> List[Tuple[int, str, str]]: + """获取所有顶层窗口的信息,返回 (窗口句柄, 类名, 窗口标题) 列表""" + windows = [] + + def enum_windows_proc(hwnd, extra): + class_name = win32gui.GetClassName(hwnd) + window_title = win32gui.GetWindowText(hwnd) + windows.append((hwnd, class_name, window_title)) + + win32gui.EnumWindows(enum_windows_proc, None) + if name: + windows = [i for i in windows if i[-1] == name] + if classname: + windows = [i for i in windows if i[1] == classname] + return windows + + +def GetCursorWindow(): + x, y = win32api.GetCursorPos() + hwnd = win32gui.WindowFromPoint((x, y)) + window_title = win32gui.GetWindowText(hwnd) + class_name = win32gui.GetClassName(hwnd) + return hwnd, window_title, class_name + + +def set_cursor_pos(x, y): + win32api.SetCursorPos((x, y)) + + +def Click(rect): + x = (rect.left + rect.right) // 2 + y = (rect.top + rect.bottom) // 2 + set_cursor_pos(x, y) + win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, x, y, 0, 0) + win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, x, y, 0, 0) + + +def GetPathByHwnd(hwnd) -> Optional[str]: + try: + thread_id, process_id = win32process.GetWindowThreadProcessId(hwnd) + process = psutil.Process(process_id) + return process.exe() + except Exception: + return None + + +def GetVersionByPath(file_path) -> Optional[str]: + try: + info = win32api.GetFileVersionInfo(file_path, '\\') + version = "{}.{}.{}.{}".format(win32api.HIWORD(info['FileVersionMS']), + win32api.LOWORD(info['FileVersionMS']), + win32api.HIWORD(info['FileVersionLS']), + win32api.LOWORD(info['FileVersionLS'])) + except Exception: + version = None + return version + + +def capture(hwnd, bbox) -> Image.Image: + """截取指定窗口的指定区域,返回 PIL 图像""" + window_rect = win32gui.GetWindowRect(hwnd) + win_left, win_top, win_right, win_bottom = window_rect + win_width = win_right - win_left + win_height = win_bottom - win_top + + # 获取窗口的设备上下文 + hwndDC = win32gui.GetWindowDC(hwnd) + mfcDC = win32ui.CreateDCFromHandle(hwndDC) + saveDC = mfcDC.CreateCompatibleDC() + + # 创建位图对象保存整个窗口截图 + saveBitMap = win32ui.CreateBitmap() + saveBitMap.CreateCompatibleBitmap(mfcDC, win_width, win_height) + saveDC.SelectObject(saveBitMap) + + # 使用PrintWindow捕获整个窗口(包括被遮挡或最小化的窗口) + result = ctypes.windll.user32.PrintWindow(hwnd, saveDC.GetSafeHdc(), 3) + + # 转换为PIL图像 + bmpinfo = saveBitMap.GetInfo() + bmpstr = saveBitMap.GetBitmapBits(True) + im = Image.frombuffer( + 'RGB', + (bmpinfo['bmWidth'], bmpinfo['bmHeight']), + bmpstr, 'raw', 'BGRX', 0, 1) + + # 释放资源 + win32gui.DeleteObject(saveBitMap.GetHandle()) + saveDC.DeleteDC() + mfcDC.DeleteDC() + win32gui.ReleaseDC(hwnd, hwndDC) + + # 计算bbox相对于窗口左上角的坐标 + bbox_left, bbox_top, bbox_right, bbox_bottom = bbox + crop_left = bbox_left - win_left + crop_top = bbox_top - win_top + crop_right = bbox_right - win_left + crop_bottom = bbox_bottom - win_top + + # 裁剪目标区域 + cropped_im = im.crop((crop_left, crop_top, crop_right, crop_bottom)) + return cropped_im + + +def GetText(HWND) -> str: + length = win32gui.SendMessage(HWND, win32con.WM_GETTEXTLENGTH) * 2 + buffer = win32gui.PyMakeBuffer(length) + win32api.SendMessage(HWND, win32con.WM_GETTEXT, length, buffer) + address, length_ = win32gui.PyGetBufferAddressAndLen(buffer[:-1]) + text = win32gui.PyGetString(address, length_)[:int(length / 2)] + buffer.release() + return text + + +def GetAllWindowExs(HWND) -> Optional[List[list]]: + if not HWND: + return None + handles = [] + win32gui.EnumChildWindows( + HWND, lambda hwnd, param: param.append([hwnd, win32gui.GetClassName(hwnd), GetText(hwnd)]), handles) + return handles + + +def FindWindow(classname=None, name=None, timeout=0) -> int: + t0 = time.time() + while True: + HWND = win32gui.FindWindow(classname, name) + if HWND: + break + if time.time() - t0 > timeout: + break + time.sleep(0.01) + return HWND + + +def FindWinEx(HWND, classname=None, name=None) -> list: + hwnds_classname = [] + hwnds_name = [] + + def find_classname(hwnd, classname): + classname_ = win32gui.GetClassName(hwnd) + if classname_ == classname: + if hwnd not in hwnds_classname: + hwnds_classname.append(hwnd) + + def find_name(hwnd, name): + name_ = GetText(hwnd) + if name in name_: + if hwnd not in hwnds_name: + hwnds_name.append(hwnd) + + if classname: + win32gui.EnumChildWindows(HWND, find_classname, classname) + if name: + win32gui.EnumChildWindows(HWND, find_name, name) + if classname and name: + hwnds = [hwnd for hwnd in hwnds_classname if hwnd in hwnds_name] + else: + hwnds = hwnds_classname + hwnds_name + return hwnds + + +def ClipboardFormats(unit=0, *units) -> List[int]: + units = list(units) + retry_count = 5 + while retry_count > 0: + try: + win32clipboard.OpenClipboard() + try: + u = win32clipboard.EnumClipboardFormats(unit) + finally: + win32clipboard.CloseClipboard() + break + except Exception: + retry_count -= 1 + units.append(u) + if u: + units = ClipboardFormats(u, *units) + return units + + +def ReadClipboardData() -> dict: + Dict = {} + formats = ClipboardFormats() + + for i in formats: + if i == 0: + continue + + retry_count = 5 + while retry_count > 0: + try: + win32clipboard.OpenClipboard() + try: + data = win32clipboard.GetClipboardData(i) + Dict[str(i)] = data + finally: + win32clipboard.CloseClipboard() + break + except Exception: + retry_count -= 1 + return Dict + + +def SetClipboardData(data_dict: dict) -> None: + try: + # 打开剪贴板 + win32clipboard.OpenClipboard() + + # 清空剪贴板 + win32clipboard.EmptyClipboard() + + # 遍历数据字典,设置各种格式的数据 + for format_id, data in data_dict.items(): + # 将字符串格式ID转换为整数 + format_num = int(format_id) + + if isinstance(data, str): + # 如果是字符串,使用Unicode格式 + win32clipboard.SetClipboardData(format_num, data) + elif isinstance(data, bytes): + # 如果是字节数据,直接设置 + win32clipboard.SetClipboardData(format_num, data) + except Exception as e: + print(f"设置剪贴板数据时出错: {e}") + + finally: + # 关闭剪贴板 + try: + win32clipboard.CloseClipboard() + except Exception: + pass + + +def SetClipboardText(text: str) -> None: + pyperclip.copy(text) + + +class DROPFILES(ctypes.Structure): + _fields_ = [ + ("pFiles", ctypes.c_uint), + ("x", ctypes.c_long), + ("y", ctypes.c_long), + ("fNC", ctypes.c_int), + ("fWide", ctypes.c_bool), + ] + + +def set_files_to_clipboard(file_paths: Union[str, Sequence[str]]) -> bool: + """将文件路径列表设置到剪贴板的 CF_HDROP 格式""" + # 如果传入的是单个字符串,转换为列表 + if isinstance(file_paths, str): + file_paths = [file_paths] + + # 验证文件路径是否存在 + valid_paths = [] + for path in file_paths: + if os.path.exists(path): + # 转换为绝对路径 + abs_path = os.path.abspath(path) + valid_paths.append(abs_path) + else: + raise ValueError(f"文件路径不存在: {path}") + + if not valid_paths: + return False + + try: + # 打开剪贴板 + win32clipboard.OpenClipboard() + + # 清空剪贴板 + win32clipboard.EmptyClipboard() + + # 计算偏移量(DROPFILES结构大小为20字节) + offset = 20 + + # 构建DROPFILES头部 + dropfiles_header = struct.pack(' bool: + return set_files_to_clipboard(paths) + + +def PasteFile(folder) -> bool: + folder = os.path.realpath(folder) + if not os.path.exists(folder): + os.makedirs(folder) + + t0 = time.time() + while True: + if time.time() - t0 > 10: + raise TimeoutError(f"读取剪贴板文件超时!") + try: + win32clipboard.OpenClipboard() + if win32clipboard.IsClipboardFormatAvailable(win32clipboard.CF_HDROP): + files = win32clipboard.GetClipboardData(win32clipboard.CF_HDROP) + for file in files: + filename = os.path.basename(file) + dest_file = os.path.join(folder, filename) + shutil.copy2(file, dest_file) + return True + else: + print("剪贴板中没有文件") + return False + except Exception: + pass + finally: + try: + win32clipboard.CloseClipboard() + except Exception: + pass + + +def enum_windows_by_pid(pid: int) -> List[int]: + window_list = [] + + def enum_callback(hwnd, lParam): + # 获取窗口的进程ID + _, process_id = win32process.GetWindowThreadProcessId(hwnd) + + # 如果是目标进程,检查窗口是否可见 + if process_id == pid: + if is_window_visible(hwnd): + window_list.append(hwnd) + return True + + win32gui.EnumWindows(enum_callback, None) + return window_list + + +def is_window_visible(hwnd) -> bool: + # 检查窗口是否可见 + style = win32gui.GetWindowLong(hwnd, win32con.GWL_STYLE) + # 检查窗口是否有 WS_VISIBLE 标志,且不是最小化的 + if style & win32con.WS_VISIBLE and not win32gui.IsIconic(hwnd): + return True + return False + + +def get_windows_by_pid(pid: int) -> List[int]: + while True: + try: + windows = enum_windows_by_pid(pid) + return windows + except Exception: + time.sleep(0.1) diff --git a/wechatauto/wx.py b/wechatauto/wx.py new file mode 100644 index 0000000..1097983 --- /dev/null +++ b/wechatauto/wx.py @@ -0,0 +1,810 @@ +"""wechatauto 顶层 API —— 兼容当前微信 4.x 客户端。 + +实现说明 +======== +早期版本基于 UIAutomation(``mmui::*`` 控件树)驱动微信。当前 4.1.x 客户端 +冷启动时 UIA 树只暴露 ``Qt51514QWindowIcon`` + ``MMUIRenderSubWindow*`` 空壳 +(原 wxauto UI 方案因此失效);通过热激活 Qt accessibility gate(见 +:mod:`wechatauto.uia_driver`)后可物化 ``mmui::*`` 完整控件树。 + +本模块把 :class:`WeChat` / :class:`Chat` 的公共 API 重新实现为 +「UIA 优先(:class:`wechatauto.uia_driver.WeChatUIA`)+ 坐标/OCR +(:class:`wechatauto.guia.WeChatGUI`)+ 本地数据库 +(:class:`wechatauto.db.WeChatDB`)」混合技术栈,**保持方法签名不变**, +原有调用方代码无需改动即可运行。 + +:class:`Listener` 抽象类保留仅为向后兼容(已由 :mod:`wechatauto.db` 的 +``Listener`` 取代)。 +""" + +from __future__ import annotations + +import ctypes +import os +import re +import threading +import time +from abc import ABC, abstractmethod +from typing import ( + Callable, + TYPE_CHECKING, + Union, + List, + Dict, + Literal, + Optional, +) + +from wechatauto.param import WxParam, WxResponse, PROJECT_NAME +from wechatauto.logger import wxlog +from wechatauto.utils.lock import uilock + +if TYPE_CHECKING: + from wechatauto.msgs.base import Message + + +# --------------------------------------------------------------------------- +# 兼容占位:UIA 时代的监听器抽象基类(保留导出,不再使用) +# --------------------------------------------------------------------------- + +class Listener(ABC): + """监听器抽象基类(兼容保留)。 + + 当前版本请使用 :class:`wechatauto.db.Listener`。 + """ + + @abstractmethod + def _get_listen_messages(self): + ... + + +# --------------------------------------------------------------------------- +# DB 消息 → Message 对象适配 +# --------------------------------------------------------------------------- + +class _FakeRect: + """伪矩形,供现有 Message 类计算 hash 使用。""" + + def __init__(self): + self.top = self.left = self.bottom = self.right = 0 + + def height(self): + return self.bottom - self.top + + def width(self): + return self.right - self.left + + +class _DBMessageControl: + """让 DB 消息复用现有 Message 子类的轻量伪控件。 + + 仅提供 ``Name`` / ``runtimeid`` / ``BoundingRectangle`` / ``Exists`` + 等只读接口;交互类操作(点击/滚动)因 DB 消息无对应控件而明确报错。 + """ + + def __init__(self, content: str, msg_id): + self.Name = content or '' + self.AutomationId = None + self.ClassName = "mmui::ChatTextItemView" + self.runtimeid = str(msg_id) + self._rect = _FakeRect() + + @property + def BoundingRectangle(self): + return self._rect + + def Exists(self, timeout=0) -> bool: + return True + + def GetChildren(self): + return [] + + def Click(self, *args, **kwargs): + raise NotImplementedError('DB 消息不支持点击操作') + + def RightClick(self, *args, **kwargs): + raise NotImplementedError('DB 消息不支持右键操作') + + +class _DBMessageParent: + """Message 所需的 parent 占位(root 指向 Chat)。""" + + def __init__(self, chat): + self.root = chat + self.msgbox = None + + +class _AllMessageChat: + """AddListenAll 使用的轻量 Chat 占位(仅含 .who,不触发 GUI 初始化)。""" + + def __init__(self, username: str): + self.who = username + self._wxid = username + + +def _extract_group_sender(content) -> str: + """群消息内容形如 ``wxid_xxx:\\n正文``,提取发送者 wxid。""" + if isinstance(content, bytes): + content = content.decode('utf-8', errors='ignore') + m = re.match(r'^(wxid_[0-9a-zA-Z_]+):\s*\n', content or '') + return m.group(1) if m else '' + + +def _pick_msg_class(is_self: bool, mtype: Optional[str], content: str): + from wechatauto.msgs import friend as friendmsg + from wechatauto.msgs import self as selfmsg + + mod = selfmsg if is_self else friendmsg + + def get(name): + return getattr(mod, name) + + if mtype == '文本': + return get('SelfTextMessage' if is_self else 'FriendTextMessage') + if mtype == '图片': + return get('SelfImageMessage' if is_self else 'FriendImageMessage') + if mtype == '语音': + return get('SelfVoiceMessage' if is_self else 'FriendVoiceMessage') + if mtype == '视频': + return get('SelfVideoMessage' if is_self else 'FriendVideoMessage') + if mtype == '位置': + return get('SelfLocationMessage' if is_self else 'FriendLocationMessage') + if mtype == '文件/链接/卡片': + head = (content or '')[:8] + if '[链接' in head or head.startswith('链接'): + return get('SelfLinkMessage' if is_self else 'FriendLinkMessage') + if head.startswith('文件') or '[文件' in head: + return get('SelfFileMessage' if is_self else 'FriendFileMessage') + if head.startswith('位置') or head.startswith('[位置'): + return get('SelfLocationMessage' if is_self else 'FriendLocationMessage') + if '[个人名片' in head or '[名片' in head: + return get('SelfPersonalCardMessage' if is_self else 'FriendPersonalCardMessage') + return get('SelfOtherMessage' if is_self else 'FriendOtherMessage') + if mtype == '动画表情': + return get('SelfEmojiMessage' if is_self else 'FriendEmojiMessage') + return get('SelfOtherMessage' if is_self else 'FriendOtherMessage') + + +def _db_row_to_message(row: dict, chat: 'Chat', self_wxid: str = None) -> 'Message': + """把 db.py 的消息行转换为现有 Message 子类实例。 + + direction 判定:``sender_id == 2`` 视为自己(与 guia 发送校验一致), + 也可用 self_wxid 比对兜底。 + """ + from wechatauto.db import WeChatDB + from wechatauto.msgs.mattr import SystemMessage + + mtype = row.get('type') + if mtype is None and row.get('local_type') is not None: + mtype = WeChatDB._msg_type_name(row.get('local_type')) + content = row.get('content') or '' + if isinstance(content, bytes): + content = WeChatDB._friendly_content(content, mtype) + sender_id = row.get('sender_id') + is_self = sender_id == 2 or bool(self_wxid and str(sender_id) == str(self_wxid)) + + ctrl = _DBMessageControl(content, row.get('local_id')) + parent = _DBMessageParent(chat) + + if mtype == '系统消息': + msg = SystemMessage(ctrl, parent) + else: + cls = _pick_msg_class(is_self, mtype, content) + msg = cls(ctrl, parent) + + # 附加 DB 元数据 + msg.local_id = row.get('local_id') + msg.sort_seq = row.get('sort_seq') + msg.create_time = row.get('create_time') + msg.wxid = sender_id + msg.attr = 'self' if is_self else 'friend' + sender = _extract_group_sender(content) or getattr(chat, 'who', '') + msg.sender = sender or getattr(chat, 'who', '') + msg.sender_remark = msg.sender + return msg + + +class SessionItem: + """会话列表条目(兼容 SessionElement 常用字段)。""" + + def __init__(self, name: str, unread: int = 0, summary: str = '', + last_time: int = 0, username: str = ''): + self.name = name + self.unread = unread + self.summary = summary + self.last_time = last_time + self.username = username + + def __repr__(self): + return f'<{PROJECT_NAME} - {self.__class__.__name__}("{self.name}")>' + + +def _resolve_wxid(db, name: str) -> str: + """把会话显示名解析为数据库 wxid;文件传输助手/未知则原样返回。""" + if name in ('filehelper', '文件传输助手'): + return 'filehelper' + try: + for hit in db.search_contact(name): + if name in (hit.get('nick_name'), hit.get('remark')): + return hit['username'] + except Exception: + pass + return name + + +# --------------------------------------------------------------------------- +# Chat +# --------------------------------------------------------------------------- + +class Chat: + """聊天窗口实例(基于 GUI + 本地数据库)。""" + + def __init__(self, who: str = None, gui=None, db=None): + from wechatauto.guia import WeChatGUI + from wechatauto.db import WeChatDB + + self.who = who or '' + self._gui = gui or WeChatGUI() + self._db = db or WeChatDB() + self._wxid = _resolve_wxid(self._db, self.who) + self._last_seq: Optional[int] = None + + def __repr__(self): + return f'<{PROJECT_NAME} - {self.__class__.__name__} object("{self.who}")>' + + def __str__(self): + return self.who or self.nickname + + def __add__(self, other): + return (self.who or '') + other + + def __radd__(self, other): + return other + (self.who or '') + + # -- 展示 ------------------------------------------------------------- + + def Show(self): + """打开该会话的聊天窗口并置前。""" + self._gui.open_chat(self.who) + + def Close(self) -> None: + """关闭聊天(GUI 模式下无独立窗口,置前即可)。""" + self._gui.bring_to_front() + + @uilock + def VoiceCall(self, who: str = None, video: bool = False) -> WxResponse: + """发起语音/视频通话。 + + Args: + who: 通话对象,不指定则使用当前聊天对象 + video: True 尝试视频通话(当前版本未暴露视频按钮,通常失败) + + Returns: + WxResponse + """ + target = who or self.who + uia = self._gui._get_uia() + if uia is None: + return WxResponse.failure('UIA 驱动不可用,无法发起通话') + if not uia.voice_call(target, video=video): + return WxResponse.failure('通话发起失败(可能未打开会话或控件不可用)') + return WxResponse.success(f'已发起通话:{target}') + + @uilock + def Poke(self, who: str = None) -> WxResponse: + """对联系人发起「拍一拍」(右键头像 → 点击拍一拍)。 + + Args: + who: 拍一拍对象,不指定则使用当前聊天对象 + + Returns: + WxResponse + """ + target = who or self.who + uia = self._gui._get_uia() + if uia is None: + return WxResponse.failure('UIA 驱动不可用,无法发起拍一拍') + if not uia.poke(target): + return WxResponse.failure('拍一拍失败(未找到对方消息或菜单不可识别)') + return WxResponse.success(f'已对 {target} 拍一拍') + + @uilock + def RecallLastMessage(self, who: str = None) -> WxResponse: + """撤回当前会话最近一条自己发送的消息。 + + Args: + who: 会话对象,不指定则使用当前聊天对象 + + Returns: + WxResponse + """ + target = who or self.who + uia = self._gui._get_uia() + if uia is None: + return WxResponse.failure('UIA 驱动不可用,无法撤回消息') + if not uia.recall_last_message(target): + return WxResponse.failure('撤回失败(消息已过期或控件不可识别)') + return WxResponse.success(f'已撤回对 {target} 发送的最近一条消息') + + @uilock + def ForwardVoiceMessage( + self, + who: str = None, + target: str = None, + save_dir: str = None, + ) -> WxResponse: + """转发语音消息(从本地媒体库提取 SILK 文件发送给目标)。 + + 微信不支持右键直接转发语音,故实现为「找到本地语音文件 → 以文件 + 消息发送」。默认转发本会话最近一条语音到 target(不指定则发给 + 本会话对象自身)。 + + Args: + who: 语音所在会话,不指定则用当前会话 + target: 转发目标联系人,不指定则转发给 who 本身 + save_dir: 语音文件临时保存目录 + + Returns: + WxResponse + """ + chat = Chat(who or self.who, self._gui, self._db) if who else self + msgs = chat.GetAllMessage() + for m in msgs: + if getattr(m, 'type', None) == 'voice': + return m.forward_to(target or chat.who, save_dir=save_dir) + return WxResponse.failure(f'会话「{chat.who}」最近 50 条中没有语音消息') + + # -- 信息 ------------------------------------------------------------- + + def ChatInfo(self) -> Dict[str, str]: + """获取聊天窗口信息。""" + info = {'chat_name': self.who, 'chat_type': 'friend'} + if self._wxid and self._wxid.endswith('@chatroom'): + info['chat_type'] = 'group' + return info + + # -- 发送 ------------------------------------------------------------- + + @uilock + def SendMsg( + self, + msg: str, + who: str = None, + clear: bool = True, + at: Union[str, List[str]] = None, + exact: bool = False, + ) -> WxResponse: + """发送消息。 + + Args: + msg: 消息内容 + who: 发送对象,不指定则发送给当前聊天对象 + clear: 是否发送前清空编辑框(GUI 路径恒清理) + at: @对象(支持 str 或 list) + exact: 是否精确匹配会话名 + + Returns: + WxResponse + """ + target = who or self.who + if at: + return self._gui.at_member(at, msg, target) + return self._gui.send_msg(msg, target) + + @uilock + def SendFiles( + self, + filepath, + who=None, + exact=False + ) -> WxResponse: + """向当前聊天窗口发送文件/图片。 + + Args: + filepath: 文件绝对路径(str 或 list) + who: 发送对象,不指定则发送给当前聊天对象 + exact: 是否精确匹配会话名 + + Returns: + WxResponse + """ + target = who or self.who + if isinstance(filepath, (list, tuple)): + result = None + for p in filepath: + result = self._gui.send_file(p, target) + return result or WxResponse.failure('文件列表为空') + return self._gui.send_file(filepath, target) + + # -- 读取 ------------------------------------------------------------- + + def GetAllMessage(self) -> List['Message']: + """获取当前聊天窗口最近 50 条消息。""" + rows = self._db.get_messages(self._wxid, limit=50) + self_wxid = self._db.get_self_info()['username'] + return [_db_row_to_message(r, self, self_wxid) for r in rows] + + def GetNewMessage(self) -> List['Message']: + """获取新消息(首次调用仅建立基线,返回空列表)。""" + latest = self._db.get_messages(self._wxid, limit=1) + current = latest[0]['sort_seq'] if latest else 0 + if self._last_seq is None: + self._last_seq = current + return [] + if current <= self._last_seq: + return [] + rows = self._db.get_new_messages(self._wxid, since_seq=self._last_seq) + self._last_seq = current + self_wxid = self._db.get_self_info()['username'] + return [_db_row_to_message(r, self, self_wxid) for r in rows] + + def GetMessageById(self, msg_id) -> Optional['Message']: + """根据消息 local_id 获取消息实例。""" + try: + local_id = int(str(msg_id).replace('db-', '')) + except (TypeError, ValueError): + return None + row = self._db.get_message_row(self._wxid, local_id) + if not row: + return None + return _db_row_to_message(row, self) + + def GetMessageByHash(self, msg_hash: str) -> Optional['Message']: + """根据消息哈希值获取消息实例。""" + if not msg_hash: + return None + self_wxid = self._db.get_self_info()['username'] + for row in self._db.get_messages(self._wxid, limit=200): + m = _db_row_to_message(row, self, self_wxid) + if m.hash == msg_hash or getattr(m, 'hash_text', None) == msg_hash: + return m + return None + + def GetLastMessage(self) -> Optional['Message']: + """获取当前聊天窗口的最后一条消息。""" + rows = self._db.get_messages(self._wxid, limit=1) + if not rows: + return None + return _db_row_to_message(rows[0], self) + + +# --------------------------------------------------------------------------- +# WeChat +# --------------------------------------------------------------------------- + +class WeChat(Chat, Listener): + """微信主窗口实例(兼容 API)。""" + + def __init__( + self, + nickname: str = None, + start_listener: bool = False, + debug: bool = False, + **kwargs + ): + from wechatauto.guia import WeChatGUI + from wechatauto.db import WeChatDB + + self._gui = WeChatGUI() + self._db = WeChatDB() + info = self._db.get_self_info() + self.nickname = nickname or info.get('nick_name') or info.get('username') or '' + self.who = self.nickname + self._wxid = info.get('username') or '' + self.listen: Dict[str, tuple] = {} + self._listener = None + self._listen_wrappers: Dict[str, Callable] = {} + self._listener_is_listening = False + self._listener_stop_event = threading.Event() + self._current_chat: Optional['Chat'] = None + self._listen_all_active = False + self._listen_all_callback: Optional[Callable] = None + + if start_listener: + self._listener_start() + if debug: + wxlog.set_debug(True) + wxlog.debug('Debug mode is on') + + # -- 监听(基于 db.Listener)------------------------------------------ + + def _listener_start(self): + from wechatauto.db import Listener as DBListener + if self._listener is not None: + if self._listener._thread and self._listener._thread.is_alive(): + return + self._listener = None + self._listener = DBListener(self._db, interval=WxParam.LISTEN_INTERVAL) + for name, (chat, _cb) in self.listen.items(): + wrapper = self._make_listen_cb(chat, _cb) + self._listen_wrappers[name] = wrapper + self._listener.add_listener(chat._wxid, wrapper) + self._listener.start() + self._listener_is_listening = True + self._listener_stop_event.clear() + + def _listener_stop(self): + if self._listener is not None: + self._listener.stop() + self._listener_is_listening = False + self._listener_stop_event.set() + + def _make_listen_cb(self, chat: 'Chat', callback: Callable) -> Callable: + self_wxid = self._db.get_self_info()['username'] + + def _wrapper(row: dict, listener) -> None: + try: + msg = _db_row_to_message(row, chat, self_wxid) + callback(msg, chat) + except Exception: + import traceback + wxlog.debug(f'监听消息回调发生错误:{traceback.format_exc()}') + + return _wrapper + + def _get_listen_messages(self): + """兼容占位:实际监听由 db.Listener 完成。""" + return + + @uilock + def AddListenChat( + self, + nickname: str, + callback: Callable[['Message', 'Chat'], None], + ) -> WxResponse: + """添加监听聊天。 + + Args: + nickname: 要监听的聊天对象(显示名) + callback: 回调函数,参数为 (Message 对象, Chat 对象) + + Returns: + Chat 对象(监听成功后返回) + """ + if not self._listener_is_listening: + wxlog.debug('检测到未开启监听器,开启监听器') + self._listener_start() + if nickname in self.listen: + return WxResponse.failure('该聊天已监听') + chat = Chat(nickname, self._gui, self._db) + if self._db.get_messages(chat._wxid, limit=1) == [] and not chat._wxid: + return WxResponse.failure('找不到聊天窗口') + self.listen[nickname] = (chat, callback) + wrapper = self._make_listen_cb(chat, callback) + self._listen_wrappers[nickname] = wrapper + if self._listener is not None: + self._listener.add_listener(chat._wxid, wrapper) + return chat + + def AddListenAll( + self, + callback: Callable[['Message', 'Chat'], None], + discover: bool = True, + ) -> WxResponse: + """监听所有会话的新消息(包括好友、群聊、文件传输助手等)。 + + Args: + callback: 回调函数,参数为 (Message 对象, Chat-like 对象)。 + Chat-like 对象的 .who 属性为会话原始 username。 + discover: 为 True 时自动发现新出现的会话(如新群聊)并注册 + 回调,无需重复调用。默认 True。 + + Returns: + WxResponse + + 示例:: + + wx = WeChat() + def on_all(msg, chat): + print(f'[{chat.who}] {msg.content}') + wx.AddListenAll(on_all) + wx.StartListening() + """ + if not self._listener_is_listening: + wxlog.debug('检测到未开启监听器,开启监听器') + self._listener_start() + if getattr(self, '_listen_all_active', False): + return WxResponse.failure('已开启全局监听') + self_wxid = self._db.get_self_info()['username'] + + def _wrap(row: dict, listener) -> None: + try: + username = row.get('username', '') + fake_chat = _AllMessageChat(username) + msg = _db_row_to_message(row, fake_chat, self_wxid) + callback(msg, fake_chat) + except Exception: + import traceback + wxlog.debug(f'全局监听回调发生错误:{traceback.format_exc()}') + + self._listen_all_callback = callback + self._listen_all_active = True + if self._listener is not None: + self._listener.add_all(_wrap, discover=discover) + return WxResponse.success('已开启全局监听') + + def RemoveListenAll(self) -> WxResponse: + """停止全局监听。""" + if not getattr(self, '_listen_all_active', False): + return WxResponse.failure('未开启全局监听') + self._listen_all_active = False + self._listen_all_callback = None + if self._listener is not None: + self._listener._discover_new = False + self._listener._all_callback = None + return WxResponse.success('已停止全局监听') + + def StartListening(self) -> None: + """启动监听。""" + self._listener_start() + + def StopListening(self, remove: bool = True) -> None: + """停止监听。 + + Args: + remove: 是否同时移除所有监听对象 + """ + self._listener_stop() + if remove: + self.listen.clear() + self._listen_wrappers.clear() + self._listen_all_active = False + self._listen_all_callback = None + + @uilock + def RemoveListenChat( + self, + nickname: str, + close_window: bool = True + ) -> WxResponse: + """移除监听聊天。 + + Args: + nickname: 要移除监听的聊天对象 + close_window: 是否关闭聊天窗口(GUI 模式忽略) + + Returns: + WxResponse + """ + if nickname not in self.listen: + return WxResponse.failure('未找到监听对象') + chat, _cb = self.listen[nickname] + if self._listener is not None: + wrapper = self._listen_wrappers.pop(nickname, None) + if wrapper is not None: + self._listener.remove_listener(chat._wxid, wrapper) + del self.listen[nickname] + return WxResponse.success() + + def KeepRunning(self): + """阻塞主线程直到手动停止监听。""" + while not self._listener_stop_event.is_set(): + try: + time.sleep(1) + except KeyboardInterrupt: + wxlog.debug(f'wechatauto("{self.nickname}") shutdown') + self.StopListening(True) + break + + # -- 会话 ------------------------------------------------------------- + + def GetSession(self) -> List['SessionItem']: + """获取当前会话列表。""" + sessions = [] + for row in self._db.get_sessions(limit=50): + username = row.get('username') or '' + name = row.get('last_sender') or username + if not name or name == username: + try: + nick = self._db.get_nickname(username) + name = nick or username + except Exception: + name = username + sessions.append(SessionItem( + name=name, + unread=row.get('unread', 0), + summary=row.get('summary', ''), + last_time=row.get('last_time', 0), + username=username, + )) + return sessions + + @uilock + def ChatWith( + self, + who: str, + exact: bool = True, + force: bool = False, + force_wait: Union[float, int] = 0.5 + ): + """打开聊天窗口。 + + Args: + who: 要聊天的对象 + exact: 搜索会话时是否精确匹配 + force: 忽略(兼容保留) + force_wait: 忽略(兼容保留) + + Returns: + str: 成功时返回会话显示名,失败返回 None + """ + chat = Chat(who, self._gui, self._db) + self._gui.open_chat(chat.who) + if self._gui.get_input_box(): + self._current_chat = chat + self.who = chat.who + self._wxid = chat._wxid + return chat.who + self._gui.open_chat(chat.who) + if self._gui.get_input_box(): + self._current_chat = chat + self.who = chat.who + self._wxid = chat._wxid + return chat.who + return None + + # -- 消息读取(委托给当前打开的会话)---------------------------------- + + def _cur(self) -> 'Chat': + return self._current_chat if self._current_chat is not None else self + + def GetAllMessage(self) -> List['Message']: + """获取当前打开会话的最近 50 条消息。""" + return self._cur().GetAllMessage() + + def GetNewMessage(self) -> List['Message']: + """获取当前打开会话的新消息。""" + return self._cur().GetNewMessage() + + def GetMessageById(self, msg_id) -> Optional['Message']: + """根据消息 local_id 获取消息实例。""" + return self._cur().GetMessageById(msg_id) + + def GetMessageByHash(self, msg_hash: str) -> Optional['Message']: + """根据消息哈希值获取消息实例。""" + return self._cur().GetMessageByHash(msg_hash) + + def GetLastMessage(self) -> Optional['Message']: + """获取当前打开会话的最后一条消息。""" + return self._cur().GetLastMessage() + + def GetSubWindow(self, nickname: str) -> Optional['Chat']: + """获取子窗口实例(GUI 模式下返回对应 Chat 对象)。""" + chat = Chat(nickname, self._gui, self._db) + try: + hits = self._db.search_contact(nickname) + except Exception: + hits = [] + if hits or nickname in ('filehelper', '文件传输助手'): + return chat + return None + + def GetAllSubWindow(self) -> List['Chat']: + """获取所有子窗口实例(GUI 模式下无独立子窗口,返回空列表)。""" + return [] + + # -- 路径 / 生命周期 --------------------------------------------------- + + @property + def path(self): + from wechatauto.utils.win32 import GetPathByHwnd + return GetPathByHwnd(self._gui.main_hwnd) + + @property + def dir(self): + wxdir = self.path + if not wxdir: + return None + wxdir = os.path.dirname(wxdir) + for d in os.listdir(wxdir): + if re.match(r'\d+\.\d+\.\d+\.\d+', d): + return os.path.join(wxdir, d) + return None + + def ShutDown(self): + """强制退出微信进程。""" + pid = ctypes.c_ulong() + ctypes.windll.user32.GetWindowThreadProcessId( + self._gui.main_hwnd, ctypes.byref(pid)) + if pid.value: + os.system(f'taskkill /f /pid {pid.value}')

x|)~c}1tD@eg)z$uj2vD5GviFN$&CQAoZ6FC2 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�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