You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows系统下用Python实时获取打印机详细状态的技术咨询

Windows下Python实时获取打印机详细状态解决方案

问题描述

在Windows系统中需通过Python实时获取打印机的详细状态(如机门打开、卡纸、缺墨粉等)并展示,但现有代码存在两个核心问题:

  • 仅支持单次状态查询,无法实现实时监控
  • 仅能获取暂停、空闲、离线等基础状态,无法捕获机门打开、缺墨粉等详细异常状态

原问题代码

def GetPrinterStatus(self, printerName):
        pythoncom.CoInitialize()
        status = ""
        try:
            wmi = win32com.client.Dispatch("WbemScripting.SWbemLocator")
            service = wmi.ConnectServer(".", "root\\cimv2")
            printers = service.ExecQuery(f"SELECT * FROM Win32_Printer WHERE Name = '{printerName}'")
            for printer in printers:
                if printer.PrinterState == 0 or printer.PrinterState == 0:
                    status = status + "IDLE"
                elif printer.PrinterState == 1 or printer.PrinterState == 1:
                    status = status + "PAUSED"
                elif printer.PrinterState == 2 or printer.PrinterState == 2:
                    status = status + "Printer Error"
                elif printer.PrinterState == 4 or printer.PrinterState == 4:
                    status = status + "Pending Deletion"
                elif printer.PrinterState == 8 or printer.PrinterState == 8:
                    status = status + "Paper Jam"
                elif printer.PrinterState == 16 or printer.PrinterState == 10:
                    status = status + "Paper Out"
                elif printer.PrinterState == 32 or printer.PrinterState == 20:
                    status = status + "Manual Feed"
                elif printer.PrinterState == 64 or printer.PrinterState == 40:
                    status = status + "Page Problem"
                elif printer.PrinterState == 128 or printer.PrinterState == 80:
                    status = status + "OFFLINE"
                elif printer.PrinterState == 256 or printer.PrinterState == 100:
                    status = status + "I/O Active"
                elif printer.PrinterState == 512 or printer.PrinterState == 200:
                    status = status + "BUSY"
                elif printer.PrinterState == 1024 or printer.PrinterState == 400:
                    status = status + "PRINTING"
                elif printer.PrinterState == 2048 or printer.PrinterState == 800:
                    status = status + "Output Bin Full"
                elif printer.PrinterState == 4096 or printer.PrinterState == 1000:
                    status = status + "Not Available"
                elif printer.PrinterState == 8192 or printer.PrinterState == 2000:
                    status = status + "WAITING"
                elif printer.PrinterState == 16384 or printer.PrinterState == 4000:
                    status = status + "PROCESSING"
                elif printer.PrinterState == 32768 or printer.PrinterState == 8000:
                    status = status + "Initializing"
                elif printer.PrinterState == 65536 or printer.PrinterState == 10000:
                    status = status + "Warming Up"
                elif printer.PrinterState == 131072 or printer.PrinterState == 20000:
                    status = status + "Toner Low"
                elif printer.PrinterState == 262144 or printer.PrinterState == 40000:
                    status = status + "No Toner"
                elif printer.PrinterState == 524288 or printer.PrinterState == 80000:
                    status = status + "Page Punt"
                elif printer.PrinterState == 1048576 or printer.PrinterState == 100000:
                    status = status + "User Intervention"
                elif printer.PrinterState == 2097152 or printer.PrinterState == 200000:
                    status = status + "Out of Memory"
                elif printer.PrinterState == 4194304 or printer.PrinterState == 400000:
                    status = status + "Printer Door Open"
                elif printer.PrinterState == 8388608 or printer.PrinterState == 800000:
                    status = status + "Unknown Server"
                elif printer.PrinterState == 6777216 or printer.PrinterState == 1000000:
                    status = status + "Power Save"
        finally:
            pythoncom.CoUninitialize()
            return status

核心问题分析

  1. 状态判断逻辑错误:PrinterState是位掩码类型,多个状态可同时存在(如卡纸+机门打开),原代码用==判断单一值,无法识别复合状态,也会遗漏大部分详细异常。
  2. 未利用扩展状态属性:Win32_Printer提供的ExtendedDetectedErrorState属性包含更精准的错误状态,原代码未使用该属性,导致无法获取缺墨、机门打开等信息。
  3. 无实时机制:原代码仅执行单次查询,未实现定时重复查询或事件监听,无法做到实时状态更新。

解决方案

1. 修正状态获取逻辑

通过位运算解析PrinterState和ExtendedDetectedErrorState的位掩码,获取完整的打印机状态:

import pythoncom
import win32com.client

# 定义PrinterState对应的状态映射(位掩码)
PRINTER_STATES = {
    0x00000001: "已暂停",
    0x00000002: "打印机错误",
    0x00000004: "待删除",
    0x00000008: "卡纸",
    0x00000010: "缺纸",
    0x00000020: "手动进纸",
    0x00000040: "页面问题",
    0x00000080: "离线",
    0x00000100: "I/O活动中",
    0x00000200: "忙碌",
    0x00000400: "正在打印",
    0x00000800: "出纸槽已满",
    0x00001000: "不可用",
    0x00002000: "等待中",
    0x00004000: "处理中",
    0x00008000: "初始化中",
    0x00010000: "预热中",
    0x00020000: "墨粉不足",
    0x00040000: "无墨粉",
    0x00080000: "页面放弃",
    0x00100000: "需要用户干预",
    0x00200000: "内存不足",
    0x00400000: "打印机机门打开",
    0x00800000: "未知服务器",
    0x04000000: "省电模式"
}

# 定义ExtendedDetectedErrorState对应的扩展状态映射
EXTENDED_STATES = {
    1: "无错误",
    2: "缺纸",
    4: "卡纸",
    8: "墨粉不足",
    16: "无墨粉",
    32: "机门打开",
    64: "需要用户干预",
    128: "输出槽满",
    256: "内存不足",
    512: "正在打印",
    1024: "正在处理",
    2048: "预热中",
    4096: "离线",
    8192: "暂停",
    16384: "初始化中",
    32768: "省电模式"
}

def get_printer_status(printer_name):
    pythoncom.CoInitialize()
    status_list = []
    try:
        wmi = win32com.client.Dispatch("WbemScripting.SWbemLocator")
        service = wmi.ConnectServer(".", "root\\cimv2")
        # 查询指定打印机
        printers = service.ExecQuery(f"SELECT * FROM Win32_Printer WHERE Name = '{printer_name}'")
        for printer in printers:
            # 解析PrinterState位掩码
            state = printer.PrinterState
            for mask, desc in PRINTER_STATES.items():
                if state & mask:
                    status_list.append(desc)
            # 解析ExtendedDetectedErrorState位掩码,补充更详细状态
            extended_state = printer.ExtendedDetectedErrorState
            if extended_state:
                for mask, desc in EXTENDED_STATES.items():
                    if extended_state & mask and desc not in status_list:
                        status_list.append(desc)
            # 无任何状态时默认显示空闲
            if not status_list:
                status_list.append("空闲")
    finally:
        pythoncom.CoUninitialize()
    return " | ".join(status_list)

2. 实现实时监控

提供两种实时监控方式,按需选择:

方式一:定时轮询(简单易实现)

通过定时重复查询打印机状态,实现实时展示:

import time

def realtime_monitor(printer_name, interval=2):
    """
    实时监控打印机状态
    :param printer_name: 打印机名称
    :param interval: 查询间隔(秒),默认2秒
    """
    print(f"开始实时监控打印机: {printer_name}")
    print("------------------------------")
    try:
        while True:
            current_status = get_printer_status(printer_name)
            # 覆盖当前行输出,避免刷屏
            print(f"\r当前状态: {current_status}", end="")
            time.sleep(interval)
    except KeyboardInterrupt:
        print("\n监控已停止")

# 调用示例(替换为你的打印机名称)
if __name__ == "__main__":
    TARGET_PRINTER = "你的打印机名称"
    realtime_monitor(TARGET_PRINTER)

方式二:WMI事件监听(高效,状态变更时触发)

监听WMI的打印机属性变更事件,仅在状态变化时更新,减少资源消耗:

def monitor_printer_events(printer_name):
    """
    通过WMI事件监听打印机状态变更
    """
    pythoncom.CoInitialize()
    try:
        wmi = win32com.client.Dispatch("WbemScripting.SWbemLocator")
        service = wmi.ConnectServer(".", "root\\cimv2")
        # 创建事件查询,每2秒检查一次状态变更
        query = f"SELECT * FROM __InstanceModificationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_Printer' AND TargetInstance.Name = '{printer_name}'"
        watcher = service.ExecNotificationQuery(query)
        print(f"开始监听打印机 {printer_name} 的状态变更...")
        while True:
            # 等待事件触发
            event = watcher.NextEvent()
            # 获取最新状态并打印
            current_status = get_printer_status(printer_name)
            print(f"\n状态变更: {current_status}")
    except KeyboardInterrupt:
        print("\n监听已停止")
    finally:
        pythoncom.CoUninitialize()

# 调用示例
if __name__ == "__main__":
    TARGET_PRINTER = "你的打印机名称"
    monitor_printer_events(TARGET_PRINTER)

使用说明

  1. 确保已安装依赖库:pip install pywin32
  2. 替换代码中的TARGET_PRINTER为你的实际打印机名称(可在Windows打印机设置中查看)
  3. 运行代码后,即可实时获取并展示打印机的详细状态

内容的提问来源于stack exchange,提问作者John0211

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 15:02:09