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). Вот почему мне пришлось написать некоторый дополнительный код (который я здесь не включил), чтобы перечислить все доступные принтеры и получить их имена.