How can I use SetJob in win32print?
Question:
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)
Answers:
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
@CristiFati solution has a problem. It generates an exception when it’s successful. You have to put it inside a try except block if you want to use it in your program.
I’ve found another better and easier solution to delete print jobs: https://stackoverflow.com/a/50443807/16198594
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)
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
- EnumJobs returning a tuple of dictionaries (where each dictionary wraps an [MS.Docs]: JOB_INFO_1 structure – for
-
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
-
@CristiFati solution has a problem. It generates an exception when it’s successful. You have to put it inside a try except block if you want to use it in your program.
I’ve found another better and easier solution to delete print jobs: https://stackoverflow.com/a/50443807/16198594