Python- How to communicate with printer

自闭症网瘾萝莉.ら 提交于 2019-12-11 05:39:48

问题


I've been searching for a few days on how to improve a program I wrote for work. The program, which uses python 3.6, simply sends pre-formatted .doc files to the printer, but I can't seem to find a way on how to signal the function to stop sending the file to print once the printer has run out of paper. The number of documents printed varies, so I can't just use a simple range function.

I've looked into the win32print module and the pycups module (which won't pip install not matter what I try). Is there something in the signal module that captures external error messages from other apps? Ideally, what would be great, is if the python script could check the status of the print queue first, before sending the file.

I found that the code below, using the win32print module, that should accomplish this, but it doesn't seem to work.

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)

回答1:


Side note: I must say that pywin32 is Win based, while pycups (or any cups wrapper) is Ux based so, unless there's some cups port for Win that I'm not aware of, you should pick one of the above 2 (preferably, matching the platform/arch that you're on).

I've done some research, and it's not necessary to iterate trough all the printer jobs, in order to check whether the printer is in an erroneous state. Also, looping over jobs from 0 to 999, doesn't guarantee that all jobs are checked, so the logic above (even if it was correct - which is not) would not stand.

Here's a sample implementation (I took the liberty of adding more errors than specified in the question: running out of paper(win32print.PRINTER_STATUS_PAPER_OUT) and placed them in PRINTER_ERROR_STATES (comment out the ones that you don't see as errors):

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

Note: Apparently, Win doesn't store the printer names as set on printers. In my case, I have a printer called EPSON******. However in Win, its name is EPSON****** (WF-7610 Series). That's why I had to write some additional code (that I didn't include here) to enumerate all available printers and get their names.



来源:https://stackoverflow.com/questions/42726925/python-how-to-communicate-with-printer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!