使用pywin32制作Windows自动化工具
最近在实验室用ENVI标了一批图,好多操作都是机械的重复的,于是想有没有可能做一个自动化的小工具来简化操作。查了一些资料发现pywin32应该是可以。于是先尝试简单做一个小例子练练手。
这篇做的是打开记事本,输入helloworld,选择编码格式为utf-8并保存。
使用了spy++工具来辅助
程序的启动
这里有两种写法,用下面哪一句都可
def start_app(path):
win32api.ShellExecute(0, 'open', path,'','',1)
# os.startfile(path) # 也可用这条
窗口的定位
每一个窗口都有唯一的一个handle,调用win32API的时候,这个handle是操作每一个窗口和控件必须的参数。
要找到窗口的handle,需要两个函数
- FindWindow(lpClassName=None, lpWindowName=None):
- 描述:自顶层窗口(也就是桌面)开始搜索条件匹配的窗体,并返回这个窗体的句柄。不搜索子窗口、不区分大小写。找不到就返回0
- 参数:
lpClassName:字符型,是窗体的类名,这个可以在Spy++里找到。
lpWindowName:字符型,是窗口名,也就是标题栏上你能看见的那个标题。 - 说明:这个函数我们仅能用来找主窗口。
- FindWindowEx(hwndParent=0, hwndChildAfter=0, lpszClass=None, lpszWindow=None);
- 描述:搜索类名和窗体名匹配的窗体,并返回这个窗体的句柄。不区分大小写,找不到就返回0。
- 参数:
hwndParent:若不为0,则搜索句柄为hwndParent窗体的子窗体。
hwndChildAfter:若不为0,则按照z-index的顺序从hwndChildAfter向后开始搜索子窗体,否则从第一个子窗体开始搜索。
lpClassName:字符型,是窗体的类名,这个可以在Spy++里找到。
lpWindowName:字符型,是窗口名,也就是标题栏上你能看见的那个标题。 - 说明:找到了主窗口以后就靠它来定位子窗体啦。
参考https://blog.csdn.net/bluehawksky/article/details/44957627
首先要获取主窗口的handle
notepad_path = r'C:\Windows\notepad.exe'
start_app(notepad_path)
while True:
win = win32gui.FindWindow('Notepad','')
if win != 0:
win32api.Sleep(200)
break
这里用了一个循环是因为程序启动需要时间,后面出现有延迟的地方,都是在实际测试的时候,有时候窗口没有完全打开导致查询不到窗口。
封装了几个函数,可以直接调用
def printHandle(func):
def wrapper(*args, **kw):
handle = func(*args, **kw)
print('%x' % (handle))
return handle
return wrapper
def find_idxSubHandle(pHandle, winClass, index=0):
"""
已知子窗口的窗体类名
寻找第index号个同类型的兄弟窗口
"""
assert type(index) == int and index >= 0
handle = win32gui.FindWindowEx(pHandle, 0, winClass, None)
while index > 0:
handle = win32gui.FindWindowEx(pHandle, handle, winClass, None)
index -= 1
return handle
def find_subHandle(pHandle, winClassList):
"""
递归寻找子窗口的句柄
pHandle是祖父窗口的句柄
winClassList是各个子窗口的class列表,父辈的list-index小于子辈
"""
assert type(winClassList) == list
if len(winClassList) == 1:
return find_idxSubHandle(pHandle, winClassList[0][0], winClassList[0][1])
else:
pHandle = find_idxSubHandle(pHandle