惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Register - Security
The Register - Security
IT之家
IT之家
阮一峰的网络日志
阮一峰的网络日志
博客园 - 叶小钗
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
S
SegmentFault 最新的问题
有赞技术团队
有赞技术团队
博客园 - 【当耐特】
The Cloudflare Blog
T
The Blog of Author Tim Ferriss
Apple Machine Learning Research
Apple Machine Learning Research
C
Check Point Blog
Microsoft Azure Blog
Microsoft Azure Blog
V
V2EX
量子位
F
Fortinet All Blogs
Martin Fowler
Martin Fowler
大猫的无限游戏
大猫的无限游戏
Last Week in AI
Last Week in AI
博客园 - 聂微东
美团技术团队
Stack Overflow Blog
Stack Overflow Blog
Google DeepMind News
Google DeepMind News
宝玉的分享
宝玉的分享
M
MIT News - Artificial intelligence
U
Unit 42
罗磊的独立博客
MyScale Blog
MyScale Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
V
Visual Studio Blog
Jina AI
Jina AI
Recorded Future
Recorded Future
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
小众软件
小众软件
H
Help Net Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
MongoDB | Blog
MongoDB | Blog
N
Netflix TechBlog - Medium
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
B
Blog
J
Java Code Geeks
爱范儿
爱范儿
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
aimingoo的专栏
aimingoo的专栏
B
Blog RSS Feed
月光博客
月光博客
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Privacy International News Feed
Know Your Adversary
Know Your Adversary
雷峰网
雷峰网

博客园 - 我才是银古

第16章:常见问题、排错与最佳实践 第15章:扩展生态、MCAD 与外部集成 第12章:实战案例:机械结构与 3D 打印零件 第14章:构建、测试、调试与贡献流程 第13章:OpenSCAD 源码架构与核心执行流程 第11章:预览、渲染、网格精度与性能优化 第09章:列表推导、递归与算法建模 第08章:参数化零件库与复用设计 第10章:导入导出、命令行与自动化 第06章:CSG 布尔建模方法 第07章:二维图形、拉伸、旋转与投影 第05章:基础几何、坐标系与变换 第04章:参数、变量、函数、模块与作用域 OpenSCAD 教程目录 第03章:OpenSCAD 语言基础 第02章:安装、环境配置与开发工作流 第01章:OpenSCAD 项目全景与学习路线 第02章:源码获取、编译与开发环境配置 第01章:OCCT项目全景与学习路线 第18章:二次开发实战与综合案例 第18章:综合实战案例 第17章:数据交换与协同 第16章:源码架构与二次开发 第15章:插件与自定义工作台开发 第14章:Python脚本宏与自动化 第13章:FEM仿真分析 第12章:CAM数控加工 第11章:SurfaceMesh与逆向工程 第10章:Draft二维绘图与BIM建筑 第09章:工程图TechDraw 第07章:参数化表达式与Spreadsheet 第08章:装配设计Assembly 第06章:Part工作台与几何内核 第05章:PartDesign实体特征建模 第04章:草图Sketcher约束建模 第02章:安装版本与工作环境配置 第03章:界面工作台与基础操作 第01章:项目全景与学习路线 第十二章:插件开发、研究功能与最佳实践 第十章:定时任务与自动化(Cron) 第七章:技能、记忆与自学习闭环 第八章:MCP 集成与上下文文件 第六章:工具系统与终端后端 第五章:模型供应商与配置体系 Hermes Agent 教程目录 第十一章:语音、视觉、浏览器与子代理协作 第四章:CLI/TUI 与会话管理 第十二章:学习路线、实战方案与最佳实践 第十一章:源码结构、开发调试与插件开发 第十章:自动化、远程访问、日志与排障 第九章:Control UI、节点、Canvas 与语音能力 第七章:工具、技能、插件与能力扩展 第八章:安全模型、访问控制与沙箱实践 第六章:Agent 工作区、会话与多智能体路由 第五章:多通道消息接入与聊天平台配置 第四章:配置体系、模型接入与认证管理 第三章:Gateway 架构、协议与运行机制 第二章:安装、环境准备与快速上手 第一章:OpenClaw 项目概览与核心定位 oh-my-openagent 教程目录 09-命令模型回退与配置参考 10-实战案例最佳实践与故障排除 05-工作模式-Ultrawork-Prometheus-Atlas 08-Hooks与MCP系统 06-Category与Skill系统 07-核心工具链 04-智能体全景详解 03-安装与环境配置 02-整体架构与多模型编排机制 01-项目简介与核心理念 01-项目概览与学习路线 02-安装部署与工具适配 03-Skill机制与using-superpowers 05-TDD系统化调试与完成前验证 04-需求澄清方案设计与计划编写 07-并行智能体子智能体与Git-Worktree 第六章:代码审查、反馈处理与分支收尾 08-中国特色Skills与本土团队落地 09-MCP构建工作流执行与自定义Skill 第23章:FreeCAD-Python-API Clipper2 C# 源码解读教程 第19章:PolyTree 多边形树结构 第20章:实际应用与最佳实践 第18章:Minkowski 和与差 第17章:RectClip 矩形裁剪优化 第16章:ClipperOffset 偏移类详解 第15章:填充规则详解 第14章:布尔运算执行流程 第13章:ClipperD 浮点裁剪类 第11章:OutRec 与 OutPt 输出结构 第9章:Active 活动边结构 第10章:Vertex 顶点与 LocalMinima 局部极小值 第12章:Clipper64 裁剪类详解 第7章:高精度运算与128位整数 第8章:ClipperBase 基类详解 第5章:枚举类型与常量定义 第6章:InternalClipper 内部工具类 第2章:核心数据结构 - Point64、PointD 第3章:路径与多边形表示 - Path64、PathD、Paths64、PathsD 第4章:矩形边界 - Rect64、RectD
第09章 - 剪贴板操作
我才是银古 · 2026-06-24 · via 博客园 - 我才是银古

第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 的剪贴板功能依赖外部命令 xselxclip。如果未安装,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 实战技巧小结

  1. 长文本走粘贴:大段文本一律用 WriteAll + 粘贴,不要用 Type 逐字打。
  2. 读不到就复制:读不到控件文本时,用“全选 + 复制 + ReadAll”的组合。
  3. 善待用户剪贴板:需要时备份并恢复用户原有的剪贴板内容。
  4. 加延时:剪贴板相关操作前后加 MilliSleep 保证时序稳定。
  5. 检查错误:始终检查 WriteAll / ReadAll 返回的 error,尤其在 Linux 上。
  6. 装好依赖:Linux 上务必安装 xsel / xclip

9.8 小结

本章我们学习了 RobotGo 的剪贴板操作:用 WriteAll / ReadAll 读写文本,并掌握了三种高级用法——用剪贴板快速输入大段文本、用剪贴板读取界面内容、备份与恢复用户剪贴板。我们还做了一个文本扩展小工具的示例,并讨论了 Linux 依赖、跨平台粘贴键、时序问题等注意事项。下一章我们将进入进程与窗口管理,让自动化程序能够定位、激活和操作特定的应用程序窗口。