python句柄操作(后台)
# 根据句柄获取线程和pid
#根据pid停止程序
import win32gui
import time
import os
import win32process
main_hwnd = win32gui.FindWindow(None, "屏幕截图")
print(main_hwnd)
# 根据句柄获取线程和pid
thread, pid = win32process.GetWindowThreadProcessId(main_hwnd)
# 根据pid停止程序
os.system('taskkill/pid ' + str(pid) + ' /f')
def get_child_windows(parent):
""" 获得parent的所有子窗口句柄返回子窗口句柄列表 """
if not parent:
return
hwnd_child_list = []
win32gui.EnumChildWindows(parent, lambda hwnd2, param: param.append(hwnd2), hwnd_child_list)
return hwnd_child_list
child_hwnd = get_child_windows(main_hwnd)
print(child_hwnd)
def show_window_attr(hWnd):
'''
显示窗口的属性
:return:
'''
if not hWnd:
return
# 中文系统默认title是gb2312的编码
title = win32gui.GetWindowText(hWnd)
#这里可能要把标题的gbk转换成utf-8 ,暂时不管了,可以加个函数
clsname = win32gui.GetClassName(hWnd)
# print('窗口句柄:%s ' % (hWnd))
print('窗口类名:%s' % (clsname))
# str = "Chrome_WidgetWin_1"
# if str == clsname:
# fd = win32gui.FindWindow(clsname, None) # 查找窗口句柄
# win32gui.ShowWindow(fd, 1) # 隐藏窗口
print ('窗口句柄:%s ' % (hWnd))
print ('窗口标题:%s' % (title))
# 方法一:麻烦
# 字典字母的对应编号,根据遍历账号密码,得到对应整数型键,然后由WM_IME_CHAR得到字母和数字
dic = {33: '!', 34: '"', 35: '#', 36: '$', 37: '%', 38: '&', 39: "'", 40: '(', 41: ')', 42: '*', 43: '+', 44: ',',
45: '-', 46: '.', 47: '/', 48: '0', 49: '1', 50: '2', 51: '3', 52: '4', 53: '5', 54: '6', 55: '7', 56: '8',
57: '9', 58: ':', 59: ';', 60: '<', 61: '=', 62: '>', 63: '?', 64: '@', 65: 'A', 66: 'B', 67: 'C', 68: 'D',
69: 'E', 70: 'F', 71: 'G', 72: 'H', 73: 'I', 74: 'J', 75: 'K', 76: 'L', 77: 'M', 78: 'N', 79: 'O', 80: 'P',
81: 'Q', 82: 'R', 83: 'S', 84: 'T', 85: 'U', 86: 'V', 87: 'W', 88: 'X', 89: 'Y', 90: 'Z', 91: '[', 92: '\\',
93: ']', 94: '^', 95: '_', 96: '`', 97: 'a', 98: 'b', 99: 'c', 100: 'd', 101: 'e', 102: 'f', 103: 'g', 104: 'h',
105: 'i', 106: 'j', 107: 'k', 108: 'l', 109: 'm', 110: 'n', 111: 'o', 112: 'p', 113: 'q', 114: 'r', 115: 's',
116: 't', 117: 'u', 118: 'v', 119: 'w', 120: 'x', 121: 'y', 122: 'z', 123: '{', 124: '|', 125: '}', 126: '~'}
text = "231yang."
for i in text:
value = int([k for k, v in dic.items() if v == i][0])
print(value)
win32gui.SendMessage(1970438, win32con.WM_IME_CHAR, value) # 输入字符串,只能英文和数字,不是按键
# 方法二:ord直接转,中文也可以输入
import win32con
import win32gui
import win32api
import time
for i in text:
win32gui.SendMessage(hwnd, win32con.WM_IME_CHAR, ord(str(i))) # 输入字符串,只能英文和数字,不是按键
time.sleep(1)
win32gui.PostMessage(hwnd, win32con.WM_KEYDOWN, win32con.VK_RETURN, 0)
# ctrl +v 粘贴
win32api.keybd_event(17, 0, 0, 0) # 有效,按下CTRL
win32gui.SendMessage(hwnd, win32con.WM_KEYDOWN, ord("V"), 0) # V
win32api.keybd_event(17, 0, win32con.KEYEVENTF_KEYUP, 0) # 放开CTRL
def screen(index):
# 获取后台窗口的句柄,注意后台窗口不能最小化
# 获取Pid(类名, 标题)
main_hwnd = win32gui.FindWindow("LDPlayerMainFrame", "雷电模拟器" + str(index)) # 获得父句柄
print(main_hwnd)
hwndChildList = []
win32gui.EnumChildWindows(main_hwnd, lambda hwnd, param: param.append(hwnd), hwndChildList)
hWnd = hwndChildList[0] # 子句柄的第一个句柄
# print(hWnd)
left, top, right, bot = win32gui.GetWindowRect(hWnd)
if right < 1100:
# 获取句柄窗口的大小信息
print("没有最大化,进行最大化")
win32gui.ShowWindow(main_hwnd, win32con.SW_MAXIMIZE)
hwndChildList = []
win32gui.EnumChildWindows(main_hwnd, lambda hwnd, param: param.append(hwnd), hwndChildList)
hWnd = hwndChildList[0] # 子句柄的第一个句柄
left, top, right, bot = win32gui.GetWindowRect(hWnd)
print(left, top, right, bot)
width = right - left
height = bot - top
# 返回句柄窗口的设备环境,覆盖整个窗口,包括非客户区,标题栏,菜单,边框
hWndDC = win32gui.GetWindowDC(hWnd)
# 创建设备描述表
mfcDC = win32ui.CreateDCFromHandle(hWndDC)
# 创建内存设备描述表
saveDC = mfcDC.CreateCompatibleDC()
# 创建位图对象准备保存图片
saveBitMap = win32ui.CreateBitmap()
# 为bitmap开辟存储空间
saveBitMap.CreateCompatibleBitmap(mfcDC, width, height)
# 将截图保存到saveBitMap中
saveDC.SelectObject(saveBitMap)
# 保存bitmap到内存设备描述表
saveDC.BitBlt((0, 0), (width, height), mfcDC, (0, 0), win32con.SRCCOPY)
# 保存图像
# 方法二(第一部分):PIL保存
# # 获取位图信息
bmpinfo = saveBitMap.GetInfo()
bmpstr = saveBitMap.GetBitmapBits(True)
# 生成图像
im_PIL = Image.frombuffer('RGB', (bmpinfo['bmWidth'], bmpinfo['bmHeight']), bmpstr, 'raw', 'BGRX', 0, 1)
im_PIL = im_PIL.resize((720, 1280), Image.ANTIALIAS) # 图片分辨率跳到720*1280
im_PIL.save("im_PIL.jpg") # 保存
return hWnd
def pc_screen():
# 获取后台窗口的句柄,注意后台窗口不能最小化
# 获取Pid(类名, 标题)
hWnd= win32gui.FindWindow("SDL_app", "Redmi Note 8") # 屏幕
# hWnd= win32gui.FindWindow("Qt5QWindowIcon", "QtScrcpy") # 控制台
print(hWnd)
# hwndChildList = []
# win32gui.EnumChildWindows(main_hwnd, lambda hwnd, param: param.append(hwnd), hwndChildList)
# hWnd = hwndChildList[0] # 子句柄的第一个句柄
# # print(hWnd)
left, top, right, bot = win32gui.GetWindowRect(hWnd)
print(left, top, right, bot)
if (right-left) != 520 and (bot-top) != 1100:
print("不满足分辨率需要调整")
win32gui.MoveWindow(hWnd, 0, 0, 520, 1400, True)
left, top, right, bot = win32gui.GetWindowRect(hWnd)
else:
print("满足分辨率不用调整了")
# if right < 1100:
# # 获取句柄窗口的大小信息
# print("没有最大化,进行最大化")
# win32gui.ShowWindow(hWnd, win32con.SW_MAXIMIZE)
# hwndChildList = []
# win32gui.EnumChildWindows(main_hwnd, lambda hwnd, param: param.append(hwnd), hwndChildList)
# hWnd = hwndChildList[0] # 子句柄的第一个句柄
# left, top, right, bot = win32gui.GetWindowRect(hWnd)
# print(left, top, right, bot)
width = right - left
height = bot - top
# 返回句柄窗口的设备环境,覆盖整个窗口,包括非客户区,标题栏,菜单,边框
hWndDC = win32gui.GetWindowDC(hWnd)
# 创建设备描述表
mfcDC = win32ui.CreateDCFromHandle(hWndDC)
# 创建内存设备描述表
saveDC = mfcDC.CreateCompatibleDC()
# 创建位图对象准备保存图片
saveBitMap = win32ui.CreateBitmap()
# 为bitmap开辟存储空间
saveBitMap.CreateCompatibleBitmap(mfcDC, width, height)
# 将截图保存到saveBitMap中
saveDC.SelectObject(saveBitMap)
# 保存bitmap到内存设备描述表
saveDC.BitBlt((0, 0), (width, height), mfcDC, (0, 0), win32con.SRCCOPY)
# 保存图像
# 方法二(第一部分):PIL保存
# # 获取位图信息
bmpinfo = saveBitMap.GetInfo()
bmpstr = saveBitMap.GetBitmapBits(True)
# 生成图像
im_PIL = Image.frombuffer('RGB', (bmpinfo['bmWidth'], bmpinfo['bmHeight']), bmpstr, 'raw', 'BGRX', 0, 1)
# im_PIL = im_PIL.resize((720, 1280), Image.ANTIALIAS) # 图片分辨率跳到720*1280
im_PIL.save("im_PIL.jpg") # 保存
return hWnd
"""获取句柄进行后台cmd输入和回车,如果没有打开cmd就前台就行搜索框打开cmd,在进行输入,不能直接用路径打开cmd"""
main_hwnd = win32gui.FindWindow(None, cmd_name)
print(main_hwnd)
if main_hwnd:
# ssh 空格+ 用户名@ip
input("ssh " + username + "@" + hostname, main_hwnd)
win32gui.PostMessage(main_hwnd, win32con.WM_KEYDOWN, win32con.VK_RETURN, 0)
time.sleep(1)
input(password, main_hwnd)
win32gui.PostMessage(main_hwnd, win32con.WM_KEYDOWN, win32con.VK_RETURN, 0)
time.sleep(0.5)
input("supervisorctl reload", main_hwnd)
win32gui.PostMessage(main_hwnd, win32con.WM_KEYDOWN, win32con.VK_RETURN, 0)
time.sleep(0.5)
input("exit", main_hwnd)
win32gui.PostMessage(main_hwnd, win32con.WM_KEYDOWN, win32con.VK_RETURN, 0)
time.sleep(0.5)
input("exit", main_hwnd)
win32gui.PostMessage(main_hwnd, win32con.WM_KEYDOWN, win32con.VK_RETURN, 0)
else:
print("没打开cmd,需要打开cmd")
os.system('start "%s"' % cmd_path)
get_hwnd()
def click(self, x, y):
param = win32api.MAKELONG(int(x), int(y))
win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, param)
win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONUP, win32con.MK_LBUTTON, param)
# -*- coding: utf-8 -*-
# from win32gui import *
# import win32gui, win32process
from win32gui import EnumWindows, IsWindow, IsWindowEnabled, GetWindowText, IsWindowVisible
import os
import time
import rpa.win32._window_action as window
time.sleep(1)
def get_pid_app(category_name, title):
titles = set()
def foo(hwnd, mouse):
# 去掉下面这句就所有都输出了,但是我不需要那么多
if IsWindow(hwnd) and IsWindowEnabled(hwnd) and IsWindowVisible(hwnd):
titles.add(GetWindowText(hwnd))
EnumWindows(foo, 0)
lt = [t for t in titles if t]
lt.sort()
for name in lt:
# 类名, 标题
log.info(name)
if title in name:
print("最大化" + str(name))
try:
window.win_maximize(title,category_name)
except Exception as e:
log.info(e)
# "廊坊银行 - Internet Explorer","IEFrame"
get_pid_app("IEFrame", "Internet Explorer")
time.sleep(0.5)
# get_pid_app("IEFrame", "廊坊银行 - Internet Explorer")
# exit()
# "廊坊银行 - Internet Explorer","IEFrame"
import win32gui
def get_hwd(tilte):
hwnd_title = dict()
def get_all_hwnd(hwnd,mouse):
if win32gui.IsWindow(hwnd) and win32gui.IsWindowEnabled(hwnd) and win32gui.IsWindowVisible(hwnd):
hwnd_title.update({hwnd:win32gui.GetWindowText(hwnd)})
win32gui.EnumWindows(get_all_hwnd, 0)
for h,t in hwnd_title.items():
if tilte in t:
# print(([h], [t]))
return h
print(get_hwd("现金流量表"))
9.使用Win32 API在Python中自动化文件另存对话框交互的优化与简化
简介:
自动化与图形用户界面(GUI)的交互是编程中的常见任务,尤其是在处理重复性任务或需要大量步骤的任务时。在本文中,我们将探讨一种简化且优化的Python脚本,利用Win32 API自动化与文件另存对话框的交互。
代码优化:
提供的Python脚本旨在自动化与Windows中的“另存为”对话框的交互过程。脚本经历以下步骤:
- 查找包含指定关键字的主窗口。
- 检索子窗口并识别“Edit”控件。
- 清空输入内容。
- 将文件路径输入“Edit”控件。
- 模拟按下回车键。
以下是对原始代码进行的关键优化和简化:
-
改进的代码结构:
优化了代码结构以提高可读性和可维护性。定义了函数来封装特定任务,使代码更加模块化。 -
get_child_windows
中param
的默认值:
确保get_child_windows
函数中的param
有一个默认值为空列表,以避免潜在的错误。 -
使用绝对路径:
脚本现在使用os.path.abspath
获取文件的绝对路径,以确保正确处理文件路径。 -
一致的注释:
添加了一致且信息丰富的注释,以解释脚本的每个步骤,使其更容易被他人理解。 -
删除不必要的操作:
删除了不必要的taskkill
操作,因为强制终止进程可能导致不可预测的后果。
以下是优化后的代码:
import win32gui
import win32process
import win32con
import time
import os
def get_child_windows(parent):
"""获取“parent”的所有子窗口句柄并返回列表。"""
if not parent:
return []
hwnd_child_list = []
win32gui.EnumChildWindows(parent, lambda hwnd2, param: param.append(hwnd2), hwnd_child_list)
return hwnd_child_list
def find_save_dialog(key_word="另存为", class_name='', text='', times=10):
"""查找包含指定关键字的主窗口句柄。"""
for _ in range(times):
main_hwnd = win32gui.FindWindow(None, key_word)
print("主句柄:", main_hwnd)
if main_hwnd:
child_hwnd_list = get_child_windows(main_hwnd)
for hwnd in child_hwnd_list:
clsname = win32gui.GetClassName(hwnd)
if text:
gettext = win32gui.GetWindowText(hwnd)
print(gettext, hwnd)
if text == gettext:
return hwnd
if clsname == "Edit":
return hwnd
else:
time.sleep(0.5)
def clear_input_box(hwnd):
"""清空编辑控件的内容。"""
win32gui.SendMessage(hwnd, win32con.WM_SETTEXT, 0, '')
def download_id(file_path, key_word="另存为"):
"""自动化文件另存对话框交互。"""
# if os.path.exists(file_path):
# os.remove(file_path)
final_hwnd = find_save_dialog(key_word)
if final_hwnd:
print('输入框句柄为:', final_hwnd)
# 清空输入框
clear_input_box(final_hwnd)
abs_file_path = os.path.abspath(file_path)
for char in abs_file_path:
win32gui.SendMessage(final_hwnd, win32con.WM_IME_CHAR, ord(str(char)), 0)
time.sleep(1)
win32gui.PostMessage(final_hwnd, win32con.WM_KEYDOWN, win32con.VK_RETURN, 0)
is_final_hwnd = find_save_dialog(key_word="确认另存为", text='是(&Y)', times=2)
if is_final_hwnd:
win32gui.PostMessage(is_final_hwnd, win32con.WM_KEYDOWN, ord("Y"), 0)
# time.sleep(0.5)
# win32gui.PostMessage(final_hwnd, win32con.WM_KEYDOWN, win32con.VK_RETURN, 0)
# win32gui.PostMessage(final_hwnd, win32con.WM_KEYDOWN, win32con.VK_RETURN, 0)
# 示例用法
download_id(r'B:\新建文件夹\打印.pdf', key_word="将打印输出另存为")
# download_id(r'B:\新建文件夹\打印.pdf', key_word="确认另存为")
结论:
自动化与GUI元素的交互需要仔细考虑特定应用和所使用的GUI框架。提供的优化脚本作为使用Python中的Win32 API自动化与文件另存对话框交互的起点。开发人员可以根据其具体需求和应用场景进一步定制和扩展脚本。
本文作者: 永生
本文链接: https://yys.zone/detail/?id=151
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
发表评论
评论列表 (0 条评论)
暂无评论,快来抢沙发吧!