Windows系统下使用Python捕获打印机打印完成事件并获取文档信息
Windows打印服务器打印完成事件监听方案
报错修复说明
你运行的旧示例代码基于32位Python编写,在64位Python环境下运行会出现ctypes类型匹配错误,报int过长的问题。有两种修复方式:
- 手动调整代码中ctypes调用的参数类型,将EnumJobsA相关的整数参数声明适配为64位类型
- 直接使用封装好的pywin32库的win32print模块,无需手动处理底层系统调用的类型匹配问题
完整实现步骤
环境准备
首先安装依赖库:pip install pywin32
核心实现逻辑
1. 监听打印队列状态变化
调用Windows打印API的事件通知接口监听打印任务状态:
- 用
win32print.OpenPrinter打开目标打印机的句柄 - 调用
win32print.FindFirstPrinterChangeNotification注册事件监听,监听任务状态变更事件 - 循环等待事件触发,触发后调用
win32print.FindNextPrinterChangeNotification获取变更详情
2. 捕获打印完成事件
当打印任务的状态值等于JOB_STATUS_PRINTED(常量值为0x00000800)时,判定为该文档打印完成。
3. 提取所需打印任务信息
调用win32print.GetJob接口获取该任务的全量属性,对应提取你需要的字段:
- 文档名称:获取返回字典的
pDocument字段值 - 页数:获取
TotalPages字段值 - 纸张格式:从
pDevMode结构的dmPaperSize字段映射,常见值对应关系:8=A3、9=A4、11=A5 - 彩色/黑白属性:从
pDevMode结构的dmColor字段判断,1=黑白、2=彩色 - 打印完成时间:直接获取
TimeCompleted字段值,为标准datetime格式
简化示例代码
import win32print import time PRINTER_NAME = "替换为你的打印机名称" JOB_STATUS_PRINTED = 0x00000800 # 纸张尺寸映射表,可根据需要补充更多尺寸 PAPER_SIZE_MAP = { 8: "A3", 9: "A4", 11: "A5" } def monitor_printer(): # 打开打印机 h_printer = win32print.OpenPrinter(PRINTER_NAME) try: # 注册监听任务状态变化事件 h_notify = win32print.FindFirstPrinterChangeNotification( h_printer, win32print.PRINTER_CHANGE_JOB, 0, None ) print(f"开始监听打印机{PRINTER_NAME}的打印事件...") while True: # 等待事件触发,超时时间1秒 wait_result = win32print.WaitForSingleObject(h_notify, 1000) if wait_result == 0: # 获取事件详情 changes, _ = win32print.FindNextPrinterChangeNotification( h_notify, win32print.PRINTER_CHANGE_JOB, None, None ) # 检查是否是任务状态更新事件 if changes & win32print.PRINTER_CHANGE_SET_JOB: # 枚举所有打印任务 jobs = win32print.EnumJobs(h_printer, 0, -1, 2) for job in jobs: if job["Status"] & JOB_STATUS_PRINTED: # 提取所需信息 doc_name = job["pDocument"] total_pages = job["TotalPages"] dev_mode = job["pDevMode"] paper_size = PAPER_SIZE_MAP.get(dev_mode["dmPaperSize"], "未知") color = "彩色" if dev_mode["dmColor"] == 2 else "黑白" complete_time = job["TimeCompleted"] # 输出信息,可根据需要改为写入数据库等操作 print("="*50) print(f"文档名称:{doc_name}") print(f"页数:{total_pages}") print(f"纸张格式:{paper_size}") print(f"打印属性:{color}") print(f"完成时间:{complete_time}") time.sleep(0.1) finally: win32print.ClosePrinter(h_printer) if __name__ == "__main__": monitor_printer()
注意事项
- 该方案仅适用于Windows平台的打印服务器,如果是Linux平台可以用CUPS的Python绑定库实现相同功能
- 运行代码需要管理员权限,否则可能无法获取打印队列的完整访问权限
- 如果需要监听多台打印机,为每台打印机单独创建监听线程即可
内容的提问来源于stack exchange,提问作者xralf
相关产品推荐
相关产品推荐

