第10章 - 进程与窗口管理
真实的自动化往往需要面向“某个具体的应用程序”:找到它的进程、激活它的窗口、向它发送输入、读取它的标题,甚至在必要时结束它。RobotGo 提供了一组进程与窗口管理函数来满足这些需求。本章系统讲解进程查找、窗口激活、定向输入、窗口信息读取与系统对话框。
10.1 进程查找
10.1.1 按名称查找进程 ID:FindIds
FindIds 根据进程名(支持部分匹配)查找所有匹配的进程 PID:
fpid, err := robotgo.FindIds("Google")
if err == nil {
fmt.Println("找到的 PID 列表:", fpid)
}
返回的是一个 PID 切片,因为同名进程可能有多个(例如浏览器的多个进程)。
10.1.2 获取所有进程:Process
Process 返回系统当前所有进程的信息列表(包含 PID 与名称等),可用于自行遍历筛选:
ps, err := robotgo.Process()
if err == nil {
for _, p := range ps {
fmt.Println(p.Pid, p.Name)
}
}
10.1.3 判断进程是否存在:PidExists
exists, err := robotgo.PidExists(1234)
if err == nil && exists {
fmt.Println("进程 1234 存在")
}
10.1.4 获取进程名:FindName / FindNames
name, err := robotgo.FindName(1234)
if err == nil {
fmt.Println("PID 1234 的进程名:", name)
}
names, err := robotgo.FindNames()
if err == nil {
fmt.Println("所有进程名:", names)
}
10.2 窗口激活
找到目标进程后,常常需要把它的窗口切换到前台(激活),以便后续输入。
10.2.1 按 PID 激活:ActivePid
fpid, err := robotgo.FindIds("Google")
if err == nil && len(fpid) > 0 {
robotgo.ActivePid(fpid[0]) // 激活第一个匹配进程的窗口
}
10.2.2 按名称激活:ActiveName
ActiveName 是更便捷的一步到位写法,内部会先按名称找进程再激活:
robotgo.ActiveName("chrome")
激活窗口后,后续的 Type / KeyTap / Click 等操作就会作用于该窗口(因为它现在是前台焦点窗口)。
10.3 向特定窗口/进程发送输入
RobotGo 的一些输入函数支持额外的 PID 参数,可以把输入定向发送给指定进程的窗口,而不依赖“当前焦点”。这在后台操作、并发控制多个窗口时很有用:
fpid, err := robotgo.FindIds("Google")
if err == nil && len(fpid) > 0 {
pid := fpid[0]
// 向指定进程输入文本
robotgo.Type("Hi galaxy!", pid)
// 向指定进程发送组合键(Cmd + A)
robotgo.KeyTap("a", pid, "cmd")
// 向指定进程切换按键状态
robotgo.KeyToggle("a", pid)
robotgo.KeyToggle("a", pid, "up")
}
注意这些“带 PID 的输入”在不同平台上的支持程度和行为可能有所不同,建议在目标平台实测。对于大多数场景,更稳妥的做法仍然是“先 ActivePid 激活窗口,再做普通输入”。
10.4 窗口信息读取
10.4.1 获取窗口标题:GetTitle
title := robotgo.GetTitle()
fmt.Println("当前活动窗口标题:", title)
GetTitle 默认返回当前活动窗口的标题,也可以传入 PID 获取指定进程窗口的标题。
10.4.2 获取窗口位置与尺寸
RobotGo 提供了获取活动窗口边界的函数,例如 GetBounds,可用于读取窗口的位置与大小(具体可用函数以你所用的 RobotGo 版本为准):
x, y, w, h := robotgo.GetBounds(pid)
fmt.Printf("窗口位置(%d,%d) 尺寸 %dx%d\n", x, y, w, h)
结合窗口边界,可以把“相对窗口的坐标”换算为“屏幕绝对坐标”,让点击操作不依赖窗口在屏幕上的具体位置。
10.5 结束进程:Kill
Kill 用于结束指定 PID 的进程:
exists, err := robotgo.PidExists(100)
if err == nil && exists {
robotgo.Kill(100)
fmt.Println("已结束进程 100")
}
谨慎使用:
Kill会强制结束进程,可能导致目标程序未保存的数据丢失。在自动化脚本中调用前,请确认 PID 正确、确实需要结束该进程。
10.6 系统对话框:Alert
虽然不属于“窗口管理”,但 Alert 能弹出原生系统对话框,常用于脚本与用户的简单交互或调试提示:
ok := robotgo.Alert("标题", "提示内容")
if ok {
fmt.Println("用户点击了确定")
} else {
fmt.Println("用户点击了取消")
}
Alert 返回布尔值表示用户点了确定还是取消,可据此控制脚本流程。
10.7 完整示例
下面是官方窗口示例的整理版,串联了进程查找、定向输入、激活、判断存在、结束进程、弹框与读取标题:
package main
import (
"fmt"
"github.com/go-vgo/robotgo"
)
func main() {
fpid, err := robotgo.FindIds("Google")
if err == nil {
fmt.Println("pids:", fpid)
if len(fpid) > 0 {
pid := fpid[0]
// 向指定进程发送输入
robotgo.Type("Hi galaxy!", pid)
robotgo.KeyTap("a", pid, "cmd")
robotgo.KeyToggle("a", pid)
robotgo.KeyToggle("a", pid, "up")
// 激活窗口
robotgo.ActivePid(pid)
// 结束进程(演示,谨慎使用)
robotgo.Kill(pid)
}
}
// 按名称激活
robotgo.ActiveName("chrome")
// 判断进程是否存在
isExist, err := robotgo.PidExists(100)
if err == nil && isExist {
fmt.Println("pid 存在:", isExist)
robotgo.Kill(100)
}
// 弹出对话框
abool := robotgo.Alert("test", "robotgo")
if abool {
fmt.Println("ok")
}
// 读取窗口标题
title := robotgo.GetTitle()
fmt.Println("title:", title)
}
10.8 实战工作流:定位并操作目标应用
把本章能力串成一个典型工作流:
func operateApp(appName string) error {
// 1. 查找进程
pids, err := robotgo.FindIds(appName)
if err != nil || len(pids) == 0 {
return fmt.Errorf("未找到应用: %s", appName)
}
// 2. 激活窗口
robotgo.ActivePid(pids[0])
robotgo.MilliSleep(300) // 等待窗口切到前台
// 3. 确认标题
fmt.Println("当前窗口:", robotgo.GetTitle())
// 4. 执行操作
robotgo.KeyTap("l", "ctrl") // 例如浏览器定位地址栏
robotgo.Type("https://github.com/go-vgo/robotgo")
robotgo.KeyTap("enter")
return nil
}
10.9 实战技巧与注意事项
- 优先“激活 + 普通输入”:相比带 PID 的定向输入,先
ActivePid再做普通操作通常更稳定、跨平台兼容性更好。 - 激活后留延时:窗口从后台切到前台需要时间,
ActivePid后加MilliSleep再操作。 - 同名进程要甄别:
FindIds可能返回多个 PID,必要时结合GetTitle、进程信息进一步确认哪个才是目标窗口。 - Kill 要谨慎:强制结束进程有数据丢失风险,务必确认 PID。
- 平台差异:进程与窗口相关 API 在 Windows / macOS / Linux 上的行为可能存在差异,关键逻辑请在目标平台实测验证。
10.10 小结
本章我们掌握了 RobotGo 的进程与窗口管理:用 FindIds / Process / PidExists / FindName 查找进程,用 ActivePid / ActiveName 激活窗口,向指定进程定向发送输入,用 GetTitle / GetBounds 读取窗口信息,用 Kill 结束进程,以及用 Alert 弹出系统对话框。我们还梳理了“定位并操作目标应用”的实战工作流。下一章将进入一个全新维度——全局事件监听,让程序能够“感知”用户的键盘鼠标动作。