Python win32底层开发从入门到实战

这是一份专为移动端阅读优化的 pywin32 Python 教程,语言通俗、步骤清晰、示例完整。全程用同步模式演示(新手友好),所有示例都在 Windows 10/11 系统下测试通过。

一、准备工作:安装与环境配置

1. 安装核心包

打开命令行,执行以下命令:

bash

复制代码
pip install pywin32  # 安装pywin32库
python Scripts/pywin32_postinstall.py -install  # 重要!执行后注册COM组件

提示:如果找不到pywin32_postinstall.py脚本,可通过pip show pywin32查看安装路径,然后用完整路径执行该脚本。例如:conda3\envs\py312\Lib\site-packages\win32\scripts。

2. 验证安装

创建test_install.py文件,运行以下代码:

python

复制代码
import win32api
import win32con
import win32gui
import win32com.client

# 弹出一个测试消息框
win32api.MessageBox(0, "pywin32安装成功!", "验证结果", win32con.MB_OK)
print("所有核心模块导入成功!")

运行后能看到系统消息框弹出,说明安装成功。

二、核心概念:pywin32 的核心模块

pywin32 提供了多个核心模块,就像 Windows 系统的 "工具箱":

模块 功能 通俗用途
win32api Windows 基础 API 系统操作(消息框、文件操作、注册表)
win32gui 窗口管理 API 查找 / 控制窗口、模拟用户界面操作
win32con Windows 常量定义 提供系统常量(如窗口样式、消息类型)
win32com COM 组件交互 自动化控制 Office、浏览器等软件
win32process 进程管理 启动 / 关闭进程、获取进程信息
win32file 文件系统 API 底层文件操作(比 Python 内置 open 更强大)

标准写法模板(记住这个格式):

python

复制代码
import win32api
import win32con
import win32gui

# 基础系统操作示例
def basic_operation():
    # 弹出消息框
    win32api.MessageBox(0, "Hello pywin32!", "标题", win32con.MB_OKCANCEL)
    
    # 获取系统时间
    print("当前系统时间:", win32api.GetLocalTime())

basic_operation()

三、窗口管理:控制 Windows 窗口

窗口管理是 pywin32 最常用的功能之一,可实现查找、控制、操作任何 Windows 窗口。

1. 查找窗口(核心功能)

python

复制代码
import win32gui
import win32con

# 1. 根据窗口标题查找(最常用)
notepad_handle = win32gui.FindWindow(None, "无标题 - 记事本")
if notepad_handle:
    print(f"找到记事本窗口,句柄: {notepad_handle}")
    
# 2. 根据窗口类名查找
explorer_handle = win32gui.FindWindow("CabinetWClass", None)  # 资源管理器类名
if explorer_handle:
    print(f"找到资源管理器窗口,句柄: {explorer_handle}")
    
# 3. 遍历所有顶层窗口
def callback(handle, extra):
    if win32gui.IsWindowVisible(handle):  # 只显示可见窗口
        title = win32gui.GetWindowText(handle)
        if title:  # 只显示有标题的窗口
            print(f"窗口句柄: {handle}, 标题: {title}")
    return True

win32gui.EnumWindows(callback, None)

2. 窗口操作(移动、调整、激活)

python

复制代码
import win32gui
import win32con
import time

def control_window():
    # 查找记事本窗口
    handle = win32gui.FindWindow(None, "无标题 - 记事本")
    if not handle:
        print("未找到记事本窗口,请先打开一个记事本")
        return
        
    # 1. 激活并前置窗口
    win32gui.SetForegroundWindow(handle)
    time.sleep(1)
    
    # 2. 移动窗口到屏幕左上角(100, 100)
    win32gui.MoveWindow(handle, 100, 100, 500, 300, True)
    time.sleep(1)
    
    # 3. 最小化窗口
    win32gui.ShowWindow(handle, win32con.SW_MINIMIZE)
    time.sleep(1)
    
    # 4. 还原窗口
    win32gui.ShowWindow(handle, win32con.SW_RESTORE)

control_window()

3. 窗口文本操作

python

复制代码
import win32gui
import win32con

def get_set_window_text():
    handle = win32gui.FindWindow(None, "无标题 - 记事本")
    if not handle:
        print("未找到记事本窗口")
        return
        
    # 获取窗口标题
    title = win32gui.GetWindowText(handle)
    print(f"当前窗口标题: {title}")
    
    # 修改窗口标题
    win32gui.SetWindowText(handle, "pywin32控制的记事本")
    print("窗口标题已修改")

get_set_window_text()

四、系统 API 操作:与 Windows 系统底层交互

1. 消息框与系统提示

python

复制代码
import win32api
import win32con

# 1. 基本消息框
win32api.MessageBox(0, "这是基本消息框", "提示", win32con.MB_OK)

# 2. 带图标和按钮的消息框
result = win32api.MessageBox(0, "是否继续操作?", "确认", 
                           win32con.MB_YESNO | win32con.MB_ICONQUESTION)
if result == win32con.IDYES:
    print("用户选择了是")
else:
    print("用户选择了否")

# 3. 系统蜂鸣
win32api.Beep(1000, 500)  # 1000Hz,持续500毫秒

2. 文件与注册表操作

python

复制代码
import win32api
import win32con
import win32file

# 1. 创建文件(底层API方式)
file_handle = win32file.CreateFile(
    "test.txt",  # 文件名
    win32con.GENERIC_WRITE,  # 写入权限
    0,  # 不共享
    None,  # 默认安全设置
    win32con.CREATE_ALWAYS,  # 总是创建新文件
    win32con.FILE_ATTRIBUTE_NORMAL,  # 正常属性
    None
)
win32file.WriteFile(file_handle, b"Hello pywin32!")
win32file.CloseHandle(file_handle)

# 2. 读取注册表值(获取系统版本)
key = win32api.RegOpenKeyEx(
    win32con.HKEY_LOCAL_MACHINE,
    r"SOFTWARE\Microsoft\Windows NT\CurrentVersion",
    0,
    win32con.KEY_READ
)
version = win32api.RegQueryValueEx(key, "ProductName")[0]
win32api.RegCloseKey(key)
print(f"Windows系统版本: {version}")

3. 进程管理

python

复制代码
import win32api
import win32process
import win32con
import subprocess

# 1. 启动新进程
notepad_path = r"C:\Windows\System32\notepad.exe"
process_info = win32process.CreateProcess(
    notepad_path,  # 程序路径
    "",  # 命令行参数
    None, None, False, 0, None, None,
    win32process.STARTUPINFO()
)
print(f"启动记事本进程,PID: {process_info[2]}")

# 2. 等待进程结束(可选)
# win32event.WaitForSingleObject(process_info[0], win32con.INFINITE)

# 3. 关闭进程
# win32api.TerminateProcess(process_info[0], 0)

五、用户输入模拟:键盘与鼠标自动化

1. 键盘输入模拟

python

复制代码
import win32api
import win32con
import win32gui
import time

def simulate_keyboard():
    # 激活记事本窗口
    handle = win32gui.FindWindow(None, "无标题 - 记事本")
    if not handle:
        print("未找到记事本窗口")
        return
    win32gui.SetForegroundWindow(handle)
    time.sleep(1)
    
    # 模拟输入文本(逐个字符)
    text = "Hello pywin32! 这是模拟键盘输入的内容。"
    for char in text:
        # 处理特殊字符(这里只处理空格)
        if char == ' ':
            win32api.keybd_event(win32con.VK_SPACE, 0, 0, 0)
            time.sleep(0.05)
            win32api.keybd_event(win32con.VK_SPACE, 0, win32con.KEYEVENTF_KEYUP, 0)
        else:
            # 普通字符(需要转换为虚拟键码)
            win32api.keybd_event(ord(char.upper()), 0, 0, 0)
            time.sleep(0.05)
            win32api.keybd_event(ord(char.upper()), 0, win32con.KEYEVENTF_KEYUP, 0)
        time.sleep(0.05)
    
    # 模拟按Enter键
    win32api.keybd_event(win32con.VK_RETURN, 0, 0, 0)
    time.sleep(0.1)
    win32api.keybd_event(win32con.VK_RETURN, 0, win32con.KEYEVENTF_KEYUP, 0)

simulate_keyboard()

2. 鼠标操作模拟

python

复制代码
import win32api
import win32con
import time

def simulate_mouse():
    # 1. 获取当前鼠标位置
    x, y = win32api.GetCursorPos()
    print(f"当前鼠标位置: ({x}, {y})")
    
    # 2. 移动鼠标到指定位置(500, 500)
    win32api.SetCursorPos((500, 500))
    time.sleep(1)
    
    # 3. 模拟左键点击
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 500, 500, 0, 0)
    time.sleep(0.1)
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 500, 500, 0, 0)
    
    # 4. 模拟右键点击
    time.sleep(1)
    win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTDOWN, 500, 500, 0, 0)
    time.sleep(0.1)
    win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTUP, 500, 500, 0, 0)

simulate_mouse()

六、COM 自动化:控制 Office 与其他软件

这是 pywin32 最强大的功能之一,可自动化控制 Excel、Word 等 Office 软件。

1. Excel 自动化基础

python

复制代码
import win32com.client
import os

def excel_automation():
    # 1. 启动Excel应用(后台运行)
    excel = win32com.client.Dispatch("Excel.Application")
    excel.Visible = False  # True表示显示界面,False表示后台运行
    
    try:
        # 2. 新建工作簿
        workbook = excel.Workbooks.Add()
        worksheet = workbook.Worksheets(1)
        
        # 3. 写入数据
        worksheet.Cells(1, 1).Value = "Hello pywin32!"
        worksheet.Cells(1, 2).Value = "Excel自动化示例"
        
        # 4. 设置单元格格式
        worksheet.Cells(1, 1).Font.Bold = True
        worksheet.Cells(1, 1).Font.Size = 14
        
        # 5. 保存文件
        file_path = os.path.join(os.getcwd(), "test_excel.xlsx")
        workbook.SaveAs(file_path)
        print(f"Excel文件已保存到: {file_path}")
        
    except Exception as e:
        print(f"出错了: {e}")
    finally:
        # 6. 关闭Excel(必须执行,否则会残留后台进程)
        workbook.Close(SaveChanges=False)
        excel.Quit()
        del excel  # 释放COM对象

excel_automation()

2. Word 自动化基础

python

复制代码
import win32com.client
import os

def word_automation():
    # 1. 启动Word应用
    word = win32com.client.Dispatch("Word.Application")
    word.Visible = True  # 显示Word界面
    
    try:
        # 2. 新建文档
        document = word.Documents.Add()
        
        # 3. 写入内容
        range_obj = document.Range(0, 0)
        range_obj.Text = "Hello pywin32!\n这是Word自动化示例文档。\n"
        
        # 4. 设置格式
        range_obj.Font.Name = "微软雅黑"
        range_obj.Font.Size = 14
        range_obj.Font.Bold = True
        
        # 5. 保存文件
        file_path = os.path.join(os.getcwd(), "test_word.docx")
        document.SaveAs(FileName=file_path)
        print(f"Word文件已保存到: {file_path}")
        
    except Exception as e:
        print(f"出错了: {e}")
    finally:
        # 6. 关闭Word
        document.Close(SaveChanges=False)
        word.Quit()
        del word

word_automation()

七、高级功能:窗口消息与钩子

1. 发送窗口消息

python

复制代码
import win32api
import win32con
import win32gui

def send_window_message():
    # 查找记事本窗口
    handle = win32gui.FindWindow(None, "无标题 - 记事本")
    if not handle:
        print("未找到记事本窗口")
        return
        
    # 发送关闭消息(模拟点击关闭按钮)
    win32api.SendMessage(handle, win32con.WM_CLOSE, 0, 0)
    
    # 或者发送自定义消息
    # win32api.SendMessage(handle, win32con.WM_USER+100, 0, 0)

2. 简单窗口钩子(监听系统事件)

python

复制代码
import win32api
import win32con
import win32gui
import win32process
import sys

def window_proc(hwnd, msg, wparam, lparam):
    """自定义窗口过程函数"""
    if msg == win32con.WM_DESTROY:
        win32api.PostQuitMessage(0)
    return win32gui.DefWindowProc(hwnd, msg, wparam, lparam)

def simple_hook():
    # 注册窗口类
    class_name = "PyWin32HookClass"
    wc = win32gui.WNDCLASSEX()
    wc.lpfnWndProc = window_proc
    wc.lpszClassName = class_name
    wc.hInstance = win32api.GetModuleHandle(None)
    win32gui.RegisterClassEx(wc)
    
    # 创建隐藏窗口(用于接收消息)
    hwnd = win32gui.CreateWindowEx(
        0, class_name, "HookWindow", 0,
        0, 0, 0, 0, 0, 0, wc.hInstance, None
    )
    
    # 消息循环(简单示例,实际使用需谨慎)
    msg = win32gui.GetMessage(None, 0, 0)
    while msg[1] != 0:
        win32gui.TranslateMessage(msg)
        win32gui.DispatchMessage(msg)
        msg = win32gui.GetMessage(None, 0, 0)

# simple_hook()  # 注意:这会阻塞程序,需要单独运行

八、实战案例:完整的记事本自动化流程

以下是一个完整的自动化脚本,包含窗口查找、激活、输入、保存等所有核心操作:

python

复制代码
import win32api
import win32con
import win32gui
import win32com.client
import time
import os

def notepad_automation():
    """完整的记事本自动化流程"""
    try:
        # 1. 启动记事本
        notepad_path = r"C:\Windows\System32\notepad.exe"
        process_info = win32api.ShellExecute(0, "open", notepad_path, "", "", 1)
        time.sleep(2)  # 等待记事本启动
        
        # 2. 查找并激活记事本窗口
        handle = None
        for _ in range(5):  # 最多尝试5次
            handle = win32gui.FindWindow(None, "无标题 - 记事本")
            if handle:
                break
            time.sleep(1)
        
        if not handle:
            print("无法找到记事本窗口")
            return
            
        win32gui.SetForegroundWindow(handle)
        time.sleep(1)
        
        # 3. 模拟输入内容
        text = "pywin32记事本自动化示例\n"
        text += "1. 自动启动记事本\n"
        text += "2. 自动输入内容\n"
        text += "3. 自动保存文件\n"
        text += "4. 自动关闭窗口\n"
        
        # 使用更高效的方式输入文本(通过SendMessage)
        edit_handle = win32gui.FindWindowEx(handle, None, "Edit", None)
        win32api.SendMessage(edit_handle, win32con.WM_SETTEXT, 0, text)
        
        # 4. 模拟保存操作(Ctrl+S)
        win32api.keybd_event(win32con.VK_CONTROL, 0, 0, 0)
        win32api.keybd_event(ord('S'), 0, 0, 0)
        time.sleep(0.1)
        win32api.keybd_event(ord('S'), 0, win32con.KEYEVENTF_KEYUP, 0)
        win32api.keybd_event(win32con.VK_CONTROL, 0, win32con.KEYEVENTF_KEYUP, 0)
        time.sleep(1)
        
        # 5. 保存对话框处理(简单示例,实际情况可能更复杂)
        save_handle = win32gui.FindWindow("#32770", "另存为")
        if save_handle:
            # 输入文件名
            edit_handle = win32gui.FindWindowEx(save_handle, None, "Edit", None)
            file_path = os.path.join(os.getcwd(), "automation_test.txt")
            win32api.SendMessage(edit_handle, win32con.WM_SETTEXT, 0, file_path)
            
            # 点击保存按钮
            button_handle = win32gui.FindWindowEx(save_handle, None, "Button", "保存(&S)")
            win32api.SendMessage(button_handle, win32con.BM_CLICK, 0, 0)
            time.sleep(1)
        
        # 6. 关闭记事本
        win32api.SendMessage(handle, win32con.WM_CLOSE, 0, 0)
        print("记事本自动化流程完成!")
        
    except Exception as e:
        print(f"出错了: {e}")

notepad_automation()

九、最佳实践:编写稳定可靠的 Windows 自动化脚本

  1. 添加适当延迟 :Windows 界面操作需要时间响应,用time.sleep(0.5~1)代替过快的连续操作
  2. 处理窗口查找失败:窗口可能未加载完成,使用循环重试机制
  3. 释放 COM 对象 :操作 Office 等软件后,必须调用Quit()并删除对象引用,避免残留后台进程
  4. 错误处理:使用 try-except 捕获异常,确保程序优雅退出
  5. 权限管理:某些操作需要管理员权限,可尝试以管理员身份运行脚本
  6. 避免无限循环:自动化脚本应设置明确的终止条件

常见问题解答

  1. **Q:导入模块时提示 "DLL load failed"?**A:确保 Python 和 pywin32 架构一致(都是 32 位或 64 位),重新安装 Microsoft Visual C++ Redistributable。

  2. Q:Office 自动化后残留后台进程? A:确保在 finally 块中关闭文档和应用程序,使用del释放 COM 对象。

  3. **Q:窗口查找不到?**A:检查窗口标题是否正确,尝试使用类名查找,或等待窗口完全加载后再查找。

  4. Q:键盘输入中文失败? A:pywin32 直接模拟键盘输入不支持中文,可改用剪贴板粘贴方式(win32clipboard模块)。

总结

pywin32 是 Python 控制 Windows 系统的强大工具,能实现从简单窗口操作到复杂 Office 自动化的各种任务。核心要点:

  1. 掌握win32api/win32gui/win32con三个基础模块的使用
  2. 理解COM 自动化原理,能控制 Office 等软件
  3. 学会窗口查找与消息发送,这是 Windows 自动化的核心
  4. 遵循最佳实践,编写稳定可靠的自动化脚本
相关推荐
阿正的梦工坊2 小时前
JavaScript 函数组合(Compose & Pipe)详解
开发语言·javascript·网络
Absurd5872 小时前
如何从SQL获取当前登录用户数据_使用系统上下文函数
jvm·数据库·python
lly2024062 小时前
Python uWSGI 安装配置
开发语言
吕源林2 小时前
golang如何实现消息批量消费_golang消息批量消费实现策略
jvm·数据库·python
weixin_458580122 小时前
如何解决Data Guard主库ORA-16038日志无法归档_强制日志传输报错排查
jvm·数据库·python
djjdjdjdjjdj2 小时前
SQL如何实现动态列的分组展示_利用条件聚合实现
jvm·数据库·python
2401_897190552 小时前
PHP与Suno音乐生成AI集成开发音频应用【操作】
jvm·数据库·python
像一只黄油飞2 小时前
第二章-04-数据类型
笔记·python·学习·零基础
两年半的个人练习生^_^2 小时前
每日一学:设计模式之原型模式
java·开发语言·设计模式·原型模式