# Wechat Desktop Automation

> Use when driving WeChat/Weixin on Windows: 搜索会话、剪贴板粘贴发消息。

- Skill: `liberation8/wechat-desktop-automation` (Agent Skill)
- Install (CLI): `npx skillmds@latest add liberation8/wechat-desktop-automation`
- Raw SKILL.md: https://api.skillmd.com/api/skills/liberation8/wechat-desktop-automation/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: liberation8 (https://skillmd.com/u/liberation8)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/liberation8/wechat-desktop-automation

---


# 微信桌面端自动化（Windows）

在 Windows 上通过 computer_use + PowerShell 驱动微信（Weixin 4.x）等自绘 UI 应用：搜索会话、输入文字、发送消息。

## 核心要点（血泪教训）

1. **微信 4.0 是自绘 UI**：UIA 树为空（capture 返回 0 elements），无法读取界面内容，也无法用元素索引点击。只能靠键盘快捷键 + 坐标。
2. **PostMessage 键盘注入对微信无效**：background 模式的 type/key 发不进微信输入框。
3. **Windows foreground lock**：SetForegroundWindow 从非 UIAccess 进程调用会被拒绝。必须先模拟按一下 Alt 键解锁，再 SetForegroundWindow。
4. **SendInput 逐字符输入长中文会被 IME 干扰**：文字乱码、符号重复、内容不完整。**短文本（≤4字）可以 SendInput，长文本必须用剪贴板粘贴**。
5. **不要 Start-Process 启动微信新实例**：会弹出"扫码登录"窗口而不是恢复已有窗口。微信已在运行时就复用现有进程。

## 标准流程

### 1. 确认微信运行状态
```
computer_use(action="list_apps")     # 找 Weixin.exe / 微信，记下 PID
computer_use(action="list_windows")  # 找标题为"微信"的主窗口（注意可能有两个微信窗口：
                                     # 主窗口标题"微信"是大窗口，标题"Weixin"的小窗是浮窗，避开它）
```
若微信未运行：`Start-Process 'C:\Program Files\Tencent\Weixin\Weixin.exe'` 并等待。

### 2. 激活微信窗口到前台（关键步骤）
用 PowerShell + user32（模拟 Alt 解锁 foreground lock）：
```powershell
Add-Type @'
using System;
using System.Runtime.InteropServices;
public class Win32 {
  [DllImport("user32.dll")] public static extern bool SetForegroundWindow(IntPtr hWnd);
  [DllImport("user32.dll")] public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo);
}
'@
$p = Get-Process Weixin | Where-Object { $_.MainWindowHandle -ne 0 } | Select-Object -First 1
[Win32]::keybd_event(0x12, 0, 0, [UIntPtr]::Zero)  # Alt down
[Win32]::keybd_event(0x12, 0, 2, [UIntPtr]::Zero)  # Alt up
Start-Sleep -Milliseconds 200
[Win32]::SetForegroundWindow($p.MainWindowHandle)  # 返回 True 表示成功
```
（git-bash 中执行时注意转义 `$` 为 `\$`，`"` 为 `\"`）

### 2b. 【推荐】SendKeys 一体化脚本（一次搞定搜索+发送）
cua-driver 的 foreground 模式会被 Windows foreground lock 反复拒绝（每次调用间用户一切窗口就失效）。
**最可靠方案**：在同一个 PowerShell 进程内完成"激活窗口 → 全部按键"，中文一律走剪贴板：

```powershell
$ErrorActionPreference = 'Stop'
Add-Type -AssemblyName System.Windows.Forms
Add-Type @'
using System;
using System.Runtime.InteropServices;
public class Win32 {
  [DllImport("user32.dll")] public static extern bool SetForegroundWindow(IntPtr hWnd);
  [DllImport("user32.dll")] public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo);
}
'@
$p = Get-Process Weixin | Where-Object { $_.MainWindowHandle -ne 0 } | Select-Object -First 1
[Win32]::keybd_event(0x12, 0, 0, [UIntPtr]::Zero)
[Win32]::keybd_event(0x12, 0, 2, [UIntPtr]::Zero)
Start-Sleep -Milliseconds 200
$ok = [Win32]::SetForegroundWindow($p.MainWindowHandle)
Start-Sleep -Milliseconds 300
if (-not $ok) { Write-Host 'ACTIVATE_FAILED'; exit 1 }
# 搜索会话：Ctrl+F → 全选清空 → 粘贴名称 → 回车进入
[System.Windows.Forms.SendKeys]::SendWait('^f'); Start-Sleep -Milliseconds 500
[System.Windows.Forms.SendKeys]::SendWait('^a'); Start-Sleep -Milliseconds 200
[System.Windows.Forms.SendKeys]::SendWait('{DELETE}'); Start-Sleep -Milliseconds 200
Set-Clipboard -Value '会话名'
[System.Windows.Forms.SendKeys]::SendWait('^v'); Start-Sleep -Milliseconds 500
[System.Windows.Forms.SendKeys]::SendWait('{ENTER}'); Start-Sleep -Milliseconds 800
# 发送消息：粘贴内容 → 回车
Set-Clipboard -Value '消息内容'
[System.Windows.Forms.SendKeys]::SendWait('^v'); Start-Sleep -Milliseconds 300
[System.Windows.Forms.SendKeys]::SendWait('{ENTER}')
Write-Host 'DONE'
```
要点：SendKeys 只发 ASCII 快捷键（^f ^a ^v {ENTER} {DELETE}），中文全部 Set-Clipboard + 粘贴。
一次调用内完成可避免 foreground lock 反复发作。缺点是无法中途确认，只能靠最终用户确认。

### 3. 搜索并进入会话
```
computer_use(action="key", keys="ctrl+f", delivery_mode="foreground")  # 微信搜索快捷键
computer_use(action="type", text="<会话名>", delivery_mode="foreground") # 短名称可 SendInput；名称长/含符号用剪贴板
computer_use(action="key", keys="return", delivery_mode="foreground")    # 进入第一个搜索结果
```

### 4. 输入消息内容（长文本必须剪贴板粘贴）
```powershell
Set-Clipboard -Value '<完整消息文本>'   # 中文文本 UTF-16，无编码问题
```
然后：
```
computer_use(action="key", keys="ctrl+v", delivery_mode="foreground")  # 粘贴
computer_use(action="key", keys="return", delivery_mode="foreground")  # 回车发送
```

### 5. 验证
由于无法读取界面，必须让用户确认发送结果（用 clarify 提问）。

## 陷阱清单

- **窗口识别**：`focus_app` 可能定位到小浮窗（标题 "Weixin"，约 258x83）而不是主窗口（标题"微信"，~880x639）。用 `list_windows` 核对 PID 和标题，capture 时显式传 `pid` + `window_id`。
- **`No active window` 错误**：foreground 操作前先 `capture(pid=..., window_id=...)` 建立窗口上下文。
- **中文标点**：`「」～` 等符号在注入时容易显示异常，写消息内容时优先用基础中文标点（，。！）。
- **发送后文字残留**：若上一条消息没发出去，输入框会有残留，再次输入前先按 `ctrl+a` + `delete` 清空（或让用户手动清）。
- **误发多条**：发错格式的消息会留在群里，提醒用户手动撤回。
- **辅助视觉模型不可用**：`vision_analysis` 可能报 `unknown variant image_url`（辅助模型不支持图片），此时无法靠截图确认界面，只能靠键盘流程 + 用户确认。

## 验证步骤

完成后向用户确认：
1. 会话是否进入正确（群名/联系人名）
2. 消息内容是否完整无乱码
3. 是否发送成功

