Python 模块虽多,但也不可能满足所有需求。而且,模块为了便于使用,通常都封装过度,有些功能无法灵活使用,必须直接调用Windows API 来实现。要完成这一目标,有两种办法,一种是使用 C 编写 Python 扩展模块,另一种就是编写普通的 DLL 通过 python 的 ctypes 来调用。
Python 没有自带访问 windows 系统 API 的库的,需要下载 pywin32,pywin32 是一个第三方模块库,主要的作用是方便 python 开发者快速调用 windows API 的一个模块库。它直接包装了几乎所有的 Windows API,可以方便地从 Python 直接调用,该模块另一大主要功能是通过 Python 进行 COM 编程。
Python extensions for Microsoft Windows Provides access to much of the Win32 API, the ability to create and use COM objects, and the Pythonwin environment.
翻译过来就是:pywin32 是 针对 Microsoft Windows 的 Python扩展,提供了对大部分 Win32 API 的访问、创建、和使用 COM对象 的能力以及 Pythonwin 环境。
pywin32 提供了齐全的windows 常量、接口、线程 以及 COM机制 等等。Windows Pywin32 允许你像 VC 一样的形式来使用PYTHON开发 win32 应用。代码风格可以类似 win32 sdk,也可以类似MFC,由你选择。如果你仍不放弃vc一样的代码过程在python下,那么这就是一个不错的选择。
1、window 消息、句柄
为了查找目标窗口的句柄,可以下载一个微软自家的 Spy++,可以很方便的查看窗体的消息。
深入理解 windows 消息机制:https://blog.csdn.net/liulianglin/article/details/14449577
Microsoft Win32 程序员参考 (在线 API):http://www.yfvb.com/help/win32sdk/index.htm
- 句柄:是一个 32 位整数,在 windows 中标记对象用,类似一个 dict 中的 key。在 win32 编程的世界里,包括 "窗口、文本框 等所有控件" 都是 窗体,所有的窗体都有独立的句柄。要操作任意一个窗体,你都需要找到这个窗体的句柄 。窗口句柄(具体位数跟个人PC操作系统位数相关),它表示的是消息所属的窗口。我们通常开发的程序都是窗口应用程序,一般一个消息都是和某个窗口相关联的。比如我们在某个活动窗口按下鼠标右键,此时产生的消息就是发送给该活动窗口的。窗口可以是任何类型的屏幕对象,因为Win32能够维护大多数可视对象的句柄(窗口、对话框、按钮、编辑框等)。补充一下:“句柄”---在Windows程序中,有各种各样的资源,系统在创建这些资源的时候,都会为他们分配内存,并返回标识这些资源的标识号,这个标识号就是句柄)。
- 消息:即 消息的标识符,是一些常量值,这些常量可以是Windows单元中预定义的常量,也可以是自定义的常量。在 Windows 中消息是由一个数值表示的,不同的消息对应不同的数值。 消息 是 windows 应用的重要部分,用来告诉窗体 "发生了什么",比如 给一个按钮发送BN_CLICKED 这么个消息,按钮就知道 "哦,我被点了",才能执行相应的下一步操作。但是当这些消息种类多到足以挑战我们的 IQ 时,所以聪明的程序开发者便想到将这些数值定义为WM_XXX 宏的形式。例如,鼠标左键按下的消息--WM_LBUTTONDOWN,键盘按下消息--WM_KEYDOWN,字符消息--WM_CHAR,等等。消息标识符以常量命名的方式指出消息的含义。当窗口过程接收到消息之后,他就会使用消息标识符来决定如何处理消息。例如、WM_PAINT告诉窗口过程窗体客户区被改变了需要重绘。符号常量指定系统消息属于的类别,其前缀指明了处理解释消息的窗体的类型。
- wParam 和 lParam:用于指定消息的附加信息。例如,当我们收到一个键盘按下消息的时候,message 成员变量的值就是 WM_KEYDOWN,但是用户到底按下的是哪一个按键,我们就得拜托这二位,由他们来告知我们具体的信息。
- time 和 pt:这俩个变量分别被用来表示消息投递到消息队列中的时间和鼠标当前的位置,一般情况下不怎么使用(但不代表没用)
PyWin32 地址:https://github.com/mhammond/pywin32
PyWin32 文档:http://timgolden.me.uk/pywin32-docs/contents.html
2、安装 pywin32
安装:pip install pywin32
- win32api :模块内定义了常用的一些 API函数,例如:MessageBox
- win32gui :模块内定义了一些有关 图形操作的API,例如:FindWindow
- win32con :模块内定义了 windows API 内的宏,即 宏常量。例如 MessageBox 内的 MB_OK。( ps:con 个人理解 是 const 常量 的意思 )
安装完成后,在 Python 安装路径下
- Lib\site-packages\win32 下是所有的 API 支撑模块。
- Lib\site-packages\win32com 下是 COM 的支撑模块。
在 Lib\site-packages 下有一个 PyWin32.CHM 帮助文件,对 Windows 编程有一定基础的看了这个帮助文件就能很快上手。pywin32 把 Windows API 按照功能分了一些大类,每一个大类作为一个模块。以下是所有的模块:
- mmapfile:提供对内存映射文件 API 的访问
- odbc:odb 数据库 api
- perfmon:包装性能监视器功能的模块。
- pywintypes:支持常见 Windows 类型的模块。
- servicemanager:与 Windows 服务控制管理器交互的模块。
- timer:包装 Win32 Timer 函数的扩展
- win2kras:将 Windows 2000 扩展封装到远程访问服务 (RAS) API 的模块。
- win32api:提供了常用的用户API
- win32clipboard:提供了有关粘贴板的API
- win32con:有关的常量。提供了消息常量的操作API。
- win32console:控制台
- win32cred:凭证管理功能的接口。此模块中的功能仅适用于 Windows XP 及更高版本。
- win32crypt:win32 Cryptography API 的接口
- win32event:提供 win32 事件/等待API接口
- win32evtlog:封装了 Windows Win32 事件日志 API。
- win32file:提供了有关文件操作的API
- win32gui:提供了有关 windows 用户界面图形操作的API
- win32help:Win32 API 的帮助
- win32inet:Windows internet (wininet) API 接口
- win32job:win32 进程和线程 API 的接口,在 Windows 2000 及更高版本中可用。
- win32lz:封装 Windows LZ 压缩例程的模块
- win32net:Windows 网络API的模块
- win32pdh:封装 Windows 性能数据帮助 API 模块
- win32pipe:管道 api
- win32print:Windows 打印 API 的模块
- win32process:进程 api
- win32profile:包装用于处理用户配置文件的函数
- win32ras:封装 Windows Remote Access Service (RAS) API
- win32security:win32 安全 API 接口
- win32service:服务
- win32trace
- win32transaction:内核事务管理器函数 模块,用于事务NTFS和事务注册表函数。
- win32ts:此模块中的所有函数都接受关键字参数
- win32wnet:公开 Windows Networking API 的模块。
- winxpgui:xp 图像用户界面 API
比如 文件类 API 就在模块 win32file 中,进程类 API 在模块 win32process 中。在使用的时候,按需导入相关模块就行了,win32con 则定义了所有的常量,几乎是必不可少的,一些难以分类的 API 则在模块 win32api 中(大部分是kernel32.dll导出的API)。
部分模块之间还存在一些交叉,比如 CreateFile 的参数中用到的 GENERIC_READ 常量,在 win32con 中有定义,在 win32file 中也有定义。用户只要大概知道这个是文件 API 用到的常量,那么不管你写 win32file.GENERIC_READ还是 win32con.GENERIC_READ 都是可以的。关闭句柄用的 CloseHandle 函数也是在两个模块中都有定义的。需要注意的是,微软提供的 Wsa 系列网络 API 也都在 win32file 模块中,因为很多操作系统都是把套接字也用为文件对象来操作的。
如果不清楚要使用的 API 在哪个模块中,到 帮助文件 里搜索一下就可以得到答案。
如果对 pywin32 中如何调用某个 API 不熟悉,那么查看 Pywin32.CHM 就足够了,如果对 API 本身的参数定义和使用不熟悉,那还得继续看 MSDN。
3、使用 pywin32 编写 windows 的 GUI
《python 宝典》:https://wenku.baidu.com/view/1f4eb95df011f18583d049649b6648d7c0c70830.html
示例:Helloworld:
示例:创建文件
在 Lib\site-packages\win32\Demos 目录下有很多例子,如果不清楚 pywin32 怎么用,可以看这些例子,比如 使用 API 进行文件操作:
# This is a "demo" of win32file - it used to be more a test case than a
# demo, so has been moved to the test directory.
# Please contribute your favourite simple little demo.
import win32file, win32api, win32con
import os# A very simple demo - note that this does no more than you can do with
# builtin Python file objects, so for something as simple as this, you
# generally *should* use builtin Python objects. Only use win32file etc
# when you need win32 specific features not available in Python.def SimpleFileDemo():testName = os.path.join(win32api.GetTempPath(), "win32file_demo_test_file")if os.path.exists(testName): os.unlink(testName)# Open the file for writing.handle = win32file.CreateFile(testName,win32file.GENERIC_WRITE,0,None,win32con.CREATE_NEW,0,None)test_data = "Hello\0there".encode("ascii")win32file.WriteFile(handle, test_data)handle.Close()# Open it for reading.handle = win32file.CreateFile(testName, win32file.GENERIC_READ, 0, None, win32con.OPEN_EXISTING, 0, None)rc, data = win32file.ReadFile(handle, 1024)handle.Close() # 此处也可使用win32file.CloseHandle(handle)来关闭句柄if data == test_data:print("Successfully wrote and read a file")else:raise Exception("Got different data back???")os.unlink(testName)if __name__ == '__main__':SimpleFileDemo()
点击 鼠标
win32gui 和 win32ui :从字面意思来看,一个是 gui(图形用户接口),一个是 ui (用户接口),但是看不出有什么区别,查看源码也没发现有什么说明。
示例:
import win32gui, win32api, win32con
# 获取鼠标当前位置的坐标
win32api.GetCursorPos()
# 将鼠标移动到坐标处
win32api.SetCursorPos((200, 200))
# 左点击
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 200, 200, 0, 0)
win32api.mouse_event(win32con.MUOSEEVENTF_LEFTUP, 200, 200, 0, 0)
# 获取窗口句柄
win32gui.FindWindow(None, 'qq')
win32gui.FindWindow('TXGuiFoundation', None)
# 通过坐标获取窗口句柄
hw = win32api.WindowFromPoint(win32api.GetCursorPos())
# 获取窗口classname
win32gui.GetClassName(hw)
# 获取窗口标题
win32gui.GetWindowText(hw)
# 获取窗口坐标
win32gui.GetwindowRect(hw)
通过窗口标题获取句柄
import win32guihld = win32gui.FindWindow(None,u"Adobe Acrobat") #返回窗口标题为Adobe Acrobat的句柄
通过父窗口句柄获取子句柄
#parent为父窗口句柄id
def get_child_windows(parent):'''获得parent的所有子窗口句柄返回子窗口句柄列表'''if not parent:returnhwndChildList = []win32gui.EnumChildWindows(parent, lambda hwnd, param: param.append(hwnd), hwndChildList)return hwndChildList
根据句柄获取句柄标题和类名
import win32guititle = win32gui.GetWindowText(jbid) #jbid为句柄id
#获取标题
clsname = win32gui.GetClassName(jbid)
#获取类名
根据句柄获取窗口位置
import win32gui
left, top, right, bottom = win32gui.GetWindowRect(jbid)
#分别为左、上、右、下的窗口位置
根据句柄进行点击操作
import win32api,win32conwin32api.SetCursorPos([横坐标, 纵坐标])
#根据横纵坐标定位光标
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP | win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
#给光标定位的位置进行单击操作(若想进行双击操作,可以延时几毫秒再点击一次)
win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTUP | win32con.MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0)
#给光标定位的位置进行右击操作
根据句柄将窗口放在最前
win32gui.SetForegroundWindow(jbid)
查找窗体句柄
在 win32 编程的世界里,包括 "窗口、文本框 等所有控件" 都是 窗体,所有的窗体都有独立的句柄。要操作任意一个窗体,你都需要找到这个窗体的句柄,这里,可以用到 FindWindow函数和FindWindowEx函数。在 pywin32 中,他们都属于 win32gui 的模块。
FindWindow(lpClassName=None, lpWindowName=None):
描述:自顶层窗口(也就是桌面)开始搜索条件匹配的窗体,并返回这个窗体的句柄。不搜索子窗口、不区分大小写。找不到就返回0
参数:
lpClassName:字符型,是窗体的类名,这个可以在Spy++里找到。
lpWindowName:字符型,是窗口名,也就是标题栏上你能看见的那个标题。
说明:这个函数我们仅能用来找主窗口。
示例代码 1 (获取所有窗口句柄。使用 win32gui 模块) :
import win32guititles = set()def foo(hwnd, mouse):# 去掉下面这句就所有都输出了,但是我不需要那么多if win32gui.IsWindow(hwnd) and win32gui.IsWindowEnabled(hwnd) and win32gui.IsWindowVisible(hwnd):titles.add(win32gui.GetWindowText(hwnd))def test():win32gui.EnumWindows(foo, 0)lt = [t for t in titles if t]lt.sort()for t in lt:print(t)if __name__ == '__main__':test()
import win32guihwnd_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 t is not "":print(h, t)
示例代码 2 :( 使用 win32ui 模块)
import win32uidef test():dlg = win32ui.CreateFileDialog(1) # 1表示打开文件对话框dlg.SetOFNInitialDir('E:/Python') # 设置打开文件对话框中的初始显示目录dlg.DoModal()filename = dlg.GetPathName() # 获取选择的文件名称print(filename)if __name__ == '__main__':test()
示例代码 3:
import win32api
import win32con
import win32gui
import win32ui
import win32console
import win32process
import os
import signalMAIN_HWND = 0def is_win_ok(hwnd, starttext):s = win32gui.GetWindowText(hwnd)if starttext in s:print(s)global MAIN_HWNDMAIN_HWND = hwndreturn Nonereturn 1def find_main_window(starttxt):global MAIN_HWNDwin32gui.EnumChildWindows(0, is_win_ok, starttxt)return MAIN_HWNDdef winfun(hwnd, lparam):s = win32gui.GetWindowText(hwnd)if len(s) > 3:print("winfun, child_hwnd: %d txt: %s" % (hwnd, s))return 1if __name__ == '__main__':os.system('start cmd')window_title = 'C:\Windows\system32\cmd.exe'window_handle = win32gui.FindWindow(None, window_title)window_handle_title = win32gui.GetWindowText(window_handle)window_handle_class_name = win32gui.GetClassName(window_handle)print(window_handle_title)print(window_handle_class_name)win32gui.CloseWindow(window_handle) # 窗口最小化win32gui.SendMessage(window_handle, win32con.WM_CLOSE) # 关闭窗口# win32api.SetCursorPos([0, 0]) # 设置 鼠标 位置file_path = './test.txt'with open(file_path, 'w+') as f:passos.system('start {0}'.format(file_path))main_app = 'test.txt - 记事本'hwnd = win32gui.FindWindow(None, main_app)win32gui.CloseWindow(hwnd) # 窗口最小化print(win32gui.GetWindowText(hwnd))print(type(hwnd))print(hwnd)if hwnd < 1:hwnd = find_main_window(main_app)print(type(hwnd))print(hwnd)if hwnd:win32gui.EnumChildWindows(hwnd, winfun, None)thread, processId = win32process.GetWindowThreadProcessId(hwnd)print(thread)# print(processId, signal.CTRL_BREAK_EVENT)# os.kill(processId, signal.CTRL_C_EVENT)# os.kill(processId, signal.CTRL_BREAK_EVENT)# Shows or hides a window and changes its statewin32gui.ShowWindow(hwnd, 0)# win32gui.HideCaret(hwnd)
示例代码 4:
import win32gui
import win32con
import win32api
import win32process
import osspider_config_count = dict(mao_yan_spider=10,tao_piao_piao_spider=10,
)# 保存 句柄 和 句柄 title。 示例 { 100 : 'C:\Windows\system32\cmd.exe'}
handle_title_dict = dict()# 通过 spider_config_count 生成 keyword_list。
keyword_list = list()# 每个 spider 对应的数量
spider_count_dict = dict()# 所有 进程 对应的数量
process_count_dict = dict()for temp_k, temp_v in spider_config_count.items():keyword_list.append(temp_k)def get_windows_handle(hwnd, mouse):if win32gui.IsWindow(hwnd) and win32gui.IsWindowEnabled(hwnd) and win32gui.IsWindowVisible(hwnd):handle_title_dict.update({hwnd: win32gui.GetWindowText(hwnd)})def get_all_windows_handle():win32gui.EnumWindows(get_windows_handle, 0)for k, v in handle_title_dict.items():# print('{0} : {1}'.format(k, v))passdef close_process():# for k, v in WINDOWS_HANDLE_DICT.items():# # print('{0} : {1}'.format(k, v))# if WINDOWS_HANDLE_DICT[k] in WINDOWS_HANDLE_TITLE_LIST:# print('{0} : {1}'.format(k, v))passdef display_all_spider_count():for k, v in handle_title_dict.items():if handle_title_dict[k]:for keyword in keyword_list:if keyword in v:if not spider_count_dict.get(keyword):spider_count_dict[keyword] = 1else:spider_count_dict[keyword] += 1for k, v in spider_count_dict.items():print('{0} : {1}'.format(k, v))def display_all_process_count():for k, v in handle_title_dict.items():if handle_title_dict[k]:if not process_count_dict.get(v):process_count_dict[v] = 1else:process_count_dict[v] += 1for k, v in process_count_dict.items():print('{0} : {1}'.format(k, v))passdef monitoring_spider_count():pan = 'E:'# spider_path = 'PythonSpider/maoyan'spider_path = 'PythonSpider/taopiaopiaoSpider'for k, v in spider_config_count.items():# for k_2, v_2 in spider_count_dict:if spider_count_dict.get(k):if spider_count_dict[k] < v:count = v - spider_count_dict[k]# win_cmd = 'for /L %i in (1,1,5) do start cmd /k "e: && cd PythonSpider" 'win_cmd = 'for /L %i in (1,1,{0}) do start cmd /k "{1} && cd {2} && scrapy crawl {3}"'.format(count, pan, spider_path, k)os.system(win_cmd)else:count = vwin_cmd = 'for /L %i in (1,1,{0}) do start cmd /k "{1} && cd {2} && scrapy crawl {3}"'.format(count, pan, spider_path, k)os.system(win_cmd)passdef test():get_all_windows_handle()for k, v in handle_title_dict.items():# print('{0} : {1}'.format(k, v))if handle_title_dict[k] == '无标题 - 记事本':print('{0} : {1}'.format(k, v))# 如果记事本有 内容未保存,win32gui.SendMessage(k, win32con.WM_CLOSE) 这个无法关闭# win32gui.SendMessage(k, win32con.WM_CLOSE)# 终止进程 方式 可以关闭记事本中有内容未保存thread_id, process_id = win32process.GetWindowThreadProcessId(k)p_handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, 0, process_id)win32api.TerminateProcess(p_handle, process_id)win32api.CloseHandle(p_handle)get_all_windows_handle()def test_2():win_cmd = 'for /L %i in (1,1,5) do start cmd /k "e: && cd PythonSpider" 'os.system(win_cmd)if __name__ == '__main__':# display_all_spider_count()display_all_process_count()# monitoring_spider_count()pass
窗口句柄 发送消息 常用方法 键盘输入
python win32api win32gui win32con
推荐微软的 Spy++ (下载地址:https://download.csdn.net/download/freeking101/11002997)来查看窗口类名等信息。
# -*- coding:utf-8 -*-import time
import win32gui
import win32con
import win32api# 从顶层窗口向下搜索主窗口,无法搜索子窗口
# FindWindow(lpClassName=None, lpWindowName=None) 窗口类名 窗口标题名
handle = win32gui.FindWindow("Notepad", None)# 获取窗口位置
left, top, right, bottom = win32gui.GetWindowRect(handle)
# 获取某个句柄的类名和标题
title = win32gui.GetWindowText(handle)
cls_name = win32gui.GetClassName(handle)# 打印句柄
print(handle)
print(cls_name)# 搜索子窗口
# 枚举子窗口
hwndChildList = []
win32gui.EnumChildWindows(handle, lambda hwnd, param: param.append(hwnd), hwndChildList)# 父窗口句柄 若不为0,则按照z-index的顺序从hwndChildAfter向后开始搜索子窗体,否则从第一个子窗体开始搜索。 子窗口类名 子窗口标题
# FindWindowEx(hwndParent=0, hwndChildAfter=0, lpszClass=None, lpszWindow=None)
subHandle = win32gui.FindWindowEx(handle, 0, "EDIT", None)# 获得窗口的菜单句柄
menuHandle = win32gui.GetMenu(subHandle)
# 获得子菜单或下拉菜单句柄
# 参数:菜单句柄 子菜单索引号
subMenuHandle = win32gui.GetSubMenu(menuHandle, 0)
# 获得菜单项中的的标志符,注意,分隔符是被编入索引的
# 参数:子菜单句柄 项目索引号
menuItemHandle = win32gui.GetMenuItemID(subMenuHandle, 0)
# 发送消息,加入消息队列,无返回
# 参数:句柄 消息类型 WParam IParam
win32gui.postMessage(subHandle, win32con.WM_COMMAND, menuItemHandle, 0)# wParam的定义是32位整型,high word就是他的31至16位,low word是它的15至0位。
# 当参数超过两个,wParam和lParam不够用时,可以将wParam就给拆成两个int16来使用。
# 这种时候在python里记得用把HIWORD的常数向左移16位,再加LOWORD,即wParam = HIWORD<<16+LOWORD。# 下选框内容更改
# 参数:下选框句柄; 消息内容; 参数下选框的哪一个item,以0起始的待选选项的索引;如果该值为-1,将从组合框列表中删除当前选项,并使当前选项为空; 参数
# CB_Handle为下选框句柄,PCB_handle下选框父窗口句柄
if win32api.SendMessage(CB_handle, win32con.CB_SETCURSEL, 1, 0) == 1:# 下选框的父窗口命令# 参数:父窗口句柄; 命令; 参数:WParam:高位表示类型,低位表示内容;参数IParam,下选框句柄# CBN_SELENDOK当用户选择了有效的列表项时发送,提示父窗体处理用户的选择。 LOWORD为组合框的ID. HIWORD为CBN_SELENDOK的值。win32api.SendMessage(PCB_handle, win32con.WM_COMMAND, 0x90000, CB_handle)# CBN_SELCHANGE当用户更改了列表项的选择时发送,不论用户是通过鼠标选择或是通过方向键选择都会发送此通知。LOWORD为组合框的ID. HIWORD为CBN_SELCHANGE的值。win32api.SendMessage(PCB_handle, win32con.WM_COMMAND, 0x10000, CB_handle)# 设置文本框内容,等窗口处理完毕后返回true。中文需编码成gbk
# 参数:句柄;消息类型;参数WParam,无需使用; 参数IParam,要设置的内容,字符串
win32api.SendMessage(handle, win32con.WM_SETTEXT, 0, os.path.abspath(fgFilePath).encode('gbk'))# 控件点击确定,处理消息后返回0
# 参数:窗口句柄; 消息类型; 参数WParam HIWORD为0(未使用),LOWORD为控件的ID; 参数IParam 0(未使用),确定控件的句柄
win32api.SendMessage(Mhandle, win32con.WM_COMMAND, 1, confirmBTN_handle)# 获取窗口文本不含截尾空字符的长度
# 参数:窗口句柄; 消息类型; 参数WParam; 参数IParam
bufSize = win32api.SendMessage(subHandle, win32con.WM_GETTEXTLENGTH, 0, 0) + 1
# 利用api生成Buffer
strBuf = win32gui.PyMakeBuffer(bufSize)
print(strBuf)
# 发送消息获取文本内容
# 参数:窗口句柄; 消息类型;文本大小; 存储位置
length = win32gui.SendMessage(subHandle, win32con.WM_GETTEXT, bufSize, strBuf)
# 反向内容,转为字符串
# text = str(strBuf[:-1])address, length = win32gui.PyGetBufferAddressAndLen(strBuf)
text = win32gui.PyGetString(address, length)
# print('text: ', text)# 鼠标单击事件
# 鼠标定位到(30,50)
win32api.SetCursorPos([30, 150])
# 执行左单键击,若需要双击则延时几毫秒再点击一次即可
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP | win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
# 右键单击
win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTUP | win32con.MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0)def click1(x, y): # 第一种win32api.SetCursorPos((x, y))win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, x, y, 0, 0)win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, x, y, 0, 0)def click2(x, y): # 第二种ctypes.windll.user32.SetCursorPos(x, y)ctypes.windll.user32.mouse_event(2, 0, 0, 0, 0)ctypes.windll.user32.mouse_event(4, 0, 0, 0, 0)def click_it(pos): # 第三种handle = win32gui.WindowFromPoint(pos)client_pos = win32gui.ScreenToClient(handle, pos)tmp = win32api.MAKELONG(client_pos[0], client_pos[1])win32gui.SendMessage(handle, win32con.WM_ACTIVATE, win32con.WA_ACTIVE, 0)win32gui.SendMessage(handle, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, tmp)win32gui.SendMessage(handle, win32con.WM_LBUTTONUP, win32con.MK_LBUTTON, tmp)# 发送回车
win32api.keybd_event(13, 0, 0, 0)
win32api.keybd_event(13, 0, win32con.KEYEVENTF_KEYUP, 0)# 关闭窗口
win32gui.PostMessage(win32lib.findWindow(classname, titlename), win32con.WM_CLOSE, 0, 0)# 检查窗口是否最小化,如果是最大化
if win32gui.IsIconic(hwnd):# win32gui.ShowWindow(hwnd, win32con.SW_SHOWNORMAL)win32gui.ShowWindow(hwnd, 8)time.sleep(0.5)# SW_HIDE:隐藏窗口并激活其他窗口。nCmdShow=0。
# SW_MAXIMIZE:最大化指定的窗口。nCmdShow=3。
# SW_MINIMIZE:最小化指定的窗口并且激活在Z序中的下一个顶层窗口。nCmdShow=6。
# SW_RESTORE:激活并显示窗口。如果窗口最小化或最大化,则系统将窗口恢复到原来的尺寸和位置。在恢复最小化窗口时,应用程序应该指定这个标志。nCmdShow=9。
# SW_SHOW:在窗口原来的位置以原来的尺寸激活和显示窗口。nCmdShow=5。
# SW_SHOWDEFAULT:依据在STARTUPINFO结构中指定的SW_FLAG标志设定显示状态,STARTUPINFO 结构是由启动应用程序的程序传递给CreateProcess函数的。nCmdShow=10。
# SW_SHOWMAXIMIZED:激活窗口并将其最大化。nCmdShow=3。
# SW_SHOWMINIMIZED:激活窗口并将其最小化。nCmdShow=2。
# SW_SHOWMINNOACTIVE:窗口最小化,激活窗口仍然维持激活状态。nCmdShow=7。
# SW_SHOWNA:以窗口原来的状态显示窗口。激活窗口仍然维持激活状态。nCmdShow=8。
# SW_SHOWNOACTIVATE:以窗口最近一次的大小和状态显示窗口。激活窗口仍然维持激活状态。nCmdShow=4。
# SW_SHOWNORMAL:激活并显示一个窗口。如果窗口被最小化或最大化,系统将其恢复到原来的尺寸和大小。应用程序在第一次显示窗口的时候应该指定此标志。nCmdShow=1。
win32 虽然也可控制键盘,但不如使用 PyUserInput 的方便。需要注意在 windows 和 mac 下接口参数可能有所不同
# win32虽然也可控制键盘,但不如使用PyUserInput的方便。
# 需要注意在windows和mac下接口参数可能有所不同。
from pymouse import PyMouse
from pykeyboard import PyKeyboard
m = PyMouse()
k = PyKeyboard()x_dim, y_dim = m.screen_size()
# 鼠标点击
m.click(x_dim/2, y_dim/2, 1)
# 键盘输入
k.type_string('Hello, World!')# 按住一个键
k.press_key('H')
# 松开一个键
k.release_key('H')
# 按住并松开,tap一个键
k.tap_key('e')
# tap支持重复的间歇点击键
k.tap_key('l',n=2,interval=5)
# 发送判断文字
k.type_string('123456')#创建组合键
k.press_key(k.alt_key)
k.tap_key(k.tab_key)
k.release_key(k.alt_key)
# 特殊功能键
k.tap_key(k.function_keys[5]) # Tap F5
k.tap_key(k.numpad_keys['Home']) # Tap 'Home' on the numpad
k.tap_key(k.numpad_keys[5], n=3) # Tap 5 on the numpad, thrice# Mac系统
k.press_keys(['Command','shift','3'])
# Windows系统
k.press_keys([k.windows_l_key,'d'])# 其中的 PyMouseEvent 和 PyKeyboardEvent 还可用于监听鼠标和键盘事件的输入
Python 鼠标、键盘
pynput 文档:https://pythonhosted.org/pynput/index.html
安装:pip install pynput
pynput 这个库让你可以控制和监控输入设备。
对于每一种输入设备,它包含一个子包来控制和监控该种输入设备:
- pynput.mouse:包含控制和监控鼠标或者触摸板的类。
- pynput.keyboard:包含控制和监控键盘的类。
地址:https://pypi.python.org/pypi/pynput
基本用法介绍:
from pynput.mouse import Button, Controller
import timemouse = Controller()
print(mouse.position)
time.sleep(3)
print('The current pointer position is {0}'.format(mouse.position))# set pointer positon
mouse.position = (277, 645)
print('now we have moved it to {0}'.format(mouse.position))# 鼠标移动(x,y)个距离
mouse.move(5, -5)
print(mouse.position)mouse.press(Button.left)
mouse.release(Button.left)# Double click
mouse.click(Button.left, 1)# scroll two steps down
mouse.scroll(0, 500)
监控鼠标事件 :
from pynput import mousedef on_move(x, y):print('Pointer moved to {o}'.format((x, y)))def on_click(x, y, button, pressed):print('{0} at {1}'.format('Pressed' if pressed else 'Released', (x, y)))if not pressed:return Falsedef on_scroll(x, y, dx, dy):print('scrolled {0} at {1}'.format('down' if dy < 0 else 'up',(x, y)))while True:with mouse.Listener(no_move=on_move, on_click=on_click, on_scroll=on_scroll) as listener:listener.join()
键盘输入用法:
from pynput.keyboard import Key, Controllerkeyboard = Controller()
# 按下空格和释放空格
# Press and release space
keyboard.press(Key.space)
keyboard.release(Key.space)
# 按下a键和释放a键
# Type a lower case A ;this will work even if no key on the physical keyboard is labelled 'A'
keyboard.press('a')
keyboard.release('a')# Type two upper case As
keyboard.press('A')
keyboard.release('A')
# or
with keyboard.pressed(Key.shift):keyboard.press('a')keyboard.release('a')# type 'hello world ' using the shortcut type method
keyboard.type('hello world')
键盘监听:
from pynput import keyboarddef on_press(key):try:print('alphanumeric key {0} pressed'.format(key.char))except AttributeError:print('special key {0} pressed'.format(key))def on_release(key):print('{0} released'.format(key))if key == keyboard.Key.esc:return Falsewhile True:with keyboard.Listener(on_press=on_press,on_release=on_release) as listener:listener.join()
按键记录器
# -*- coding:utf-8 -*-
import time
from pynput.keyboard import Key, Controller, Listenerkeyboard = Controller()
keys = []def on_press(key):string = str(key).replace("'", "")def on_release(key):global keysstring = str(key).replace("'", "")keys.append('\r' + string)main_string = "".join(keys)print(main_string)if len(main_string) > 15:with open('D:\keys.txt', 'a') as f:f.write(main_string)keys = []def write_to_file(key):letter = str(key)letter = letter.replace("'", "")with open("./log.txt", 'a') as f:f.write(letter)if __name__ == '__main__':# with Listener(on_press=write_to_file) as listener:# listener.join()with Listener(on_press=on_press, on_release=on_release) as listener:listener.join()pass
Python 编写简易木马程序
:https://blog.csdn.net/weixin_34405261/article/details/113554335
win32process
# -*- coding:utf-8 -*-import psutil
import win32gui
import win32process
from ctypes import *user32 = windll.user32
kernel32 = windll.kernel32
ps_api = windll.psapi
current_window = Nonedef func_test_window():app = win32gui.GetWindowText(67526)if win32gui.IsWindowVisible(67526) and win32gui.IsWindowEnabled(67526):thread_id, process_id = win32process.GetWindowThreadProcessId(67526)process = psutil.Process(process_id)print(process.name(), process_id)proc = psutil.Process(pid=process_id)print(proc.name())print(app)def get_current_process():# 获取最上层的窗口句柄hwnd = user32.GetForegroundWindow()# 获取进程 idpid = c_ulong(0)user32.GetWindowThreadProcessId(hwnd, byref(pid))# 将进程ID 存入变量中process_id = pid.value# 申请内存char_array = create_string_buffer(b"0" * 512)h_process = kernel32.OpenProcess(0x400 | 0x10, False, pid)ps_api.GetModuleBaseNameA(h_process, None, byref(char_array), 512)# 读取窗口标题window_title = create_string_buffer(b"0" * 512)length = user32.GetWindowTextA(hwnd, byref(window_title), 512)print(f"PID:{process_id} - {char_array.value} - {window_title.value}")# 关闭 handleskernel32.CloseHandle(hwnd)kernel32.CloseHandle(h_process)passif __name__ == '__main__':get_current_process()pass
Python MFC GUI
使用 pywin32编写 windows的GUI (《python 宝典》)
:https://wenku.baidu.com/view/1f4eb95df011f18583d049649b6648d7c0c70830.html
Python win32 库进行内存读写
Python win32库进行内存读写:
- 游戏辅助:https://www.jianshu.com/p/0bddab537860
- 植物大战僵尸 辅助:https://www.jianshu.com/p/ee890eb0d8d6
:https://tieba.baidu.com/p/1297024013?red_tag=3286293802
Python 游戏辅助
:https://www.jianshu.com/u/dd32b7845ea9
4、python 找图 找色
一文讲透,经典Python图像处理库,带你领略Pillow的强大魅力:https://baijiahao.baidu.com/s?id=1730140116378756711
关键字:python 找图 找色 || win32gui win32api win32con
python 能做类似于按键精灵 那种桌面找图返回坐标么?:https://www.52pojie.cn/thread-1432042-1-1.html
Python实现按键精灵(二) - 找图找色:https://www.bbsmax.com/A/amd0KBKj5g/
python 操作 winAPI:https://www.cnblogs.com/liming19680104/p/11988565.html
关键字:Python GetWindowThreadProcessId
Python 实现按键精灵找色点击功能,使用 pywin32 和 Pillow 库:https://blog.csdn.net/lrnboy/article/details/85227548