Python- как общаться с принтером

Я искал несколько дней, как улучшить программу, которую я написал для работы. Программа, которая использует python 3.6, просто отправляет предварительно отформатированные файлы.doc на принтер, но я не могу найти способ, как дать сигнал функции, чтобы прекратить отправку файла на печать, когда принтер закончился бумага. Количество печатаемых документов варьируется, поэтому я не могу просто использовать функцию простого диапазона.

Я посмотрел на модуль win32print и модуль pycups (который не будет устанавливать pip, независимо от того, что я пытаюсь). Есть ли что-то в сигнальном модуле, который фиксирует внешние сообщения об ошибках из других приложений? В идеале, было бы здорово, если бы скрипт 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)

1 ответ

Примечание: я должен сказать, что pywin32 основан на Win, в то время как pycups (или любая оболочка cups) основана на Ux, поэтому, если для Win нет некоторого порта cups, о котором я не знаю, вам следует выбрать один из 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). Вот почему мне пришлось написать некоторый дополнительный код (который я здесь не включил), чтобы перечислить все доступные принтеры и получить их имена.

Другие вопросы по тегам