Windows GUI 自动化(纯 ctypes)

SKILL运维和基础设施
运维和基础设施 未标注权限 许可证不明确
安装这个技能

纯用 Python ctypes 操作 Windows 图形界面,零第三方自动化依赖。覆盖 DPI 感知设置、鼠标点击/拖拽/双击、键盘输入与快捷键、剪贴板写入(中文与长路径的唯一稳法)、窗口枚举与定位、全屏截图回读判断,以及自绘 UI(NanoVG/Nuklear/SDL/ImGui)的坐标点击配方。含六个必踩的坑:DPI 缩放导致点偏、首次点击只激活窗口、剪贴板 argtypes 未设导致 access violation、系统对话框拒收正斜杠、误点悬浮图标、忘记还原鼠标位置。适用于:安装向导、系统文件对话框、托盘/圆盘菜单、桌面宠物换模型等只有 GUI 入口的操作。

一句话选型结论

按资料字段整理

Windows GUI 自动化(纯 ctypes)是运维和基础设施类的 Agent Skill,安装方式未标注,权限级别未标注,许可证不明确,有可直接复制的安装命令。技能本质是给模型读的说明书,效果取决于模型与客户端;装完先用一个小任务验证,再放进正式流程。

分类运维和基础设施 安装方式未标注 权限级别未标注权限 许可证许可证不明确
累计安装 未标注 本周 未标注
GitHub 星标 未标注 仓库 未标注
下载量 未标注 技能市场下载数
权限级别 未标注权限 安装前请确认风险范围
许可证 许可证不明确 未说明

安装

未标注
在支持 Skills 的客户端里执行,装完问一句「你有哪些技能」验证
skillhub install user_3d005bdf/windows-gui-automation-ctypes
  1. 1
    确认客户端支持

    确认你的客户端支持 Skills(Claude、Codex、Cursor 等),并升级到较新的版本。

  2. 2
    拿到技能文件

    执行上面的命令安装;也可以把仓库里的 SKILL.md 手动放进客户端的 skills 目录。

  3. 3
    刷新技能列表

    重新打开客户端,或刷新技能列表,让新放进来的技能被加载。

  4. 4
    验证是否生效

    问一句「你有哪些技能」,确认列表里出现它,再拿一个小任务试跑。

技能档案

运维和基础设施
字段来自技能仓库与公开索引,中文说明由本站标注
作者 / 维护方user_3d005bdf仓库 未标注 · 版本 未标注
宿主客户端未标注技能可被这些客户端加载
安装方式未标注安装包 community
权限级别未标注权限安装前请确认风险范围
许可证未说明许可证不明确,商用前请自行确认条款
仓库可用性available技能仓库当前是否可访问
最近核验未标注上游最后核验时间 · 数据更新 1791683881
正文体量9.3 KBSKILL.md 原文大小,越大说明说明书写得越细

典型使用场景

3 类
按分类整理的常见用法,具体以 SKILL.md 为准
查服务与日志

按现象定位服务状态与日志线索。

写部署与巡检脚本

把重复的部署、巡检写成脚本。

故障排查

按步骤排查网络、依赖与配置。

选择建议

装之前先看这几条
按条目字段给出的判断,不替你决定用不用

值得选的地方

  • 有可直接复制的安装命令,不用自己翻文档找入口。

先想清楚的地方

  • 没有标注权限级别,实际能做什么要装好后确认。
  • 许可证不明确,商用或二次分发前先到仓库确认条款。
  • 没有做站内核验,内容以作者仓库为准。
  • 技能只是说明书,实际效果取决于模型与客户端,装完先用小任务试一遍。

更适合

  • 需要在运维和基础设施场景里给模型补一套做法的人。
  • 愿意先读一遍 SKILL.md、确认它会让模型做什么的人。

不太适合

  • 对许可证要求很严、必须明确可商用的人。
  • 只想装完就自动变强、不打算看说明书的人。

同类对比

6 个同类
同分类里挑最接近的几条,字段以各自详情页为准
技能权限级别安装方式累计安装宿主客户端安装命令
Windows GUI 自动化(纯 ctypes)当前 未标注权限 未标注 未标注 未标注 有
Azure 部署 调用外部服务 GitHub 仓库 664.2 万 Codex、Claude、Cursor 有
Azure diagnostics 问题管理 调用外部服务 GitHub 仓库 657.6 万 Codex、Claude、Cursor 有
Azure aigateway 部署 调用外部服务 GitHub 仓库 655.3 万 Codex、Claude、Cursor 有
Azure AI 搜索 调用外部服务 GitHub 仓库 651.4 万 Codex、Claude、Cursor 有
Azure Cloud migrate 部署 调用外部服务 GitHub 仓库 650.7 万 Codex、Claude、Cursor 有

SKILL.md 全文

9.3 KB
模型实际读到的说明书原文,来自技能仓库

Windows GUI 自动化 · 纯 ctypes 方案

核心结论:不依赖任何第三方自动化库,只用 ctypes + PIL 即可完整驱动 Windows GUI。
截图回读靠多模态看图能力闭环验证。


0. 什么时候用 / 不用

用:
- 目标软件只有 GUI 入口(安装向导、文件对话框、托盘/圆盘菜单、自绘 UI)。
- 已实测排除命令行:传参数、拖放关联、直接改配置目录,都无效。
- 需要"帮着点三下"类的小操作。

不用:
- 有 CLI / API / 配置文件可直接达成 → 优先走那些(更快更稳)。
- 网页类任务 → 用浏览器自动化或直接抓取。

动手前先穷尽非 GUI 路径,GUI 模拟永远是最后手段(脆、慢、会占用户鼠标)。


1. 起手式:必须设 DPI 感知

不设必错位。 高 DPI 机器上 GetSystemMetrics 返回逻辑像素(如 1536×1080),
而 SetCursorPos/窗口矩形用物理像素(1920×1080),差 1.25 倍 → 点偏。

import ctypes
u32 = ctypes.windll.user32
try:    ctypes.windll.shcore.SetProcessDpiAwareness(2)   # PER_MONITOR_AWARE_V2,首选
except Exception: u32.SetProcessDPIAware()               # 兜底
print(u32.GetSystemMetrics(0), u32.GetSystemMetrics(1))  # 应与物理分辨率一致

2. 基本动作

import time
def click(x, y, button='left', pause=0.30):
    u32.SetCursorPos(x, y); time.sleep(pause)
    down, up = (0x0002, 0x0004) if button == 'left' else (0x0008, 0x0010)
    u32.mouse_event(down, 0, 0, 0, 0); time.sleep(0.07)
    u32.mouse_event(up,   0, 0, 0, 0)

def key(vk, mods=()):                     # vk 用虚拟键码
    for m in mods: u32.keybd_event(m, 0, 0, 0)
    u32.keybd_event(vk, 0, 0, 0); u32.keybd_event(vk, 0, 0x0002, 0)
    for m in reversed(mods): u32.keybd_event(m, 0, 0x0002, 0)

CTRL, ALT, SHIFT = 0x11, 0x12, 0x10
VK_A, VK_C, VK_V, VK_H, VK_RETURN, VK_ESCAPE = 0x41, 0x43, 0x56, 0x48, 0x0D, 0x1B
  • 拖拽 = SetCursorPos 起点 → LEFTDOWN → 若干次 SetCursorPos 中间点(每步 sleep 20~40ms)→ LEFTUP。
  • 双击 = 两次 click,间隔 150~250ms(太慢变两次单击)。
  • 右键菜单:click(x, y, 'right')。

3. 找窗口

from ctypes import wintypes
def find_windows(pred):
    out = []
    CB = ctypes.WINFUNCTYPE(ctypes.c_bool, wintypes.HWND, wintypes.LPARAM)
    @CB
    def cb(h, l):
        cls = ctypes.create_unicode_buffer(256); u32.GetClassNameW(h, cls, 256)
        n = u32.GetWindowTextLengthW(h)
        b = ctypes.create_unicode_buffer(n + 1); u32.GetWindowTextW(h, b, n + 1)
        r = wintypes.RECT(); u32.GetWindowRect(h, ctypes.byref(r))
        if pred(cls.value, b.value, h):
            out.append((h, cls.value, b.value, (r.left, r.top, r.right, r.bottom)))
        return True
    u32.EnumWindows(cb, 0)
    return out

常用 class 名参照:
| class | 是什么 |
|---|---|
| #32770 | 系统对话框(文件/文件夹选择、消息框、UAC) |
| SDL_app | SDL 窗口(大量桌面应用/游戏/自绘 UI) |
| Chrome_WidgetWin_1 | Chromium 系(Electron/Edge/Chrome) |
| CabinetWClass | 资源管理器 |
| Shell_TrayWnd | 任务栏 |
| tooltips_class32 / SysShadow | 悬停提示、阴影(忽略掉) |

判位置用 GetWindowRect 取绝对屏幕坐标,点击坐标 = 窗口左上 + 相对偏移。
相对偏移从截图量出来最可靠(见 §5)。


4. 剪贴板:输入中文/长路径的唯一稳法

keybd_event 只能打 ASCII 且受输入法干扰。中文、长路径、"含空格的路径"一律走剪贴板。

k32 = ctypes.windll.kernel32
k32.GlobalAlloc.restype  = ctypes.c_void_p
k32.GlobalAlloc.argtypes = [ctypes.c_uint, ctypes.c_size_t]
k32.GlobalLock.restype   = ctypes.c_void_p
k32.GlobalLock.argtypes  = [ctypes.c_void_p]
k32.GlobalUnlock.argtypes= [ctypes.c_void_p]
u32.SetClipboardData.restype  = ctypes.c_void_p
u32.SetClipboardData.argtypes = [ctypes.c_uint, ctypes.c_void_p]

def set_clipboard(text):
    u32.OpenClipboard(None); u32.EmptyClipboard()
    data = text.encode('utf-16le') + b'\x00\x00'
    h = k32.GlobalAlloc(0x0002, len(data))          # GMEM_MOVEABLE
    p = k32.GlobalLock(h); ctypes.memmove(p, data, len(data)); k32.GlobalUnlock(h)
    u32.SetClipboardData(13, h); u32.CloseClipboard()   # CF_UNICODETEXT

> ⚠️ 不设 argtypes/restype 会 OSError: access violation writing 0x0 ——
> 64 位下句柄被截断成 32 位。这是本方案最容易踩的一脚。

然后 set_clipboard(path) → 点击输入框 → key(VK_A, [CTRL]) → key(VK_V, [CTRL])。


5. 验证闭环(本方案的精髓)

不要盲点。每次点击前后都截图看。

from PIL import ImageGrab
def shot(path, box=None):
    im = ImageGrab.grab(all_screens=True)      # 多显示器需要 all_screens
    if box: im = im.crop(box)                  # 只留关心的区域,读图更清楚
    im.save(path); return path

流程:截图 → 看图 → 判断元素位置 → 点击 → 再截图确认。
- 全屏图 1920×1080 直接看会糊,务必 crop 到目标窗口范围再读。
- 长图(教程 PNG 之类)按高度切 6~8 段 + 放大 1.6 倍再读。
- 图片坐标 = 物理像素坐标,与 SetCursorPos 同一坐标系 → 看图就能换算点击点。


6. 六个必踩的坑

  1. 首次点击只用于激活窗口,不会被控件接收 → 目标窗口非前台时连点两次,或先 SetForegroundWindow(hwnd) 再 sleep 0.6s。
  2. DPI 未设 → 整体点偏 1.25 倍(见 §1)。
  3. 剪贴板 argtypes 未设 → access violation(见 §4)。
  4. 路径分隔符:系统"选择文件夹"框拒收正斜杠,D:/a/b 报「文件夹名无效」,必须 D:\a\b。
  5. 别点在图标/按钮上:列表卡片常带悬浮小图标(表情/文件夹/删除),点卡片空白或大图区域。
  6. 恢复鼠标:开始前 GetCursorPos 存原位置,结束后 SetCursorPos 还回去,少打扰用户。

另:动用户鼠标前先告知(它会自己动,用户会以为闹鬼)。


7. 实战配方:自绘 UI(圆盘/环形菜单)

NanoVG/Nuklear/SDL 这类自绘菜单不是 Win32 控件,拿不到句柄,只能按坐标点。
- 先右键触发根窗口,枚举窗口看是否多出一个 SDL_app 的菜单窗口。
- 环形菜单:从截图量出圆心 (cx, cy) 与外圈半径 R,第 k 个扇区(12 等分,从正上顺时针)
的角度 θ = -90° + k*30°,点 (cx + R*cosθ*0.75, cy + R*sinθ*0.75)。
- 先点最安全的项试水(如"设置"),确认坐标系没跑偏,再点目标项。
- 图标语义靠看截图认(齿轮=设置、水滴=透明度、跑步=动作…),别猜。

系统对话框(#32770)是另一回事——那是真 Win32 控件,可靠得多:
优先利用它的「文件夹:」/「文件名:」输入框 + 确定按钮,比在自绘 UI 上点坐标稳 10 倍。


8. 参考流程:带 GUI 导入功能的软件(典型链路)

许多桌面软件的"导入素材"只有 GUI 入口,标准链路如下:

右键程序主体               → 弹出圆盘/环形菜单(自绘窗口,class 常为 SDL_app)
点菜单里的齿轮/设置项       → 打开设置窗口
点左栏的目标分类           → 切换到对应面板
点虚线框「点击或拖入文件夹」 → 弹出系统对话框 #32770「选择文件夹」
点「文件夹:」框 → Ctrl+A → Ctrl+V → 粘入绝对路径(反斜杠!)
点「选择文件夹」           → 导入完成,素材目录下出现规范化包
点新素材卡片               → 切换生效
  • 全程纯 ctypes,无第三方依赖。
  • 关键判据全部落在文件系统证据上(素材目录变化、状态文件),不靠"看起来成功了"。

9. 做完必查(不要只看截图)

截图是"当时的画面",持久化状态要去文件里核:
配置文件 / 注册表 / 安装目录 / 进程列表。
例:切换素材后要确认该软件的状态文件里对应字段已变——这才证明重启后仍生效。

常见问题

5 问
答案由本站依据条目字段整理
Windows GUI 自动化(纯 ctypes)怎么安装?

在支持 Skills 的客户端里执行:skillhub install user_3d005bdf/windows-gui-automation-ctypes。安装方式为未标注。装完刷新技能列表或重开客户端。

Windows GUI 自动化(纯 ctypes)支持哪些客户端?

资料没有标注宿主客户端,但只要客户端支持 Skills(Claude、Codex、Cursor 等),一般都能加载。

Windows GUI 自动化(纯 ctypes)权限高吗,安全吗?

权限级别为未标注权限。安装前先看它会读取或写入哪些内容。

Windows GUI 自动化(纯 ctypes)收费吗?

本站不代收费用,也没有标注具体价格。是否收费取决于技能本身和所用的模型或客户端,正式使用前按作者说明确认。

Windows GUI 自动化(纯 ctypes)用什么许可证?

许可证标注为 未说明(许可证不明确)。商用或二次分发前请到仓库确认条款原文。

热门专题

按场景挑技能
全部专题 →

技能内容以作者仓库为准;分类、权限级别与许可证状态的中文说明为中文整理,最近核验 未标注。