赞
踩
PyWin32是Python在Windows平台上的一个扩展库,提供了访问Windows API、COM接口和其他Windows原生功能的功能。它允许开发者使用Python语言来编写与Windows操作系统交互的应用程序。
通过PyWin32,开发者可以利用Python的简洁和灵活性,与Windows系统进行无缝交互,编写各种应用程序、脚本和自动化工具。无论是系统管理、GUI开发还是与其他Windows应用程序集成,PyWin32都提供了强大的功能和工具,使得Python在Windows平台上的应用开发更加便捷和高效。
该项目地址是:GitHub - mhammond/pywin32: Python for Windows (pywin32) Extensions
在Python安装路径下\AppData\Local\Programs\Python\Python38\Lib\site-packages 有帮助文档:PyWin32.chm
文件类API在模块win32file中,进程类API在模块win32process中,win32con定义了所有的常量,,一些难以分类的API则在模块win32api中(大部分是kernel32.dll导出的API)
ctypes 调用C库printf打印输出
- >>> import ctypes
- >>> # cdll = cdecl标准 windll = stdcall标准 linux则是调用 libc.so.6
- >>> msvcrt = ctypes.cdll.LoadLibrary("C:\WINDOWS\system32\msvcrt.dll")
- >>> msvcrt = ctypes.cdll.msvcrt
- >>>
- >>> string = "hello lyshark\n"
- >>> string = string.encode("utf-8")
- >>> msvcrt.printf(string)
- hello lyshark
- 14
ctypes 调用messagebox输出:
- >>> from ctypes import *
- >>> user32 = windll.LoadLibrary("user32.dll")
- >>> string = "Hello lyshark\n"
- >>> string = string.encode("utf-8")
- >>>
- >>>user32.MessageBoxA(0,string,"ctypes".encode("utf-8"),0)
- >>>
- >>>user32 = windll.LoadLibrary("user32.dll")
- >>>MessageBox = user32.MessageBoxA
- >>>print(MessageBox(0,"hello lyshark".encode("utf-8"),"msgbox".encode("utf-8"),0))
ctypes 调用 kernel32
- >>> kernel32 = windll.LoadLibrary("kernel32.dll")
- >>> CreateProcess = kernel32.CreateProcessA
- >>> ReadProcessMemory = kernel32.ReadProcessMemory
ctypes 声明结构体
- from ctypes import *
-
- class MyStruct(Structure):
- _fields_ = [
- ("username",c_char*10),
- ("age",c_int),
- ("sex",c_long)
- ]
- class MyUnion(Union):
- _fields_ = [
- ("a_long",c_long),
- ("a_int",c_int),
- ("a_char",c_char*10)
- ]
-
- MyStruct.username = "lyshark"
- MyStruct.age = 22
-
- print(MyStruct.username)
pywin32常用使用方式
- >>> import win32api
- >>> import win32con
- >>>
- >>> win32api.MessageBox(0,"hello lyshark","Msgbox",win32con.MB_OK)
- 1
- >>> import win32process
- # 打开记事本程序,获得其句柄
- >>> handle = win32process.CreateProcess('c:\\windows\\notepad.exe',
- '', None , None , 0 ,win32process. CREATE_NO_WINDOW , None , None ,
- win32process.STARTUPINFO())
- # 使用TerminateProcess函数终止记事本程序
- >>> win32process.TerminateProcess(handle[0],0)
-
- >>> import win32event
- # 创建进程获得句柄
- >>> handle = win32process.CreateProcess('c:\\windows\\notepad.exe',
- '', None , None , 0 ,win32process. CREATE_NO_WINDOW , None , None ,
- win32process.STARTUPINFO())
- # 等待进程结束
- >>> win32event.WaitForSingleObject(handle[0], -1)
- 0 # 进程结束的返回值
-
- >>> import win32api
- # 打开记事本程序,在后台运行,即显示记事本程序的窗口
- >>> win32api.ShellExecute(0, 'open', 'notepad.exe', '','',0)
鼠标控制
- import win32gui
- import win32api
-
- 获取句柄
- hwnd = win32gui.FindWindow(classname, titlename)
-
- 获取窗口左上角和右下角坐标
- left, top, right, bottom = win32gui.GetWindowRect(hwnd)
-
- 获取某个句柄的类名和标题
- title = win32gui.GetWindowText(hwnd)
- clsname = win32gui.GetClassName(hwnd)
-
- 获取父句柄hwnd类名为clsname的子句柄
- hwnd1= win32gui.FindWindowEx(hwnd, None, clsname, None)
-
- 获取位置
- win32api.GetCursorPos()
-
- 鼠标定位到(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)
-
- 发送回车键
- 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)
鼠标左右键判断
- import win32api
- import win32con
- b = (0,0)
-
- # win32api.GetAsyncKeyState(win32con.VK_LMENU)
-
- # VK_LBUTTON 鼠标左键
- # VK_RBUTTON 鼠标右键
- # https://baike.baidu.com/item/GetAsyncKeyState/918387?fr=aladdin
-
- for i in range(100):
- a = win32api.GetCursorPos()
- if a != b:
- b = a
- print(a)
- else:
- print("xx")
- time.sleep(1)
将上面代码有趣的组合在一起,可以搞事情了,部分片段。
- def Write_Dictionaries(LogName,Dict):
- logging.basicConfig(level=logging.DEBUG,
- format = "%(asctime)s --> %(message)s",
- datefmt = "%Y-%m-%d %H:%M:%S",
- filename = LogName,
- filemode = "a+")
- logging.info(str(Dict))
-
- def RecordingScript(LogName,Sleep):
- temp = (0,0)
- mose = {"Pos_x":0, "Pos_y":0, "MouseL":0, "MouseR":0}
- while True:
- Position = win32api.GetCursorPos()
- MouseLeft = win32api.GetAsyncKeyState(win32con.VK_LBUTTON)
- MouseRight = win32api.GetAsyncKeyState(win32con.VK_RBUTTON)
-
- if Position != temp or MouseLeft!=0 or MouseRight!=0:
- temp = Position
- mose["Pos_x"] = Position[0]
- mose["Pos_y"] = Position[1]
- mose["MouseL"] = MouseLeft
- mose["MouseR"] = MouseRight
- Write_Dictionaries(LogName,mose)
- time.sleep(int(Sleep))
-
- def writelog():
- with open("aaa.log","r",encoding="utf-8") as fp:
- b = [ item.split(" --> ")[1] for item in fp.readlines()]
- for i in b:
- dic = eval(i.replace("\n",""))
- win32api.SetCursorPos(bos)
- print("坐标:{}".format(bos))
遍历进程模块
- import os,sys
- import win32api
- import win32con
- import win32process
-
- handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, False, pid ===> 10992 )
- hModule = win32process.EnumProcessModules(handle)
- temp=[]
- for i in hModule:
- print(win32process.GetModuleFileNameEx(handle,i))
- win32api.CloseHandle(handle)
调用createprocess
- CreateProcess调用
-
- appName:可执行的文件名。
- commandLine:命令行参数。
- processAttributes:进程安全属性,如果为None,则为默认的安全属性。
- threadAttributes:线程安全属性,如果为None,则为默认的安全属性。
- bInheritHandles:继承标志。
- dwCreationFlags:创建标志。
- newEnvironment:创建进程的环境变量。
- currentDirectory:进程的当前目录。
- startupinfo :创建进程的属性。
-
- WaitForSingleObject(handle, milisecond)
-
- handle : 要操作的进程句柄
- milisecond: 等待的时间,如果为-1,则一直等待.
-
- >>> import win32process
- >>> handle=win32process.CreateProcess("d://run.exe", '', None , None , 0 ,win32process.CREATE_NEW_CONSOLE , None , None ,win32process.STARTUPINFO())
- >>> win32event.WaitForSingleObject(handle[0],2)
枚举部分进程模块
- import win32process
- import win32api
- import win32con
- from ctypes import *
- import ctypes
-
- def GetProcessModules( pid ):
- handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, False, pid )
- hModule = win32process.EnumProcessModules(handle)
- temp=[]
- for i in hModule:
- temp.append([hex(i),win32process.GetModuleFileNameEx(handle,i)])
- win32api.CloseHandle(handle)
- return temp
-
- temp = GetProcessModules(5852)
- for x in temp:
- print("[+] 模块地址: {} ------> 模块名称: {}".format(x[0],x[1]))
取出进程PID
- handle = win32gui.FindWindow(0,ClassName)
- threadpid, procpid = win32process.GetWindowThreadProcessId(handle)
- ProcessModule = GetProcessModules(int(procpid))
枚举所有窗口句柄
- import win32gui
-
- 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():
- print(h, t)
打开网页或文件
- win32api.ShellExecute(None, "open", "C:\\Test.txt", None, None, SW_SHOWNORMAL) # 打开C:\Test.txt 文件
- win32api.ShellExecute(None, "open", "http:#www.google.com", None, None, SW_SHOWNORMAL) # 打开网页www.google.com
- win32api.ShellExecute(None, "explore", "D:\\C++", None, None, SW_SHOWNORMAL) # 打开目录D:\C++
- win32api.ShellExecute(None, "print", "C:\\Test.txt", None, None, SW_HIDE) # 打印文件C:\Test.txt
- win32api.ShellExecute(None,"open", "mailto:", None, None, SW_SHOWNORMAL) # 打开邮箱
- win32api.ShellExecute(None, "open", "calc.exe", None, None, SW_SHOWNORMAL) # 调用计算器
- win32api.ShellExecute(None, "open", "NOTEPAD.EXE", None, None, SW_SHOWNORMAL) # 调用记事本
窗口句柄操作
- import time
- import win32gui
- import win32api
- import win32con
-
- """
- 该类实现了:查找(定位)句柄信息,菜单信息
- """
- class HandleMenu(object):
-
- def __init__(self, cls_name=None, title=None):
-
- self.handle = win32gui.FindWindow(cls_name, title)
- self.window_list = []
-
- def call_back(self, sub_handle, sub_handles): # Edit 20de0
- """遍历子窗体"""
-
- title = win32gui.GetWindowText(sub_handle)
- cls_name = win32gui.GetClassName(sub_handle)
- print(title, '+', cls_name)
-
- position = win32gui.GetWindowRect(sub_handle)
- aim_point = round(position[0] + (position[2] - position[0]) / 2), round(
- position[1] + (position[3] - position[1]) / 2)
- win32api.SetCursorPos(aim_point)
- time.sleep(1)
-
- # 鼠标点击
- # win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0)
- # time.sleep(0.05)
- # win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0)
- # time.sleep(0.05)
- # ComboBox - ---------
- # Edit - ---------
- if cls_name == 'ComboBox':
- win32gui.SendMessage(sub_handle, win32con.WM_SETTEXT, None, '902723')
- time.sleep(1)
- sub_handles.append({'cls_name': cls_name, 'title': title})
-
- return True
-
- def get_sub_handles(self):
- """通过父句柄获取子句柄"""
-
- sub_handles = []
- win32gui.EnumChildWindows(self.handle, self.call_back, sub_handles)
- print(sub_handles)
- return sub_handles
-
- def get_menu_text(self, menu, idx):
- import win32gui_struct
- mii, extra = win32gui_struct.EmptyMENUITEMINFO() # 新建一个win32gui的空的结构体mii
- win32gui.GetMenuItemInfo(menu, idx, True, mii) # 将子菜单内容获取到mii
- ftype, fstate, wid, hsubmenu, hbmpchecked, hbmpunchecked, \
- dwitemdata, text, hbmpitem = win32gui_struct.UnpackMENUITEMINFO(mii) # 解包mii
- return text
-
- def get_menu(self):
- """menu操作(记事本)"""
-
- menu = win32gui.GetMenu(self.handle)
- menu1 = win32gui.GetSubMenu(menu, 0) # 第几个菜单 0-第一个
- cmd_ID = win32gui.GetMenuItemID(menu1, 3) # 第几个子菜单
- win32gui.PostMessage(self.handle, win32con.WM_COMMAND, cmd_ID, 0)
- menu_text1 = [self.get_menu_text(menu, i) for i in range(5)]
- menu_text2 = [self.get_menu_text(menu1, i) for i in range(9)]
-
- print(menu_text1)
- print(menu_text2)
-
- def get_all_window_info(self, hwnd, nouse):
-
- # 去掉下面这句就所有都输出了,但是我不需要那么多
- if win32gui.IsWindow(hwnd) and win32gui.IsWindowEnabled(hwnd) and win32gui.IsWindowVisible(hwnd):
- # 设置为最前窗口
- win32gui.SetForegroundWindow(hwnd)
- # 获取某个句柄的标题和类名
- title = win32gui.GetWindowText(hwnd)
- cls_name = win32gui.GetClassName(hwnd)
- d = {'类名': cls_name, '标题': title}
- info = win32gui.GetWindowRect(hwnd)
- aim_point = round(info[0] + (info[2] - info[0]) / 2), round(info[1] + (info[3] - info[1]) / 2)
- win32api.SetCursorPos(aim_point)
- time.sleep(2)
- self.window_list.append(d)
-
- def get_all_windows(self):
- """获取所有活动窗口的类名、标题"""
- win32gui.EnumWindows(self.get_all_window_info, 0)
- return self.window_list
-
- if __name__ == '__main__':
- # 1.通过父句柄获取子句柄
- # hm=HandleMenu(title='另存为')
- # hm.get_sub_handles()
- # 2.menu操作
- # hm=HandleMenu(title='aa - 记事本')
- # hm.get_menu()
- # 3.获取所有活动窗口的类名、标题
- hm = HandleMenu()
- hm.get_all_windows()
鼠标操作
- import win32api
- import win32gui
- import win32con
- import win32print
- import time
-
- # 1 获取句柄
- # 1.1 通过坐标获取窗口句柄
- handle = win32gui.WindowFromPoint(win32api.GetCursorPos()) # (259, 185)
- # 1.2 获取最前窗口句柄
- handle = win32gui.GetForegroundWindow()
- # 1.3 通过类名或查标题找窗口
- handle = win32gui.FindWindow('cls_name', "title")
- # 1.4 找子窗体
- sub_handle = win32gui.FindWindowEx(handle, None, 'Edit', None) # 子窗口类名叫“Edit”
-
- # 句柄操作
- title = win32gui.GetWindowText(handle)
- cls_name = win32gui.GetClassName(handle)
- print({'类名': cls_name, '标题': title})
- # 获取窗口位置
- info = win32gui.GetWindowRect(handle)
- # 设置为最前窗口
- win32gui.SetForegroundWindow(handle)
-
- # 2.按键-看键盘码
- # 获取鼠标当前位置的坐标
- cursor_pos = win32api.GetCursorPos()
- # 将鼠标移动到坐标处
- win32api.SetCursorPos((200, 200))
- # 回车
- win32api.keybd_event(13, 0, win32con.KEYEVENTF_EXTENDEDKEY, 0)
- win32api.keybd_event(13, 0, win32con.KEYEVENTF_KEYUP, 0)
- # 左单键击
- 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)
- # 鼠标左键按下-放开
- win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
- win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
- # 鼠标右键按下-放开
- win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
- win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
- # TAB键
- win32api.keybd_event(win32con.VK_TAB, 0, 0, 0)
- win32api.keybd_event(win32con.VK_TAB, 0, win32con.KEYEVENTF_KEYUP, 0)
- # 快捷键Alt+F
- win32api.keybd_event(18, 0, 0, 0) # Alt
- win32api.keybd_event(70, 0, 0, 0) # F
- win32api.keybd_event(70, 0, win32con.KEYEVENTF_KEYUP, 0) # 释放按键
- win32api.keybd_event(18, 0, win32con.KEYEVENTF_KEYUP, 0)
-
- # 3.Message
- win = win32gui.FindWindow('Notepad', None)
- tid = win32gui.FindWindowEx(win, None, 'Edit', None)
- # 输入文本
- win32gui.SendMessage(tid, win32con.WM_SETTEXT, None, '你好hello word!')
- # 确定
- win32gui.SendMessage(handle, win32con.WM_COMMAND, 1, btnhld)
- # 关闭窗口
- win32gui.PostMessage(win32gui.FindWindow('Notepad', None), win32con.WM_CLOSE, 0, 0)
- # 回车
- win32gui.PostMessage(tid, win32con.WM_KEYDOWN, win32con.VK_RETURN, 0) # 插入一个回车符,post 没有返回值,执行完马上返回
- win32gui.PostMessage(tid, win32con.WM_KEYDOWN, win32con.VK_RETURN, 0)
- print("%x" % win)
- print("%x" % tid)
- # 选项框
- res = win32api.MessageBox(None, "Hello Pywin32", "pywin32", win32con.MB_YESNOCANCEL)
- print(res)
- win32api.MessageBox(0, "Hello PYwin32", "MessageBox", win32con.MB_OK | win32con.MB_ICONWARNING) # 加警告标志
针对PDF处理
- from win32con import SW_HIDE, SW_SHOWNORMAL
-
- for fn in ['2.txt', '3.txt']:
- print(fn)
- res = win32api.ShellExecute(0, # 指定父窗口句柄
-
- 'print', # 指定动作, 譬如: open、print、edit、explore、find
-
- fn, # 指定要打开的文件或程序
-
- win32print.GetDefaultPrinter(),
- # 给要打开的程序指定参数;GetDefaultPrinter 取得默认打印机名称 <type 'str'>,GetDefaultPrinterW 取得默认打印机名称 <type 'unicode'>
-
- "./downloads/", # 目录路径
-
- SW_SHOWNORMAL) # 打开选项,SW_HIDE = 0; {隐藏},SW_SHOWNORMAL = 1; {用最近的大小和位置显示, 激活}
- print(res) # 返回值大于32表示执行成功,返回值小于32表示执行错误
-
- # 打印 -pdf
- def print_pdf(pdf_file_name):
- """
- 静默打印pdf
- :param pdf_file_name:
- :return:
- """
- # GSPRINT_PATH = resource_path + 'GSPRINT\\gsprint'
- GHOSTSCRIPT_PATH = resource_path + 'GHOSTSCRIPT\\bin\\gswin32c' # gswin32c.exe
- currentprinter = config.printerName # "printerName":"FUJI XEROX ApeosPort-VI C3370\""
- currentprinter = win32print.GetDefaultPrinter()
- arg = '-dPrinted ' \
- '-dBATCH ' \
- '-dNOPAUSE ' \
- '-dNOSAFER ' \
- '-dFitPage ' \
- '-dNORANGEPAGESIZE ' \
- '-q ' \
- '-dNumCopies=1 ' \
- '-sDEVICE=mswinpr2 ' \
- '-sOutputFile="\\\\spool\\' \
- + currentprinter + " " + \
- pdf_file_name
- log.info(arg)
- win32api.ShellExecute(
- 0,
- 'open',
- GHOSTSCRIPT_PATH,
- arg,
- ".",
- 0
- )
- # os.remove(pdf_file_name)
截屏
- from PIL import ImageGrab
- # 利用PIL截屏
- im = ImageGrab.grab()
- im.save('aa.jpg')
-
- # 5.文件的读写
- import win32file, win32api, win32con
- import os
-
- def SimpleFileDemo():
- testName = os.path.join(win32api.GetTempPath(), "opt_win_file.txt")
-
- if os.path.exists(testName):
- os.unlink(testName) # os.unlink() 方法用于删除文件,如果文件是一个目录则返回一个错误。
- # 写
- 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()
- # 读
- 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()
- # print(win32api.GetTempPath()) # 获取临时文件夹路径
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。