Skip to content
Advertisement

How can I use SetJob in win32print?

I want to clear or delete print jobs using Python. But how can I get JobID?

win32print.SetJob(hPrinter, JobID , Level , JobInfo , Command)

How could I run this code?

jobs = []
for p in win32print.EnumPrinters(win32print.PRINTER_ENUM_LOCAL,None, 1):
    flags, desc, name, comment = p

    pHandle = win32print.OpenPrinter(name)
    print = list(win32print.EnumJobs(pHandle, 0, -1, 1))
    jobs.extend(print)
    SetJob(pHandle, id, 1,JOB_CONTROL_DELETE)
    #where should i get id from?
    win32print.ClosePrinter(pHandle)

Advertisement

Answer

Starting from your code, I’ve managed to create a small script that deletes any print job on any (local) printer (I’ve tested it and it works).

Here it is (I’ve run it with Python 3.5):

code00.py:

#!/usr/bin/env python

import sys
import win32print as wprn


def main(*argv):
    enum_flags = wprn.PRINTER_ENUM_LOCAL #| wprn.PRINTER_ENUM_SHARED
    printer_name = None
    printer_info_level = 1
    for printer_info in wprn.EnumPrinters(enum_flags, printer_name, printer_info_level):
        name = printer_info[2]
        #print(printer_info)
        printer_handle = wprn.OpenPrinter(name)
        job_info_level = 1
        job_info_tuple = wprn.EnumJobs(printer_handle, 0, -1, job_info_level)
        #print(type(job_info_tuple), len(job_info_tuple))
        for job_info in job_info_tuple:
            #print("t", type(job_info), job_info, dir(job_info))
            wprn.SetJob(printer_handle, job_info["JobId"], job_info_level, job_info, wprn.JOB_CONTROL_DELETE)
        wprn.ClosePrinter(printer_handle)


if __name__ == "__main__":
    print("Python {:s} {:03d}bit on {:s}n".format(" ".join(elem.strip() for elem in sys.version.split("n")),
                                                   64 if sys.maxsize > 0x100000000 else 32, sys.platform))
    rc = main(*sys.argv[1:])
    print("nDone.")
    sys.exit(rc)

Notes:

  • What I said in my comment (about iterating over printers) still stands, but I suppose that is beyond the scope of this question

  • I’ve improved the script a little bit:

    • Give (more) meaningful names to variables

    • Use variables instead of plain numbers to increase code readability

    • Other small corrections

    • Probably, it could use some exception handling

  • The secret of the script consist of:

    • EnumJobs returning a tuple of dictionaries (where each dictionary wraps an [MS.Docs]: JOB_INFO_1 structure – for job_info_level = 1), or (obviously) an empty tuple if there are no queued jobs for the printer
  • How the information from EnumJobs is passed to SetJob:

    • The JobID argument (that you asked about) is job_info["JobId"] (check previous bullet)

    • Also notice the next 2 arguments: Level and JobInfo

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement