Search code examples
pythonprintingpywin32win32compython-3.6

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)

Solution

  • 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