Mac 睡眠之后微信不会退出附完美解决方案
z 2026-03-20
随笔
一直有个挺烦人的问题:
👉 Mac 上登录微信后,手机设置免提醒。但电脑睡眠之后手机基本就收不到通知了。
尤其是合上电脑盖子或睡眠之后,人已经走了,结果手机也不提醒,容易错过消息。
折腾了一下,搞了个比较稳定的自动方案:Mac 睡眠自动退出微信,唤醒自动恢复(稳定方案),效果还不错,记录一下。
# 问题本质
WeChat 的机制是:
PC 在线 → 手机不推送
PC 离线 → 手机恢复推送
1
2
2
所以核心思路其实很简单:
Mac 睡眠 → 让微信下线
Mac 唤醒 → 再自动打开微信
1
2
2
# 为什么不用 sleepwatcher
一开始试的是 sleepwatcher:
brew install sleepwatcher
1
确实能用,但有几个问题:
- 偶尔不触发(特别是快速合盖)
- 微信有时候退出不干净
- 唤醒时容易启动失败
- 没有日志,出问题不好排查
👉 结论:能用,但不稳
# 最终方案:Hammerspoon(推荐)
用的是:Hammerspoon
它是基于 macOS 系统事件的自动化工具,比 sleepwatcher 稳很多。
# 实现效果
最终效果:
Mac 合盖 / 睡眠 → 自动退出微信 → 手机恢复通知 ✅
Mac 唤醒 → 自动打开微信(带重试)✅
1
2
2
基本无感使用。
# 安装
brew install --cask hammerspoon
1
启动后,编辑配置文件:
vim ~/.hammerspoon/init.lua
1
# 核心脚本
-- ================================
-- Mac睡眠 WeChat 自动控制(优雅退出 + 强制兜底 + 自动登录)
-- ================================
local logFile = "/tmp/wechat_sleep.log"
-- 分隔符
local function logSeparator(title)
local f = io.open(logFile, "a")
if f then
f:write("\n========================================\n")
f:write(os.date("%Y-%m-%d %H:%M:%S ") .. title .. "\n")
f:write("========================================\n")
f:close()
end
end
-- 普通日志
local function log(msg)
local f = io.open(logFile, "a")
if f then
f:write(os.date("%Y-%m-%d %H:%M:%S ") .. msg .. "\n")
f:close()
end
end
-- 用系统进程判断
local function isWeChatRunning()
local result = hs.execute("pgrep -x WeChat")
return result ~= nil and result ~= ""
end
-- 优雅退出
local function quitWeChatGracefully()
if not isWeChatRunning() then
return true
end
log("尝试优雅退出微信(osascript)")
hs.execute("osascript -e 'quit app \"WeChat\"'")
for i = 1, 15 do
if not isWeChatRunning() then
log("优雅退出成功")
return true
end
hs.timer.usleep(200000)
end
log("优雅退出超时")
return false
end
-- 强制终止
local function killWeChatForce()
log("执行强制终止(pkill)")
hs.execute("pkill WeChat")
hs.timer.usleep(500000)
if not isWeChatRunning() then
log("pkill 终止成功")
return true
end
log("pkill 未生效,升级为 pkill -9")
hs.execute("pkill -9 WeChat")
for i = 1, 20 do
if not isWeChatRunning() then
log("强制终止成功,微信已退出")
return true
end
hs.timer.usleep(300000)
end
log("严重异常:强制终止后仍检测到进程")
return false
end
-- 停止流程
local function stopWeChat()
if not isWeChatRunning() then
log("微信未运行,无需处理")
return
end
local ok = quitWeChatGracefully()
if not ok then
killWeChatForce()
end
if isWeChatRunning() then
log("执行最终兜底强杀")
hs.execute("pkill -9 WeChat")
end
if not isWeChatRunning() then
log("微信已完全退出")
else
log("严重异常:微信仍在运行")
end
end
-- 启动微信
local function startWeChat()
for i = 1, 5 do
log("尝试启动微信,第 " .. i .. " 次")
hs.application.launchOrFocus("WeChat")
hs.timer.sleep(2)
if isWeChatRunning() then
log("微信启动成功")
return
end
end
log("微信启动失败")
end
-- 网络检测
local function waitForNetwork(timeout)
local t = 0
while t < timeout do
local ok = hs.execute("ping -c 1 8.8.8.8 >/dev/null 2>&1")
if ok then
log("网络已恢复")
return true
end
hs.timer.sleep(1)
t = t + 1
end
log("网络检测超时")
return false
end
-- 监听
local watcher = hs.caffeinate.watcher.new(function(event)
if event == hs.caffeinate.watcher.systemWillSleep then
logSeparator("系统准备进入睡眠")
stopWeChat()
elseif event == hs.caffeinate.watcher.systemDidWake then
logSeparator("系统已唤醒")
hs.timer.doAfter(5, function()
waitForNetwork(10)
if not isWeChatRunning() then
startWeChat()
else
log("微信已在运行,无需启动")
end
end)
end
end)
watcher:start()
logSeparator("微信自动控制服务已启动")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# 如何生效
修改完后:
打开 APP 应用:Hammerspoon → Reload Config
1
或者:
hs -c "hs.reload()"
1
# 效果验证
可以看日志:
tail -f /tmp/wechat_sleep.log
1
能看到:
========================================
2026-03-20 18:09:38 系统准备进入睡眠
========================================
2026-03-20 18:09:38 尝试优雅退出微信(osascript)
2026-03-20 18:09:39 优雅退出成功
2026-03-20 18:09:39 微信已完全退出
========================================
2026-03-20 18:09:53 系统已唤醒
========================================
2026-03-20 18:09:58 网络已恢复
2026-03-20 18:09:58 尝试启动微信,第 1 次
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 一些细节优化
# 1 为什么要强杀(pkill)
因为:osascript quit 不一定成功有时候微信会残留进程。
# 2 为什么要延迟 5 秒
因为刚唤醒时:
- Wi-Fi 可能还没连上
- 系统还没完全恢复
# 3 为什么要检测网络
避免:微信启动 → 没网 → 登录失败
# 适合人群
- Mac 常驻微信用户
- 经常合盖离开
- 依赖手机通知
# 总结
👉 用 Hammerspoon 接管系统事件,比“脚本 + 运气”靠谱得多。
这个方案的核心是:
监听系统睡眠/唤醒事件
+ 自动控制微信进程
+ 加上重试 网络检测
1
2
3
2
3
优点:
- 稳定
- 有日志(可排查)
- 基本无感
打赏一下

「真诚赞赏,手留余香」
# 打赏记录
| 打赏者 | 打助金额 (元) | 支付方式 | 时间 | 备注 |
|---|---|---|---|---|
| John | 12 | 微信 | 2020-06-09 | |
| 艾斯 | 32 | 支付宝 | 2020-07-11 | nice |
| HickSalmon | 15 | 微信 | 2020-09-21 | 有赏交流 |