如何使用Python自动控制windows桌面


Posted in Python onJuly 11, 2019

前言

在使用PC时与PC交互的主要途径是看屏幕显示、听声音,点击鼠标和敲键盘等等。在自动化办公的趋势下,繁琐的工作可以让程序自动完成。比如自动化测试、自动下单交易等。很多软件除了可以GUI方式操作外还可以用CLI接口操作,不过当一些软件未提供CLI接口时,我们应该怎么办呢?我们还可以用程序控制桌面上的窗口、模拟点击鼠标或按下键盘等动作来释放自己。

pywin32是一个Python库,它为Python提供访问Windows API的扩展,提供了齐全的windows常量、接口、线程以及COM机制等等,安装后会自带一个pythonwin的IDE。接下来主要介绍下如何通过Python去操作windows桌面软件。

1、打开软件或文件

比如打开一个谷歌浏览器,或者打开一个word文件,如下所示:

win32api.ShellExecute(1, 'open',
 r'C:Program Files (x86)GoogleChromeApplicationchrome.exe',
 '', '', 1)
win32api.ShellExecute(1, 'open',
 r'C:UsersJayDesktopEnvironment Guider.docx',
 '', '', 1)

win32api.ShellExecute()的参数主要包括:

  • HWND:指定父窗口句柄
  • Operation:指定动作, 譬如"edit",“explore”,“open”,“find”,“print”,“NULL”
  • FileName:指定要打开的文件或程序
  • Parameters:指定打开程序所需参数
  • Directory:缺省目录
  • ShowCmd:打开选项,可选值:
    • SW_HIDE = 0; {隐藏窗口,活动状态给令一个窗口}
    • SW_SHOWNORMAL = 1; {用最近的大小和位置显示窗口, 同时令其进入活动状态}
    • SW_NORMAL = 1; {用当前的大小和位置显示一个窗口,不改变活动窗口}
    • SW_SHOWMINIMIZED = 2; {最小化窗口,并将其激活}
    • SW_SHOWMAXIMIZED = 3; {最大化窗口,并将其激活}
    • SW_MAXIMIZE = 3; {同 SW_SHOWMAXIMIZED}
    • SW_SHOWNOACTIVATE = 4; {用最近的大小和位置显示一个窗口,不改变活动窗口}
    • SW_SHOW = 5; {用当前的大小和位置显示一个窗口,令其进入活动状态}
    • SW_MINIMIZE = 6; {最小化窗口, 不激活}
    • SW_SHOWMINNOACTIVE = 7; {同 SW_MINIMIZE}
    • SW_SHOWNA = 8; {用当前的大小和位置显示一个窗口,不改变活动窗口}
    • SW_RESTORE = 9; {同 SW_SHOWNORMAL}
    • SW_SHOWDEFAULT = 10; {同 SW_SHOWNORMAL}
    • SW_MAX = 10; {同 SW_SHOWNORMAL}

执行成功会返回应用程序句柄, 如果返回值 <= 32,则表示执行错误。返回值可能的错误有:

  • 0—— {内存不足}
  • 2—— {文件名错误}
  • 3—— {路径名错误}
  • 11—— {EXE 文件无效}
  • 26—— {发生共享错误}
  • 27—— {文件名不完全或无效}
  • 28—— {超时}
  • 29—— {DDE 事务失败}
  • 30—— {正在处理其他 DDE 事务而不能完成该 DDE 事务}
  • 31—— {没有相关联的应用程序}

2、查找窗体的句柄

在win32编程的世界里,包括窗口到文本框的所有控件都是窗体,所有的窗体都有独立的句柄。要操作任意一个窗体,都需要找到这个窗体的句柄。句柄是一个32位整数,在windows中用于标记对象。比如查找Snipping Tool和New Text Document.txt的句柄,如下所示:

para_hld = win32gui.FindWindow(None, "Snipping Tool")# 1836416
para_hld = win32gui.FindWindow(None, "New Text Document.txt - Notepad")# 591410

win32gui.FindWindow()属于win32gui的模块,它自顶层窗口(也就是桌面)开始搜索条件匹配的窗体,并返回这个窗体的句柄。该函数仅能查找主窗口,因此无法搜索子窗口,也不区分大小写,未找到则返回0。

win32gui.FindWindow()的参数主要包括 (lpClassName=None, lpWindowName=None):

  • lpClassName:字符型,窗体的类名,可以在Spy++里找到
  • lpWindowName:字符型,窗口名,也就是标题栏上能看见的那个标题。

如何使用Python自动控制windows桌面

3、查找句柄的类名和标题

比如通过Snipping Tool和New Text Document.txt的句柄查找对应的类名和标题,如下所示:

title = win32gui.GetWindowText(1836416)
classname = win32gui.GetClassName(1836416)
print "windows handler:{0}; title:{1}; classname:{2}".format(1836416, title, classname)

打印显示如下:

windows handler:1836416; title:Snipping Tool; classname:Microsoft-Windows-Tablet-SnipperToolbar
title = win32gui.GetWindowText(591410)
classname = win32gui.GetClassName(591410)
print "windows handler:{0}; title:{1}; classname:{2}".format(591410, title, classname)

打印显示如下:

windows handler:591410; title:New Text Document.txt - Notepad; classname:Notepad

4、调用win32gui.EnumWindows()枚举所有窗口句柄

直到最后一个顶层窗口被枚举则停止枚举过程。如下所示:

hWndList = []
win32gui.EnumWindows(lambda hWnd, param: param.append(hWnd), hWndList)
print hWndList
for hwnd in hWndList:
 title = win32gui.GetWindowText(hwnd)
 print title

打印显示如下:

[852802L, 65946L, 65928L, 65930L, 65900L, 65920L, 65924L, 65922L, 65944L, 65892L, 65886L, 6817870L, 65960L, 6031410L, …… 66052L, 65734L]
……
New Text Document.txt - Notepad
Snipping Tool
DDE Server Window
OfficePowerManagerWindow
OfficePowerManagerWindow
DDE Server Window
GDI+ Window
Global Internet Access
……

5、win32gui.SetForegroundWindow()函数将指定窗体设置到最顶层,并且激活该窗口

构造函数为:win32gui.SetWindowPos(HWN hWnd,HWND hWndlnsertAfter, int X,int Y, int cx,int cy, UNIT.Flags)

关于win32gui.SetForegroundWindow(para_hld)报错的问题:

pywintypes.error: (0, ‘SetForegroundWindow', ‘No error message is available')

其实调用SetForegroundWindow()会有很多限制,参考官网的说明

如何使用Python自动控制windows桌面

因此调用SetForegroundWindow()时需要查看当前运行的条件是否符合上述要求,此处在调用SetForegroundWindow()前事先发送一个键盘event来解决该问题。

例程如下所示:

win32api.keybd_event(13, 0, 0, 0) #
win32gui.SetForegroundWindow(para_hld)

6、win32api.keybd_event()模拟键盘输入

构造函数如下所示:

win32api.keybd_event (bVk, bScan, dwFlags, dwExtraInfo)
  • bVk:虚拟键码(键盘键码对照表见附录);
  • bScan:硬件扫描码,一般设置为0即可;
  • dwFlags:函数操作的一个标志位,如果值为KEYEVENTF_EXTENDEDKEY则该键被按下,也可设置为0即可,如果值为KEYEVENTF_KEYUP则该按键被释放;
  • dwExtraInfo:定义与击键相关的附加的32位值,一般设置为0即可。

按下enter键后抬起的例程如下所示:

win32api.keybd_event(13,0,0,0) # enter
win32api.keybd_event(13,0,win32con.KEYEVENTF_KEYUP,0) #释放按键

7、模拟鼠标输入

直接给出例程,如下所示:

# 获取鼠标当前位置的坐标
print win32api.GetCursorPos()
# 将鼠标移动到坐标处
win32api.SetCursorPos((100, 100))
# 左点击
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 100, 100, 0, 0)
time.sleep(2)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 100, 100, 0, 0)

8、关于鼠标键盘的操作还可以使用PyUserInput库

PyUserInput是一个使用python的跨平台的操作鼠标和键盘的模块,使用非常方便。支持的平台及依赖如下:

  • Linux - Xlib
  • Mac - Quartz, AppKit
  • Windows - pywin32, pyHook

实例化一个鼠标和键盘对象,如下所示:

from pymouse import PyMouse
from pykeyboard import PyKeyboard
m = PyMouse()
k = PyKeyboard()
操作鼠标和键盘,如下所示:
m.click(190,70,1)#移动并且在xy位置点击
time.sleep(2)
m.click(190, 200, 1)#移动并且在xy位置点击
time.sleep(2)
k.tap_key(k.function_keys[5])#?点击功能键F5

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python常用web框架简单性能测试结果分享(包含django、flask、bottle、tornado)
Aug 25 Python
Python中的类学习笔记
Sep 23 Python
Python3中的2to3转换工具使用示例
Jun 12 Python
对pandas中时间窗函数rolling的使用详解
Nov 28 Python
10个Python面试常问的问题(小结)
Nov 20 Python
flask的orm框架SQLAlchemy查询实现解析
Dec 12 Python
python集合删除多种方法详解
Feb 10 Python
Python networkx包的实现
Feb 14 Python
python怎么调用自己的函数
Jul 01 Python
Python爬虫使用bs4方法实现数据解析
Aug 25 Python
pycharm中leetcode插件使用图文详解
Dec 07 Python
Python 实现定积分与二重定积分的操作
May 26 Python
python字典嵌套字典的情况下找到某个key的value详解
Jul 10 #Python
如何安装并使用conda指令管理python环境
Jul 10 #Python
python变量的存储原理详解
Jul 10 #Python
python中 * 的用法详解
Jul 10 #Python
通过python实现随机交换礼物程序详解
Jul 10 #Python
Python实现简单的列表冒泡排序和反转列表操作示例
Jul 10 #Python
Python获取好友地区分布及好友性别分布情况代码详解
Jul 10 #Python
You might like
yii框架源码分析之创建controller代码
2011/06/28 PHP
PHP上传图片类显示缩略图功能
2016/06/30 PHP
详解JavaScript基于面向对象之继承
2015/12/13 Javascript
jquery简单倒计时实现方法
2015/12/18 Javascript
JavaScript添加随滚动条滚动窗体的方法
2016/02/23 Javascript
jQuery+CSS实现简单切换菜单示例
2016/07/27 Javascript
Jquery获取当前城市的天气信息
2016/08/05 Javascript
如何防止INPUT按回车自动提交表单FORM
2016/12/06 Javascript
基于BootstrapValidator的Form表单验证(24)
2016/12/12 Javascript
基于vue.js轮播组件vue-awesome-swiper实现轮播图
2017/03/17 Javascript
Cookies 和 Session的详解及区别
2017/04/21 Javascript
解决jQuery ajax动态新增节点无法触发点击事件的问题
2017/05/24 jQuery
浅谈vue引入css,less遇到的坑和解决方法
2018/01/20 Javascript
Vue 全局loading组件实例详解
2018/05/29 Javascript
vue结合axios与后端进行ajax交互的方法
2018/07/06 Javascript
javascript对HTML字符转义与反转义
2018/12/13 Javascript
vue相关配置文件详解及多环境配置详细步骤
2020/05/19 Javascript
python基础教程之序列详解
2014/08/29 Python
python3实现ftp服务功能(服务端 For Linux)
2017/03/24 Python
python利用dir函数查看类中所有成员函数示例代码
2017/09/08 Python
python 实现交换两个列表元素的位置示例
2019/06/26 Python
解决pycharm下os.system执行命令返回有中文乱码的问题
2019/07/07 Python
Django与AJAX实现网页动态数据显示的示例代码
2021/02/24 Python
详解CSS3中字体平滑处理和抗锯齿渲染
2017/03/29 HTML / CSS
美国现代家具和家居商店:Apt2B
2016/08/29 全球购物
京东全球售:直邮香港,澳门,台湾,美国,澳大利亚等地区
2017/09/24 全球购物
计算机应用专业推荐信
2013/11/13 职场文书
《我不是最弱小的》教学反思
2014/02/23 职场文书
成人继续教育实施方案
2014/03/01 职场文书
节水倡议书范文
2014/04/15 职场文书
社会公德演讲稿
2014/05/20 职场文书
欢迎领导检查标语
2014/06/27 职场文书
弘扬焦裕禄精神践行三严三实心得体会
2014/10/13 职场文书
2015会计试用期工作总结
2014/12/12 职场文书
出国留学单位推荐信
2015/03/26 职场文书
贷款工作证明模板
2015/06/12 职场文书