第09章 - 剪贴板操作
剪贴板是桌面自动化中一个看似简单却极其实用的能力。它不仅能在程序之间传递文本,更是“高效输入大段文本”和“读取界面内容”的关键手段。本章讲解 RobotGo 的剪贴板读写函数、它在自动化中的高级用法,以及相关的平台依赖与注意事项。
9.1 剪贴板的两个核心函数
RobotGo 主库提供了两个简洁的剪贴板函数:
WriteAll(text string) error:把文本写入系统剪贴板。ReadAll() (string, error):从系统剪贴板读取文本。
基本用法:
package main
import (
"fmt"
"github.com/go-vgo/robotgo"
)
func main() {
// 写入剪贴板
err := robotgo.WriteAll("通过 RobotGo 写入的文本")
if err != nil {
fmt.Println("写入失败:", err)
return
}
// 读取剪贴板
text, err := robotgo.ReadAll()
if err != nil {
fmt.Println("读取失败:", err)
return
}
fmt.Println("剪贴板内容:", text)
}
两个函数都返回 error,在实际代码中应当检查错误,尤其是在 Linux 上(剪贴板依赖外部命令,环境不全时可能失败)。
9.2 高级用法一:用剪贴板快速输入大段文本
第 5 章提到,Type 是逐字符输入,输入长文本既慢又容易因输入法干扰而出错。利用剪贴板“写入 + 粘贴”可以瞬间完成大段文本输入:
func pasteText(text string) error {
if err := robotgo.WriteAll(text); err != nil {
return err
}
robotgo.MilliSleep(100) // 给系统一点时间完成写入
// 粘贴:Windows/Linux 用 ctrl,macOS 用 cmd
robotgo.KeyTap("v", "ctrl")
return nil
}
这种方式与文本长度几乎无关,无论是几个字还是几千字,粘贴都是一瞬间完成,而且不受输入法状态影响,是自动化填表、批量录入的首选方案。
9.3 高级用法二:用剪贴板读取界面内容
反过来,剪贴板也是“读取屏幕上文本”的有效途径。很多 GUI 控件无法直接读取其文本,但可以通过“全选 + 复制”把内容送进剪贴板,再用 ReadAll 读出来:
func grabSelectedText() (string, error) {
// 复制当前选中内容
robotgo.KeyTap("c", "ctrl")
robotgo.MilliSleep(100) // 等待系统完成复制
return robotgo.ReadAll()
}
func grabAllText() (string, error) {
robotgo.KeyTap("a", "ctrl") // 全选
robotgo.MilliSleep(50)
robotgo.KeyTap("c", "ctrl") // 复制
robotgo.MilliSleep(100)
return robotgo.ReadAll()
}
这是在无法通过常规 API 读取内容时的“万能读取法”,在自动化测试中用于断言界面文本尤为常见。
9.4 高级用法三:保护与恢复用户剪贴板
自动化脚本使用剪贴板会覆盖用户原本的剪贴板内容,这可能造成困扰。礼貌的做法是在操作前备份、操作后恢复:
func withClipboard(temp string, action func()) error {
// 备份原剪贴板
backup, _ := robotgo.ReadAll()
// 写入临时内容并执行操作
if err := robotgo.WriteAll(temp); err != nil {
return err
}
robotgo.MilliSleep(50)
action()
// 恢复原剪贴板
robotgo.MilliSleep(50)
return robotgo.WriteAll(backup)
}
这样用户在脚本运行前复制的内容不会被你的脚本“吃掉”。
9.5 实战示例:文本扩展工具
把剪贴板与输入结合,可以做一个简单的“文本扩展”小工具:输入一个缩写,自动替换为预设的长文本。下面演示核心逻辑(热键触发部分见第 11 章):
package main
import (
"github.com/go-vgo/robotgo"
)
var snippets = map[string]string{
"/addr": "北京市海淀区中关村大街 1 号",
"/email": "example@example.com",
"/sign": "此致\n敬礼\n张三",
}
func expand(key string) {
text, ok := snippets[key]
if !ok {
return
}
// 删除已输入的缩写(按退格 len(key) 次)
for range key {
robotgo.KeyTap("backspace")
}
// 通过剪贴板粘贴展开后的文本
robotgo.WriteAll(text)
robotgo.MilliSleep(50)
robotgo.KeyTap("v", "ctrl")
}
9.6 平台依赖与注意事项
9.6.1 Linux 需要 xsel / xclip
在 Linux(X11)上,RobotGo 的剪贴板功能依赖外部命令 xsel 或 xclip。如果未安装,WriteAll / ReadAll 会返回错误。安装方式:
# Ubuntu / Debian
sudo apt install xsel xclip
# Fedora
sudo dnf install xsel xclip
9.6.2 跨平台粘贴键
粘贴快捷键在不同系统不同:
import "runtime"
func pasteKey() string {
if runtime.GOOS == "darwin" {
return "cmd"
}
return "ctrl"
}
// 使用
robotgo.KeyTap("v", pasteKey())
9.6.3 时序问题
剪贴板的写入、系统粘贴、应用读取之间存在异步性。在 WriteAll 之后、KeyTap("v", ...) 之前,以及 KeyTap("c", ...) 之后、ReadAll 之前,加入适当的 MilliSleep(通常 50~150ms)能显著提升稳定性,避免“粘贴出旧内容”或“读到空值”。
9.6.4 仅支持文本
RobotGo 主库的 WriteAll / ReadAll 面向纯文本。如果需要处理图片、富文本等其他剪贴板格式,需要借助平台特定的方案或其他库,这超出了 RobotGo 主库的范围。
9.7 实战技巧小结
- 长文本走粘贴:大段文本一律用
WriteAll+ 粘贴,不要用Type逐字打。 - 读不到就复制:读不到控件文本时,用“全选 + 复制 + ReadAll”的组合。
- 善待用户剪贴板:需要时备份并恢复用户原有的剪贴板内容。
- 加延时:剪贴板相关操作前后加
MilliSleep保证时序稳定。 - 检查错误:始终检查
WriteAll/ReadAll返回的error,尤其在 Linux 上。 - 装好依赖:Linux 上务必安装
xsel/xclip。
9.8 小结
本章我们学习了 RobotGo 的剪贴板操作:用 WriteAll / ReadAll 读写文本,并掌握了三种高级用法——用剪贴板快速输入大段文本、用剪贴板读取界面内容、备份与恢复用户剪贴板。我们还做了一个文本扩展小工具的示例,并讨论了 Linux 依赖、跨平台粘贴键、时序问题等注意事项。下一章我们将进入进程与窗口管理,让自动化程序能够定位、激活和操作特定的应用程序窗口。