0

What I'm trying to achieve is to print a file with win32print, so that I can inform the user about the job that is actually being printed.

It is sufficient to print the file name to standard output with print function.

I have this code taken from here to illustrate the problem.

from win32 import win32print
import subprocess

printer_name = win32print.GetDefaultPrinter()

print("Printer: %s" % (printer_name))

hPrinter = win32print.OpenPrinter(printer_name)

try:
    hJob = win32print.StartDocPrinter(hPrinter, 1, ("test of raw data", None, "RAW"))
    try:
        f = open("test2.ps", "r")
        win32print.StartPagePrinter(hPrinter)
        win32print.WritePrinter(hPrinter, bytes(f.read(), "utf-8"))
        win32print.EndPagePrinter(hPrinter)
    finally:
        win32print.EndDocPrinter(hPrinter)
finally:
    print("Printing: %s" % (hJob))
    win32print.ClosePrinter(hPrinter)

How would you notify the user about what is being printed (detect starting new job)?

Here are the status codes.

e.g. 0x00000400 means the printer is printing . I can't find how to get job actually being printed.

xralf
  • 3,312
  • 45
  • 129
  • 200
  • 1
    Do you want to get the document name? You could first [`EnumJobs`](https://learn.microsoft.com/en-us/windows/win32/printdocs/enumjobs), then check the `JOB_INFO_x.Status` if it is `JOB_STATUS_PRINTED` or `JOB_STATUS_PRINTING`, and the `JOB_INFO_x.pDocument` is the document name. – Drake Wu Feb 28 '20 at 05:44
  • @DrakeWu-MSFT Could you please write the code snippet to see the checking and notifying? For now, it would be enough to print a message in the command line, to see successive printing of all documents. Later (not part of this question), I would like to inform in the status bar or use some progress bar. – xralf Feb 28 '20 at 06:14

1 Answers1

1

If you want to print the document name of the job which is in printing status. You could try the following sample:

import win32print

if __name__ == "__main__":
    hPrinter= win32print.OpenPrinter(name)
    job_info_level = 1
    job_infos = win32print.EnumJobs(hPrinter, 0, -1, job_info_level)
    for job_info in job_infos:
        if (job_info['Status'] == win32print.JOB_STATUS_PRINTING)
            print("Printing "+job_info['pDocument'])
    win32print.ClosePrinter(hPrinter)\

UPDATE:

To get the document name when printing, you could use FindFirstPrinterChangeNotification and FindNextPrinterChangeNotification.

Set the JOB_NOTIFY_FIELD_DOCUMENT in FindFirstPrinterChangeNotification. You could refer to this answer

Drake Wu
  • 6,927
  • 1
  • 7
  • 30
  • And is it possible to write something like: while there are jobs to print: print document_name – xralf Feb 28 '20 at 13:57
  • Thank you, I will try the answer you link to as soon as I'm on Windows laptop, anyway it looks pretty large. For me would be sufficient to detect if the printer just printed a document and save_it_to_db() as printed. – xralf Mar 03 '20 at 22:21