1

几天来,我一直在寻找如何改进我为工作编写的程序。该程序使用 python 3.6,只是将预先格式化的 .doc 文件发送到打印机,但我似乎无法找到一种方法来指示函数在打印机用完后停止发送文件以进行打印纸。打印的文档数量各不相同,所以我不能只使用简单的范围函数。

我研究了 win32print 模块和 pycups 模块(无论我尝试什么都不会 pip install )。信号模块中是否有一些东西可以捕获来自其他应用程序的外部错误消息?理想情况下,如果 python 脚本可以在发送文件之前先检查打印队列的状态,那就太好了。

我发现下面的代码,使用 win32print 模块,应该可以完成这个,但它似乎不起作用。

import win32print

p = win32print.OpenPrinter("Canon Inkjet iP1800 series")

raw = win32print.EnumJobs(p, 0, 999)

def main():
    while len(raw) > 0:
        #does some function

    if #receives error from printer:
        break

main()

win32print.ClosePrinter(p)
4

1 回答 1

0

旁注:我必须说pywin32是基于Win的,而pycups(或任何杯子包装器)是基于Ux的,所以除非有一些我不知道的Win杯子端口,否则您应该选择上述 2 之一(最好,与您所在的平台/拱门相匹配)。

我做了一些研究,没有必要遍历所有打印机作业,以检查打印机是否处于错误状态。此外,循环从 0 到 999 的作业并不能保证检查所有作业,因此上面的逻辑(即使它是正确的 - 这不是)不会成立。

这是一个示例实现(我冒昧地添加了比问题中指定的错误更多的错误:用完纸(win32print.PRINTER_STATUS_PAPER_OUT)并将它们放入 PRINTER_ERROR_STATES(注释掉那些你不认为是错误的错误):

import win32print

PRINTER_ERROR_STATES = (
    win32print.PRINTER_STATUS_NO_TONER,
    win32print.PRINTER_STATUS_NOT_AVAILABLE,
    win32print.PRINTER_STATUS_OFFLINE,
    win32print.PRINTER_STATUS_OUT_OF_MEMORY,
    win32print.PRINTER_STATUS_OUTPUT_BIN_FULL,
    win32print.PRINTER_STATUS_PAGE_PUNT,
    win32print.PRINTER_STATUS_PAPER_JAM,
    win32print.PRINTER_STATUS_PAPER_OUT,
    win32print.PRINTER_STATUS_PAPER_PROBLEM,
)


def printer_errorneous_state(printer, error_states=PRINTER_ERROR_STATES):
    prn_opts = win32print.GetPrinter(printer)
    status_opts = prn_opts[18]
    for error_state in error_states:
        if status_opts & error_state:
            return error_state
    return 0


def main():
    printer_name = "Canon Inkjet iP1800 series" # or get_printer_names()[0]
    prn = win32print.OpenPrinter(printer_name)
    error = printer_errorneous_state(prn)
    if error:
        print("ERROR occurred: ", error)
    else:
        print("Printer OK...")
        #  Do the real work

    win32print.ClosePrinter(prn)


if __name__ == "__main__":
    main()

注意:显然,Win不会存储打印机上设置的打印机名称。就我而言,我有一台名为EPSON******的打印机。但是在Win中,它的名字是EPSON******(WF-7610 系列)。这就是为什么我必须编写一些额外的代码(我没有在这里包含)来枚举所有可用的打印机并获取它们的名称。

于 2017-03-25T05:17:41.173 回答