pywin32库 : Python 操作 windows 系统 API

这篇具有很好参考价值的文章主要介绍了pywin32库 : Python 操作 windows 系统 API。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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 支撑模块。pywin32库 : Python 操作 windows 系统 API
  • Lib\site-packages\win32com 下是 COM 的支撑模块。pywin32库 : Python 操作 windows 系统 API

在 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库 : Python 操作 windows 系统 API

如果对 pywin32 中如何调用某个 API 不熟悉,那么查看 Pywin32.CHM 就足够了,如果对 API 本身的参数定义和使用不熟悉,那还得继续看 MSDN。

3、使用 pywin32 编写 windows 的 GUI

《python 宝典》:https://wenku.baidu.com/view/1f4eb95df011f18583d049649b6648d7c0c70830.html

示例:Helloworld:

pywin32库 : Python 操作 windows 系统 API

示例:创建文件

在 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 (用户接口),但是看不出有什么区别,查看源码也没发现有什么说明。

pywin32库 : Python 操作 windows 系统 API

 示例:

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 win32gui
 
hld = win32gui.FindWindow(None,u"Adobe Acrobat") #返回窗口标题为Adobe Acrobat的句柄

通过父窗口句柄获取子句柄

#parent为父窗口句柄id
def get_child_windows(parent):
    '''
    获得parent的所有子窗口句柄
     返回子窗口句柄列表
     '''
    if not parent:
        return
    hwndChildList = []
    win32gui.EnumChildWindows(parent, lambda hwnd, param: param.append(hwnd),  hwndChildList)
    return hwndChildList

根据句柄获取句柄标题和类名

import win32gui
 
title = win32gui.GetWindowText(jbid)   #jbid为句柄id
#获取标题
clsname = win32gui.GetClassName(jbid)  
#获取类名

根据句柄获取窗口位置

import win32gui
left, top, right, bottom = win32gui.GetWindowRect(jbid)
#分别为左、上、右、下的窗口位置

根据句柄进行点击操作

import win32api,win32con
 
win32api.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 win32gui


titles = 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 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():
    if t is not "":
        print(h, t)

示例代码 2 :( 使用 win32ui 模块)

import win32ui


def 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 signal

MAIN_HWND = 0


def is_win_ok(hwnd, starttext):
    s = win32gui.GetWindowText(hwnd)
    if starttext in s:
        print(s)
        global MAIN_HWND
        MAIN_HWND = hwnd
        return None
    return 1


def find_main_window(starttxt):
    global MAIN_HWND
    win32gui.EnumChildWindows(0, is_win_ok, starttxt)
    return MAIN_HWND


def winfun(hwnd, lparam):
    s = win32gui.GetWindowText(hwnd)
    if len(s) > 3:
        print("winfun, child_hwnd: %d txt: %s" % (hwnd, s))
    return 1


if __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:
        pass
    os.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 state
    win32gui.ShowWindow(hwnd, 0)
    # win32gui.HideCaret(hwnd)

示例代码 4:

import win32gui
import win32con
import win32api
import win32process
import os


spider_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))
        pass


def 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))
    pass


def 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] = 1
                    else:
                        spider_count_dict[keyword] += 1

    for 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] = 1
            else:
                process_count_dict[v] += 1
    for k, v in process_count_dict.items():
        print('{0} : {1}'.format(k, v))
    pass


def 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 = v
            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)
    pass


def 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 time

mouse = 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 mouse


def 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 False


def 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, Controller

keyboard = 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 keyboard


def 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 False


while 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, Listener


keyboard = Controller()
keys = []


def on_press(key):
    string = str(key).replace("'", "")


def on_release(key):
    global keys
    string = 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 = None


def 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()

    # 获取进程 id
    pid = 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}")

    # 关闭 handles
    kernel32.CloseHandle(hwnd)
    kernel32.CloseHandle(h_process)
    pass


if __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

pywin32库 : Python 操作 windows 系统 API

关键字:Python GetWindowThreadProcessId

Python 实现按键精灵找色点击功能,使用 pywin32 和 Pillow 库:https://blog.csdn.net/lrnboy/article/details/85227548文章来源地址https://www.toymoban.com/news/detail-494412.html

到了这里,关于pywin32库 : Python 操作 windows 系统 API的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Python pywin32实现word和Excel的处理

    pywin32处理Word和Excel的一些事 我们知道Python处理word和Excel的可以借助第三库python-docx、xlrd、xlwt和openpyxl等实现,但这些模块只支持基本的读写操作,如果要实现一些较为深入功能,就要看模块是否有相应功能支持了。 例如将word和Excel转为pdf,在word和Excel里面执行VBA实现特殊功

    2024年02月04日
    浏览(61)
  • 【Python】解决pywin32各种常见问题及中英文手册下载(详细)

    目录 前言 一、中英文手册获取 二、各种常见问题 1. ModuleNotFoundError: No module named \\\'win32xxx\\\' 2. ImportError:DLL load failed while importing win32xxx: 找不到指定的模块。 方法一 方法二 方法三 3. pywintypes.error: (2, \\\'XXX\\\', \\\'系统找不到指定的文件。\\\') 总结 pywin32是针对微软Windows的Python扩展,p

    2024年02月07日
    浏览(41)
  • Electron 适配 Windows 7 32位操作系统

    1)electron v10.4.7 2)npm 13.14.0 Index of /download/release/v13.14.0/ 1)系统需升级为最低SP1版本的OS; 2)必须安装的.NET Framework 最低版本为4.6(本例中安装的是v4.6.2); 3)以防报错,最好安装微软常用运行库合集; 1)下载SP1升级包,并安装; 2)等待安装完成,重启计算机; 3)安装微

    2024年02月05日
    浏览(80)
  • jenkins构建时,报错ERROR: No matching distribution found for pywin32==305

    最近用jenkin构建了一个任务,控制台输出,出现如下报错信息: ERROR: Could not find a version that satisfies the requirement pywin32==305 (from versions: none) ERROR: No matching distribution found for pywin32==305 Build step \\\'Execute shell\\\' marked build as failure Finished: FAILURE   原因: requirement是需要导入的依赖包文件

    2023年04月27日
    浏览(46)
  • pip intall pywin32出现 error: subprocess-exited-with-error 错误的解决办法

    问题描述: 安装pywin32时候报错: 有朋友说更新一下setuptools就可以了。 方法来自:pip intall 出现 error: subprocess-exited-with-error 错误的解决办法_Jackfled的博客-CSDN博客_subprocess-exit 可惜我测试了,没用。 报错: error: subprocess-exited-with-error_匿名用户2022的博客-CSDN博客  还有另外一

    2024年02月12日
    浏览(61)
  • 服务器pip3配置requirements.txt时候could not find a version that satisfies the requirement pywin32

    服务器安装pywin32报错:  这个没解决我的问题: pycharm安装pywin32 报错:No matching distribution found for pywin32_棠宁的博客-CSDN博客_no matching distribution found for pywin32 然后还有人这样: Could not find a version that satisfies the requirement win32api (from versions: ) No matching distribution found for win32api

    2024年02月05日
    浏览(52)
  • Linux操作系统网络模块

    Linux操作系统的网络模块是负责网络通信的核心部分。它通过实现各种协议和算法,使得计算机能够在网络中进行数据交换和通信。网络模块主要包括以下几个方面的功能: (1)IP协议栈:负责处理网络层的数据包,实现IP地址的分配、路由选择等功能。 IP协议栈是网络模块

    2023年04月18日
    浏览(43)
  • 操作系统实验-添加一个内核模块

    参考用书: 《操作系统实践:基于Linux的应用与内核编程》 一.添加一个内核模块 1.1需求分析 对于一个应用程序而言,源代码经编译后与标准运行库链接,通过系统调用执行操作系统内核中的特权指令,指令返回的结果通过系统调用返回给用户,完成程序。 由于Linux是单内

    2024年02月05日
    浏览(51)
  • 基于STM32的智能巡检小车系统设计--STM32最小系统、直流电机、直流电源模块设计

    作者:车 邮箱:692604135@qq.com 学校:西安工程大学硕士研究生 方向:机器视觉、图像分割、深度学习 在介绍具体实现功能之前,需要介绍以下模块。 本课题选择的单片机是ST(意法半导体)开发的STM32F407VET6。 这是一款采用Corte-M4为内核的高性能32位ARM微控制器。该芯片支持

    2024年02月10日
    浏览(54)
  • Python模块openpyxl & 操作Excel文件

    简介         openpyxl是一个用于读取和编写Excel 2010 xlsx/xlsm/xltx/xltm文件的Python库。openpyxl以Python语言和MIT许可证发布。         openpyxl可以处理Excel文件中的绝大多数内容,包括图表、图像和公式。它可以处理大量数据,支持Pandas和NumPy库导入和导出数据。Openpyxl还支持自

    2024年02月10日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包