wechat-scheduled-sender
微信定时群发控制台 · Electron + Python UIA 自动化🔥 一个 1 star 的新仓库,把微信自动化最难的那一步做对了
微信 4.x 的界面是 Qt 自绘的。这意味着所有基于 UIA(UI Automation)的自动化工具都会撞上同一堵墙:QAccessible 在响应 WM_GETOBJECT 之前,会检查 Weixin.dll 里一个运行时 active byte。冷启动时如果没开读屏模式,这个字节是 0——此时 UIA 只能拿到 Qt 外壳(实测约 2 个节点),会话列表、输入框、发送按钮全都看不见。
这个仓库(Alanine-gH/wechat-scheduled-sender)抓到的正是这一步:把这个字节热写为 1 之后,控件树立即实体化,实测从 2 个节点变成 90+ 个,session_list、chat_input_field、发送按钮全部出现,而且不需要重启微信。这件事本身值得记一笔——但它同时也决定了这个项目最致命的短板,后面会讲。
📋 三层架构与真实能力边界
先看清楚它到底自己写了什么、又借了什么,这决定了它的可靠性边界:
- Electron 主进程:目录重定向、拉起与回收 Python 边车、建窗口、系统集成;
- Python 边车:UIA 自动化引擎 + 本地 HTTP 服务,端口由系统分配(
--port 0),每次启动生成随机 token,只监听 127.0.0.1; - 单文件 HTML 控制台:经
preload拿到端口与 token,走X-Token头调本地接口。
关键要说实话:gate 热激活、SQLCipher 数据库解密这些核心能力,来自依赖库 wechatauto-replica(PyPI 1.2.9,Apache-2.0),不是本仓库原创。这个仓库自己写的是 920 行 sender.py(打开会话、校验目标、写内容、点发送、回读校验)、编排层和界面。所以它更像一个「把难用的库包成能用的产品」的工程,而不是底层突破。
📊 实测速查大表:它能做什么 vs 它做不到什么
⚠️ 五个硬伤:用之前必须知道的
- 依赖脆弱是结构性的,不是 bug:微信从
4.1.15.13自动更新到4.2.0.11后,gate RVA 从0xb135c38变成0xb507c08。库「扫到一个候选值就标记 verified」,结果控件树时有时无——26 条目标全部失败。这类方案的宿命是:微信一升级就得等库更新,中间是不可用状态; - 合规风险明确:本质是逆向 + 自动化微信客户端,违反微信用户协议,账号封禁风险由使用者承担。作者自己在宣传物料里也写明「不是官方接口,高频群发有风控风险,内容请合法合规」;
- 仓库没有 LICENSE 文件:
LICENSE请求返回 404,README 里「许可」二字出现 0 次。宣传图上标着 MIT,但仓库里没有对应文件——法律上等于保留所有权利,不能直接商用或二次分发; - 安全设计有缺口:服务端
Access-Control-Allow-Origin: "*"通配,配合「浏览器模式无 token 就放行」的设计,意味着任意网页都能跨域打这个本地服务。虽然只监听 127.0.0.1,但浏览器模式下等于本地接口对全网页面开放; - 微信必须已登录且窗口可恢复:数据库密钥存在微信进程内存里,首次提取后缓存到本地;发送是 GUI 操作,微信完全退出就跑不了。另外安装目录必须可写,不要装在
C:\Program Files下。
- 创建与推送都在 2026-11-02 当天(06:59 → 09:11 UTC),属于刚发布的新项目;
- stars 1 / forks 1 / watchers 0,作者账号 19 个公开仓库、0 follower——几乎没有社区验证,踩坑只能靠自己;
- 仓库里还带了 5.8MB 宣传视频、分镜工程、配音时间轴与发布文案,是带推广意图的项目,不是纯技术沉淀。
🎯 值得学的不是代码,是这个习惯
- 第一层:Electron 路径重定向——必须在
app ready之前调app.setPath()改道userData/sessionData/temp/crashDumps/logs,晚了就先创建再改道,为时已晚; - 第二层:环境变量(这一步最容易漏)——只调
app.setPath('temp')不够,它只改浏览器进程的 PathService;Chromium 的子进程(renderer / GPU / network)用继承的TEMP/TMP环境变量经GetTempPath()自己解析临时目录。必须同时改process.env.TEMP/TMP/TMPDIR; - 第三层:第三方库兜底——把
os.path.expanduser('~')整体重定向到安装目录,且必须在import wechatauto之前执行,否则模块级常量已经算好了。
- 作者做了一次独立验证:另开一个进程,自己取基线、自己冷启动、自己归因,不依赖主程序的日志自证;
- 第一轮没通过——抓到真实反例:Chromium 渲染进程每次启动都在真实
%TEMP%里留一个 0 字节 GUID.tmp; - 用 Restart Manager 归因确认占用者是
--type=renderer,单独跑 Python 服务做同一次数据库读取则零新增——反证不是 Python 侧; - 补上
process.env.TEMP/TMP/TMPDIR后复验:3 次冷启动(含一次 78 秒)10 → 10,零新增,才判定通过。
结论:技术上它能跑,但只在特定微信版本上;工程上「用户文件重定向 + 独立验证」这套方法论值得学。但我不建议直接使用——合规风险、版本脆弱、缺 LICENSE 三条叠加,代价大于收益。真要用,先找作者补许可声明,并接受「微信一升级就可能全线失效」这个前提。作者本人在推广时把风险说在前面,这点是负责任的;问题出在仓库少了那个 LICENSE 文件。