209 lines
7.3 KiB
Python
209 lines
7.3 KiB
Python
|
|
# -*- coding: utf-8 -*-
|
|||
|
|
# @Author: Luxuan
|
|||
|
|
# @Date: 2024-05-23 21:50:44
|
|||
|
|
# @Last Modified by: Luxuan
|
|||
|
|
# @Last Modified time: 2024-05-25 11:07:03
|
|||
|
|
|
|||
|
|
|
|||
|
|
import pyautogui as pag
|
|||
|
|
import pywinauto
|
|||
|
|
import win32gui
|
|||
|
|
import win32con
|
|||
|
|
import uiautomation as uiauto
|
|||
|
|
import psutil
|
|||
|
|
from PIL import ImageGrab,ImageSequence
|
|||
|
|
|
|||
|
|
class WinUIBase(object):
|
|||
|
|
def __init__(self):
|
|||
|
|
self.app = None
|
|||
|
|
pass
|
|||
|
|
|
|||
|
|
def launcher(self, app_name, backend='win32',timeout=2):
|
|||
|
|
"""
|
|||
|
|
:param app_name: app进程名称或者app路径
|
|||
|
|
:return:
|
|||
|
|
"""
|
|||
|
|
pid_list = self._check_processes(app_name)
|
|||
|
|
if len(pid_list) == 0:
|
|||
|
|
self.app = pywinauto.application.Application(backend=backend).start(app_name, timeout=timeout, retry_interval=2)
|
|||
|
|
else:
|
|||
|
|
pid = pid_list[0]
|
|||
|
|
self.app = pywinauto.application.Application(backend=backend).connect(process=pid, timeout=timeout, retry_interval=2)
|
|||
|
|
pass
|
|||
|
|
|
|||
|
|
def find_window(self, win_title):
|
|||
|
|
win = None
|
|||
|
|
try:
|
|||
|
|
win = self.app.window(title_re=win_title)
|
|||
|
|
# self.main_win.maximize()
|
|||
|
|
win.wait(wait_for='visible', timeout=3, retry_interval=2)
|
|||
|
|
# time.sleep(0.2)
|
|||
|
|
return win
|
|||
|
|
except Exception as e:
|
|||
|
|
print(e)
|
|||
|
|
return win
|
|||
|
|
pass
|
|||
|
|
|
|||
|
|
def show_mode(self,win,mode):
|
|||
|
|
if mode=="max":
|
|||
|
|
win.maximize()
|
|||
|
|
elif mode=="min":
|
|||
|
|
pass
|
|||
|
|
elif mode=="focus":
|
|||
|
|
pass
|
|||
|
|
elif mode=="top":
|
|||
|
|
pass
|
|||
|
|
pass
|
|||
|
|
|
|||
|
|
def get_window(self,name):
|
|||
|
|
wins = self.app.windows()
|
|||
|
|
win_items = [x for x in wins if x.element_info.name==name]
|
|||
|
|
if len(win_items)>0:
|
|||
|
|
return win_items[0]
|
|||
|
|
return None
|
|||
|
|
|
|||
|
|
def get_childers(self,control,auto_id = None, class_name = None, name= None):
|
|||
|
|
childers = control.descendants()
|
|||
|
|
if auto_id:
|
|||
|
|
childers = [x for x in childers if x.handle==auto_id]
|
|||
|
|
elif class_name:
|
|||
|
|
childers = [x for x in childers if x.element_info.class_name==class_name]
|
|||
|
|
elif name:
|
|||
|
|
childers = [x for x in childers if x.element_info.name==name]
|
|||
|
|
|
|||
|
|
if len(childers)==1:
|
|||
|
|
return childers[0]
|
|||
|
|
return childers
|
|||
|
|
pass
|
|||
|
|
|
|||
|
|
def close_popups(self,win,set_show=False):
|
|||
|
|
try:
|
|||
|
|
popup_hwnd = win.popup_window()
|
|||
|
|
if not popup_hwnd or not set_show:
|
|||
|
|
return
|
|||
|
|
popup_window = self.app.window(handle=popup_hwnd)
|
|||
|
|
popup_window.wait(wait_for='visible', timeout=1)
|
|||
|
|
popup_window.set_focus()
|
|||
|
|
# popup_window.close()
|
|||
|
|
popup_window.type_keys("{ENTER}")
|
|||
|
|
except Exception as e:
|
|||
|
|
print(e)
|
|||
|
|
pass
|
|||
|
|
|
|||
|
|
def _check_processes(self, app_name):
|
|||
|
|
pid_list = []
|
|||
|
|
processes = psutil.process_iter()
|
|||
|
|
for process in processes:
|
|||
|
|
try:
|
|||
|
|
name = process.name()
|
|||
|
|
# conns = process.connections()
|
|||
|
|
exe = process.exe()
|
|||
|
|
if app_name in name or app_name == exe:
|
|||
|
|
pid_list.append(process.pid)
|
|||
|
|
except Exception as e:
|
|||
|
|
print(e)
|
|||
|
|
return pid_list
|
|||
|
|
pass
|
|||
|
|
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
pass
|
|||
|
|
|
|||
|
|
|
|||
|
|
"""
|
|||
|
|
pywinauto
|
|||
|
|
What is pywinauto — pywinauto 0.6.8 documentation
|
|||
|
|
https://pywinauto.readthedocs.io/en/latest/
|
|||
|
|
GitHub - 2gis/Winium.Desktop: Winium.Desktop is Selenium Remote WebDriver implementation for automated testing of Windows application based on WinFroms and WPF platforms.
|
|||
|
|
https://github.com/2gis/Winium.Desktop
|
|||
|
|
|
|||
|
|
app2.window(title_re ='Form',class_name_re="WindowsForms10").wait('ready', timeout=10)
|
|||
|
|
打印所有子控件
|
|||
|
|
print_control_identifiers()
|
|||
|
|
|
|||
|
|
win.type_keys('{F5}')
|
|||
|
|
app = Application(backend='win32').start('notepad.exe')
|
|||
|
|
mainwin = app['无标题 - 记事本']
|
|||
|
|
mainwin.Edit.type_keys("自动化输入第一行", with_spaces = True)
|
|||
|
|
mainwin.child_window(class_name="Edit").type_keys("{ENTER} 自动化输入第二行", with_spaces = True)
|
|||
|
|
mainwin.menu_select('文件 -> 保存')
|
|||
|
|
app['另存为']['文件名 Edit'].set_text(r'D:\temp\test_pywa\pywa.txt')
|
|||
|
|
app['另存为']['保存 Button'].click()
|
|||
|
|
app['pywa.txt - 记事本'].type_keys('%FX')
|
|||
|
|
|
|||
|
|
send_keys('^a^c') # select all (Ctrl+A) and copy to clipboard (Ctrl+C)
|
|||
|
|
send_keys('+{INS}') # insert from clipboard (Shift+Ins)
|
|||
|
|
send_keys('%{F4}') # close an active window with Alt+F4
|
|||
|
|
截图
|
|||
|
|
bmp = win.capture_as_image()
|
|||
|
|
pywinauto客户端自动化---窗口进行截图 - 测试-安静 - 博客园
|
|||
|
|
https://www.cnblogs.com/qican/p/13262198.html
|
|||
|
|
|
|||
|
|
Python图像库PIL的类Image及其方法介绍_python pil image-CSDN博客
|
|||
|
|
https://blog.csdn.net/leemboy/article/details/83792729
|
|||
|
|
|
|||
|
|
im.getpixel((0,0))
|
|||
|
|
Python 查找句柄与控件信息(pywinauto库)_pywinauto edit-CSDN博客
|
|||
|
|
https://blog.csdn.net/lylelo/article/details/120214006
|
|||
|
|
app[window_title].menu_select("File->open")
|
|||
|
|
|
|||
|
|
使用pywinauto,如何获取静态文本对象的文本,鉴于父对话框的手柄 - VoidCC
|
|||
|
|
http://cn.voidcc.com/question/p-obaazoml-x.html
|
|||
|
|
indow_handle = pywinauto.findwindows.find_windows(title = u'My Dialog Name')
|
|||
|
|
# 返回应用程序当前顶部窗口,是WindowSpecification对象,可以继续使用对象的方法往下继续查找控件
|
|||
|
|
app.top_window()
|
|||
|
|
dlg.close() # 关闭界面
|
|||
|
|
dlg.minimize() # 最小化界面
|
|||
|
|
dlg.maximize() # 最大化界面
|
|||
|
|
dlg.restore() # 将窗口恢复为正常大小,比如最小化的让他正常显示在桌面
|
|||
|
|
dlg.get_show_state() # 正常0,最大化1,最小化2
|
|||
|
|
|
|||
|
|
# 移动鼠标
|
|||
|
|
mouse.move(coords=(x, y))
|
|||
|
|
|
|||
|
|
# 指定位置,鼠标左击
|
|||
|
|
mouse.click(button='left', coords=(40, 40))
|
|||
|
|
|
|||
|
|
# 鼠标双击
|
|||
|
|
mouse.double_click(button='left', coords=(140, 40))
|
|||
|
|
|
|||
|
|
# 将属性移动到(140,40)坐标处按下
|
|||
|
|
mouse.press(button='left', coords=(140, 40))
|
|||
|
|
|
|||
|
|
# 将鼠标移动到(300,40)坐标处释放,
|
|||
|
|
mouse.release(button='left', coords=(300, 40))
|
|||
|
|
|
|||
|
|
# 右键单击指定坐标
|
|||
|
|
mouse.right_click(coords=(400, 400))
|
|||
|
|
|
|||
|
|
keyboard.send('enter')
|
|||
|
|
keyboard.send('ctrl+v')
|
|||
|
|
handle = window.handle
|
|||
|
|
|
|||
|
|
|
|||
|
|
【python句柄获取】——简单明了的获取窗口句柄,并使用句柄操作获取相应内容(全网最详细)_python获取窗口句柄-CSDN博客
|
|||
|
|
https://blog.csdn.net/weixin_46625757/article/details/122498299
|
|||
|
|
# 通过句柄窗口置顶
|
|||
|
|
win32gui.SetWindowPos('句柄值', win32con.HWND_TOPMOST, 0, 0, 0, 0,win32con.SWP_NOMOVE | win32con.SWP_NOACTIVATE | win32con.SWP_NOOWNERZORDER | win32con.SWP_SHOWWINDOW | win32con.SWP_NOSIZE)
|
|||
|
|
# 通过句柄取消窗口置顶
|
|||
|
|
def set_down(hwnd):
|
|||
|
|
win32gui.SetWindowPos(hwnd, win32con.HWND_NOTOPMOST, 0, 0, 0, 0,
|
|||
|
|
win32con.SWP_SHOWWINDOW | win32con.SWP_NOSIZE | win32con.SWP_NOMOVE)
|
|||
|
|
set_down("句柄值")
|
|||
|
|
# 通过句柄将窗口放到最前
|
|||
|
|
win32gui.SetForegroundWindow("句柄值")
|
|||
|
|
|
|||
|
|
# 通过窗口句柄【最大化窗口】
|
|||
|
|
win32gui.ShowWindow('句柄值', win32con.SW_MAXIMIZE)
|
|||
|
|
|
|||
|
|
# 通过窗口句柄【最小化窗口】
|
|||
|
|
win32gui.ShowWindow('句柄值', win32con.SW_MINIMIZE)
|
|||
|
|
# 通过窗口句柄【关闭当前句柄控件】
|
|||
|
|
# 是关闭单个句柄控件,不是关闭整个程序,只能关闭输入的句柄值
|
|||
|
|
win32gui.SendMessage('句柄值', win32con.WM_CLOSE)
|
|||
|
|
# 在打开此文件所在文件夹并【定位到此文件】
|
|||
|
|
FILE = 'C:/Windows/System32/notepad.exe'
|
|||
|
|
subprocess.Popen(f'explorer.exe /select,{FILE}', shell=False)
|
|||
|
|
#通过窗口标题获取句柄
|
|||
|
|
hld = win32gui.FindWindow(None,u"此电脑")
|
|||
|
|
"""
|