自动化脚本在自己电脑上跑得好好的,一装到客户机器上就各种失灵 —— 这种情况我遇到过太多次。排查下来,绝大多数问题不在代码,而在系统环境。
下面按类别整理需要在 Windows 上做的设置。每一项都标注了优先级:必做的是几乎所有自动化工具都要配的,按需的则取决于你的实现方式和目标程序。
一、权限类(必做)
1. UAC 与权限对等
问题:如果被自动化的程序(比如直播伴侣)是以管理员权限运行的,而你的脚本不是,Windows 的 UIPI 机制会阻止脚本向高权限窗口发送消息、读取控件信息。表现是「明明窗口在那儿,脚本却找不到」或「控件识别结果为空」。
怎么解决:
- 推荐做法:让脚本和目标准备相同的权限级别。目标程序用管理员运行,脚本也用管理员运行。
- 另一种做法是把 UAC 滑块调到默认档或更低(控制面板 → 用户账户 → 更改用户账户控制设置),减少权限不一致的情况。
注意:直接把 UAC 关掉能解决很多识别问题,但会让整台机器的安全性下降。交付给客户的工具,建议用「权限对等」而不是「关掉 UAC」。
2. 以管理员身份运行
如果脚本确实需要管理员权限,又不想每次手动右键:
- 右键快捷方式 → 属性 → 快捷方式 选项卡 → 高级 → 勾选以管理员身份运行
- 如果是打包成 exe,可以在打包时写入请求的管理员权限清单
二、显示与坐标类(必做)
3. 屏幕缩放必须是 100%
问题:这是坐标类自动化最高频的坑。系统缩放设为 125% / 150% 时,逻辑坐标和物理像素之间会有比例换算,用屏幕坐标点击(pyautogui、图像识别)会出现固定比例的偏移 —— 看起来「总是差那么一点」。
怎么解决:
- 把显示缩放设为 100%(桌面右键 → 显示设置 → 缩放与布局)
- 更好的做法是在程序里声明 DPI 感知,让系统不要给窗口做缩放换算,而不是要求用户改系统设置
4. 多显示器与虚拟坐标
问题:多显示器环境下,各屏幕的坐标是拼在一起的一大块虚拟桌面,副屏在主屏左边时会出现负坐标。写死 (0, 0) 之类的坐标在多屏机器上必然出错。
怎么解决:不要假设主屏在原点,用系统 API 查询实际显示器布局后再计算坐标。
5. 窗口大小与位置
问题:基于坐标点击的方案,窗口位置一变,所有坐标全部失效。
怎么解决:脚本启动时先把目标窗口恢复并移动到固定位置、固定尺寸,再去计算控件坐标。基于 UIA 的方案对位置不敏感,能规避这个问题 —— 这也是我更推荐 UIA 的原因之一。
三、运行稳定性(必做)
6. 关掉屏保与睡眠
问题:屏保启动或系统进入睡眠会直接中断任务;即使没睡眠,屏幕关闭也可能让某些基于渲染帧的界面停止刷新(Chromium 内核的客户端尤其明显),导致自动化工具读取控件时一直等待。
怎么解决:控制面板 → 电源选项 → 更改计划设置,把「关闭显示器」和「使计算机进入睡眠状态」都设为从不;屏幕保护程序设为无。同时对长时间跑任务的机器,把电源计划设为高性能,避免 CPU 降频导致界面响应变慢。
四、依赖与环境(必做)
7. Visual C++ 运行库
问题:不少工具和客户端依赖 VC++ Redistributable,缺失时会直接报「找不到 xxx.dll」或程序静默退出。
怎么解决:到 微软官网 下载安装最新版(x86 与 x64 都要装,很多程序是 32 位的)。
8. DirectX 与图形组件
问题:这是最容易被忽略、也最难排查的一类。新装系统如果缺少 DirectX 相关组件,Chromium 内核的客户端界面能显示,但不再产生新的渲染帧,无障碍树(UIA)也就停止刷新,自动化工具读取控件时会挂起 —— 表现为「任务卡住不动,也不报错,用鼠标碰一下窗口就继续了」。
怎么解决:用 DirectX 修复工具(DirectX Repair)检测并补齐组件,然后重启。这个案例我单独写过一篇:定时软件一直显示正在开播中,却不点击按钮,怎么办?
五、安全软件(按需)
9. 防火墙与杀毒软件
问题:自动化工具因为会模拟输入、操作其他进程的内存,很容易被杀软误判。常见表现是程序被静默拦截、或者运行到一半被终止。
怎么解决:优先加白名单,而不是直接关闭安全软件。把程序目录和 exe 加入杀软排除项;防火墙同理,把需要联网的功能放行即可。只有在排查阶段才临时关闭,定位完立刻恢复。
六、脚本与调试(开发侧)
10. PowerShell 执行策略
问题:如果脚本是通过 PowerShell 跑的,默认执行策略可能直接拒绝运行。
怎么解决:以管理员身份运行 PowerShell,执行:
Set-ExecutionPolicy RemoteSigned
11. 选对 pywinauto 的后端
问题:pywinauto 支持两套后端,选错会识别不到控件。
怎么解决:现代应用(尤其 Chromium 内核的客户端)用 uia 后端;老式 Win32 程序用 win32 后端。显式指定比依赖默认值可靠:
from pywinauto import Application
app = Application(backend="uia").connect(title="窗口标题")
12. 日志一定要加
问题:脚本在某些电脑上失败但没有任何提示,是最难处理的情况 —— 你无法远程看着用户的屏幕。
怎么解决:从第一版就把关键步骤写进日志,记录每一步的状态、耗时和异常。客户出问题时让他把日志发过来,定位效率会完全不同。
import logging
logging.basicConfig(filename='automation.log', level=logging.DEBUG,
format='%(asctime)s %(levelname)s %(message)s')
logging.debug('开始执行脚本')
优先级速查
| 类别 | 项目 | 优先级 |
|---|---|---|
| 权限 | 权限对等 / 管理员运行 | 必做 |
| 显示 | 缩放 100% / 多屏坐标 / 窗口位置 | 必做(坐标方案) |
| 稳定性 | 关闭屏保与睡眠 / 高性能电源 | 必做 |
| 环境 | VC++ 运行库 / DirectX 组件 | 必做 |
| 安全 | 杀软与防火墙白名单 | 按需 |
| 调试 | 执行策略 / 后端选择 / 日志 | 开发阶段就要做 |
小结
做 Windows 自动化,代码只占一半,另一半是环境。「在我电脑上没问题」是最没意义的结论 —— 交付类工具在设计阶段就应该把这些环境差异考虑进去:能用 UIA 就不用坐标,能声明 DPI 感知就不要让用户改设置,能从第一版就带日志就不要等到出问题再加。
如果问题仍然存在,可以根据具体报错进一步排查;也欢迎随时与我们交流。