PyWin32 - How to Monitor the Print Queue

The other day I was trying to figure out a way to monitor the print queue on Windows. The task at hand was to keep track of what documents went to the printer and completely successfully. The idea was that when the print completed, the document would then be archived. To do this sort of thing, you need PyWin32 (AKA: Python for Windows extensions). In this article, we'll look at a simple script that checks the print queue.

Here's the code:

import time
import win32print

#----------------------------------------------------------------------
def print_job_checker():
    """
    Prints out all jobs in the print queue every 5 seconds
    """
    jobs = [1]
    while jobs:
        jobs = []
        for p in win32print.EnumPrinters(win32print.PRINTER_ENUM_LOCAL,
                                         None, 1):
            flags, desc, name, comment = p
            
            phandle = win32print.OpenPrinter(name)
            print_jobs = win32print.EnumJobs(phandle, 0, -1, 1)
            if print_jobs:
                jobs.extend(list(print_jobs))
            for job in print_jobs:
                print "printer name => " + name
                document = job["pDocument"]
                print "Document name => " + document
            win32print.ClosePrinter(phandle)
            
        time.sleep(5)
    print "No more jobs!"
        
#----------------------------------------------------------------------
if __name__ == "__main__":
    print_job_checker()

First off we import win32print and the time module. We need win32print to access the printer. We create a potentially infinite loop to keep checking for jobs in the print queue. If the jobs list is ever empty, that means there is nothing left in the print queue and the function will exit. In the code above we use win32print.EnumPrinters() to loop over the printers that are installed on the machine. The first argument is a flag (win32print.PRINTER_ENUM_LOCAL), the second is a name (or None in this case), and the third is information level. There are several flags we can use, such as PRINTER_ENUM_SHARED, PRINTER_ENUM_LOCAL or PRINTER_ENUM_CONNECTIONS. I went with PRINTER_ENUM_LOCAL because it was returning a printer name in a format that I could use with win32print's OpenPrinter method. We do this to query the printer for information via a handle. To get a list of the print jobs, we call win32print.EnumJobs() with the print handle. Then we loop over them and print out the printer name and the document name. You don't need to do all these prints, but I found it helpful when I was writing the code. For testing purposes, I recommend opening the print queue and setting it to "paused" so that you can prevent printing paper until you are ready. This allows you to still add items to the print queue that you can query.

I put a 5 seconds delay between checks to make sure there are no new updates to the queue. If there are print jobs, it checks the queue again. Otherwise it breaks out of the loop.

Hopefully you will find this piece of code useful for something you are doing. Enjoy!

Additional Information

Copyright © 2024 Mouse Vs Python | Powered by Pythonlibrary