From 855150cd05c1ba67af439cc25057b5406410619a Mon Sep 17 00:00:00 2001 From: CristiFati Date: Fri, 3 Dec 2021 20:41:08 +0200 Subject: [PATCH 1/7] Minor: format and spacing --- .../recipe-305690.py | 128 +++++++++--------- 1 file changed, 64 insertions(+), 64 deletions(-) diff --git a/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py b/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py index f34449c27..389c9def8 100644 --- a/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py +++ b/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py @@ -34,6 +34,7 @@ JOB_STATUS_USER_INTERVENTION = 0x00000400 JOB_STATUS_RESTART = 0x00000800 + class SYSTEMTIME(Structure): _fields_ = [ ("wYear", c_short), @@ -43,38 +44,41 @@ class SYSTEMTIME(Structure): ("wHour", c_short), ("wMinute",c_short), ("wSecond", c_short), - ("wMilliseconds", c_short) - ] - -class DEVMODE(Structure): - _fields_ = [ - ("dmDeviceName", c_char * 32), - ("dmSpecVersion", c_short), - ("dmDriverVersion", c_short), - ("dmSize", c_short), - ("dmDriverExtra", c_short), - ("dmFields", c_int), - ("dmOrientation", c_short), - ("dmPaperSize", c_short), - ("dmPaperLength", c_short), - ("dmPaperWidth", c_short), - ("dmScale", c_short), - ("dmCopies", c_short), - ("dmDefaultSource", c_short), - ("dmPrintQuality", c_short), - ("dmColor", c_short), - ("dmDuplex", c_short), - ("dmYResolution", c_short), - ("dmTTOption", c_short), - ("dmCollate", c_short), - ("dmFormName", c_char * 32), - ("dmLogPixels", c_int), - ("dmBitsPerPel", c_long), - ("dmPelsWidth", c_long), - ("dmPelsHeight", c_long), - ("dmDisplayFlags", c_long), - ("dmDisplayFrequency", c_long) + ("wMilliseconds", c_short), + ] + + +class DEVMODE(Structure): + _fields_ = [ + ("dmDeviceName", c_char * 32), + ("dmSpecVersion", c_short), + ("dmDriverVersion", c_short), + ("dmSize", c_short), + ("dmDriverExtra", c_short), + ("dmFields", c_int), + ("dmOrientation", c_short), + ("dmPaperSize", c_short), + ("dmPaperLength", c_short), + ("dmPaperWidth", c_short), + ("dmScale", c_short), + ("dmCopies", c_short), + ("dmDefaultSource", c_short), + ("dmPrintQuality", c_short), + ("dmColor", c_short), + ("dmDuplex", c_short), + ("dmYResolution", c_short), + ("dmTTOption", c_short), + ("dmCollate", c_short), + ("dmFormName", c_char * 32), + ("dmLogPixels", c_int), + ("dmBitsPerPel", c_long), + ("dmPelsWidth", c_long), + ("dmPelsHeight", c_long), + ("dmDisplayFlags", c_long), + ("dmDisplayFrequency", c_long), ] + + class JOB_INFO_2(Structure): _fields_ = [ ("JobId", c_ulong), @@ -99,41 +103,39 @@ class JOB_INFO_2(Structure): ("Size", c_ulong), ("Submitted", SYSTEMTIME), ("Time", c_ulong), - ("PagesPrinted", c_ulong) - ] + ("PagesPrinted", c_ulong), + ] class Printer: def ReadPrinterData(self, hPrinter): - #-- Read Data from printer pReadBuffer = c_buffer(500) # can make this dynamic depending on the job Size i.e. pJobInfo[i].Size - pBuf = addressof(pReadBuffer) + pBuf = addressof(pReadBuffer) READ_BUFFER_SIZE = sizeof(pReadBuffer) NoRead = c_ulong() pNoRead = addressof(NoRead) #-- Lets try to get the spool file ret = ws.ReadPrinter(hPrinter, - pBuf, - READ_BUFFER_SIZE, - pNoRead) + pBuf, + READ_BUFFER_SIZE, + pNoRead) if ret: print "".join([i for i in pReadBuffer]) pBuf = None pReadBuffer = None - + def GetDefaultPrinter(self): - #-- Get the default printer - plen = c_long() - ret = ws.GetDefaultPrinterA(None, byref(plen)) - pname = c_buffer(plen.value) - ret = ws.GetDefaultPrinterA(pname, byref(plen)) + plen = c_long() + ret = ws.GetDefaultPrinterA(None, byref(plen)) + pname = c_buffer(plen.value) + ret = ws.GetDefaultPrinterA(pname, byref(plen)) return pname.value - + def OpenPrinter(self, prtname = None): #-- Let open our printer if prtname == None: @@ -150,9 +152,8 @@ def ClosePrinter(self, handle = None): else: ws.ClosePrinter(handle) handle = None - + def EnumJobs(self, pJob, cbBuf): - #-- Enumerates printer jobs FirstJob = c_ulong(0) #Start from this job self.NoJobs = 20 #How many jobs do you want to get? @@ -161,30 +162,29 @@ def EnumJobs(self, pJob, cbBuf): self.nReturned = c_ulong(0) # No. of jobs returned ret = ws.EnumJobsA(self.OpenPrinter(), - FirstJob, - self.NoJobs, - Level, - pJob, - cbBuf, - byref(self.pcbNeeded), - byref(self.nReturned)) - + FirstJob, + self.NoJobs, + Level, + pJob, + cbBuf, + byref(self.pcbNeeded), + byref(self.nReturned)) + return ret - if __name__== "__main__": while 1: #-- Loop picking up printer jobs prt = Printer() - + # we need to call EnumJobs() to find out how much memory you need # It should have failed if there are jobs on the printer if not prt.EnumJobs(None,0): - + #-- Lets first close the printer prt.ClosePrinter() - + #-- Allocate JOB_INFO_2 structures pJobArray = JOB_INFO_2 * prt.NoJobs pJobInfo = pJobArray() @@ -192,30 +192,30 @@ def EnumJobs(self, pJob, cbBuf): #-- Call EnumJobs now with the correct memory needed from the first call prt.EnumJobs(pJob, prt.pcbNeeded) - + #-- Lets check whether we got any job from the second call if prt.nReturned.value: for i in range (prt.nReturned.value): print pJobInfo[i].JobId, pJobInfo[i].pDocument, pJobInfo[i].pUserName, pJobInfo[i].Status - + prtName = prt.GetDefaultPrinter() #-- Lets try and get the spool file. The call to open printer must have the jobid: #-- Format "printername,Job xxxx" prtJobName = prtName+","+"Job"+" "+str(pJobInfo[i].JobId) pHandle = prt.OpenPrinter(prtJobName) - + if pHandle.value: #-- Read spool file. Does not work well if you do not have a bidirectional printer. prt.ReadPrinterData(pHandle) prt.ClosePrinter(pHandle) prt.ClosePrinter() - + #-- Clean up pJob = None pJobInfo = None prt = None - + #-- Wait for the next printer job #-- Adjust this depending on the speed of your printer and network time.sleep(3) From 21e19d2953c495345c893a5518b150744078dd28 Mon Sep 17 00:00:00 2001 From: CristiFati Date: Fri, 3 Dec 2021 20:42:41 +0200 Subject: [PATCH 2/7] Python 3 syntax --- recipes/Python/305690_Enumerate_printer_job/recipe-305690.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py b/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py index 389c9def8..14d0b9ba9 100644 --- a/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py +++ b/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py @@ -124,7 +124,7 @@ def ReadPrinterData(self, hPrinter): pNoRead) if ret: - print "".join([i for i in pReadBuffer]) + print("".join([i for i in pReadBuffer])) pBuf = None pReadBuffer = None @@ -196,7 +196,7 @@ def EnumJobs(self, pJob, cbBuf): #-- Lets check whether we got any job from the second call if prt.nReturned.value: for i in range (prt.nReturned.value): - print pJobInfo[i].JobId, pJobInfo[i].pDocument, pJobInfo[i].pUserName, pJobInfo[i].Status + print(pJobInfo[i].JobId, pJobInfo[i].pDocument, pJobInfo[i].pUserName, pJobInfo[i].Status) prtName = prt.GetDefaultPrinter() From a0f19d4df002a9dd0b8b137fa452d77b57ef8921 Mon Sep 17 00:00:00 2001 From: CristiFati Date: Fri, 3 Dec 2021 21:02:54 +0200 Subject: [PATCH 3/7] Define argtypes and restype for functions called via CTypes --- .../recipe-305690.py | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py b/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py index 14d0b9ba9..f58e1a903 100644 --- a/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py +++ b/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py @@ -1,5 +1,7 @@ import time from ctypes import * +from ctypes import wintypes as wt + """ This script enumerates printer jobs from a specified default printer. This information includes Jobid, Document name, @@ -18,8 +20,27 @@ license GPL """ + +LPPRINTER_DEFAULTS = wt.LPVOID + ws = WinDLL("winspool.drv") +ws.ClosePrinter.argtypes = (wt.HANDLE,) +ws.ClosePrinter.restype = wt.BOOL + +ws.EnumJobsA.argtypes = (wt.HANDLE, wt.DWORD, wt.DWORD, wt.DWORD, wt.LPBYTE, wt.DWORD, wt.LPDWORD, wt.LPDWORD) +ws.EnumJobsA.restype = wt.BOOL + +ws.GetDefaultPrinterA.argtypes = (wt.LPSTR, wt.LPDWORD) +ws.GetDefaultPrinterA.restype = wt.BOOL + +ws.OpenPrinterA.argtypes = (wt.LPSTR, POINTER(wt.HANDLE), LPPRINTER_DEFAULTS) +ws.OpenPrinterA.restype = wt.BOOL + +ws.ReadPrinter.argtypes = (wt.HANDLE, wt.LPVOID, wt.DWORD, wt.LPDWORD) +ws.ReadPrinter.restype = wt.BOOL + + #-- Job Status meaning JOB_STATUS_PAUSED = 0x00000001 JOB_STATUS_ERROR = 0x00000002 @@ -130,7 +151,7 @@ def ReadPrinterData(self, hPrinter): def GetDefaultPrinter(self): #-- Get the default printer - plen = c_long() + plen = wt.DWORD() ret = ws.GetDefaultPrinterA(None, byref(plen)) pname = c_buffer(plen.value) ret = ws.GetDefaultPrinterA(pname, byref(plen)) @@ -140,7 +161,7 @@ def OpenPrinter(self, prtname = None): #-- Let open our printer if prtname == None: self.prtname = self.GetDefaultPrinter() - self.handle = c_ulong() + self.handle = wt.HANDLE() ret = ws.OpenPrinterA(self.prtname, byref(self.handle), None) return self.handle From 0b22e6ec41fc25479eb18afb69b4a9fa473dc38e Mon Sep 17 00:00:00 2001 From: CristiFati Date: Fri, 3 Dec 2021 21:09:41 +0200 Subject: [PATCH 4/7] 'import *' is lame --- .../recipe-305690.py | 162 +++++++++--------- 1 file changed, 81 insertions(+), 81 deletions(-) diff --git a/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py b/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py index f58e1a903..be28a9b41 100644 --- a/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py +++ b/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py @@ -1,5 +1,5 @@ import time -from ctypes import * +import ctypes as ct from ctypes import wintypes as wt @@ -23,7 +23,7 @@ LPPRINTER_DEFAULTS = wt.LPVOID -ws = WinDLL("winspool.drv") +ws = ct.WinDLL("winspool.drv") ws.ClosePrinter.argtypes = (wt.HANDLE,) ws.ClosePrinter.restype = wt.BOOL @@ -34,7 +34,7 @@ ws.GetDefaultPrinterA.argtypes = (wt.LPSTR, wt.LPDWORD) ws.GetDefaultPrinterA.restype = wt.BOOL -ws.OpenPrinterA.argtypes = (wt.LPSTR, POINTER(wt.HANDLE), LPPRINTER_DEFAULTS) +ws.OpenPrinterA.argtypes = (wt.LPSTR, ct.POINTER(wt.HANDLE), LPPRINTER_DEFAULTS) ws.OpenPrinterA.restype = wt.BOOL ws.ReadPrinter.argtypes = (wt.HANDLE, wt.LPVOID, wt.DWORD, wt.LPDWORD) @@ -56,75 +56,75 @@ JOB_STATUS_RESTART = 0x00000800 -class SYSTEMTIME(Structure): +class SYSTEMTIME(ct.Structure): _fields_ = [ - ("wYear", c_short), - ("wMonth", c_short), - ("wDayOfWeek", c_short), - ("wDay", c_short), - ("wHour", c_short), - ("wMinute",c_short), - ("wSecond", c_short), - ("wMilliseconds", c_short), + ("wYear", ct.c_short), + ("wMonth", ct.c_short), + ("wDayOfWeek", ct.c_short), + ("wDay", ct.c_short), + ("wHour", ct.c_short), + ("wMinute", ct.c_short), + ("wSecond", ct.c_short), + ("wMilliseconds", ct.c_short), ] -class DEVMODE(Structure): +class DEVMODE(ct.Structure): _fields_ = [ - ("dmDeviceName", c_char * 32), - ("dmSpecVersion", c_short), - ("dmDriverVersion", c_short), - ("dmSize", c_short), - ("dmDriverExtra", c_short), - ("dmFields", c_int), - ("dmOrientation", c_short), - ("dmPaperSize", c_short), - ("dmPaperLength", c_short), - ("dmPaperWidth", c_short), - ("dmScale", c_short), - ("dmCopies", c_short), - ("dmDefaultSource", c_short), - ("dmPrintQuality", c_short), - ("dmColor", c_short), - ("dmDuplex", c_short), - ("dmYResolution", c_short), - ("dmTTOption", c_short), - ("dmCollate", c_short), - ("dmFormName", c_char * 32), - ("dmLogPixels", c_int), - ("dmBitsPerPel", c_long), - ("dmPelsWidth", c_long), - ("dmPelsHeight", c_long), - ("dmDisplayFlags", c_long), - ("dmDisplayFrequency", c_long), + ("dmDeviceName", ct.c_char * 32), + ("dmSpecVersion", ct.c_short), + ("dmDriverVersion", ct.c_short), + ("dmSize", ct.c_short), + ("dmDriverExtra", ct.c_short), + ("dmFields", ct.c_int), + ("dmOrientation", ct.c_short), + ("dmPaperSize", ct.c_short), + ("dmPaperLength", ct.c_short), + ("dmPaperWidth", ct.c_short), + ("dmScale", ct.c_short), + ("dmCopies", ct.c_short), + ("dmDefaultSource", ct.c_short), + ("dmPrintQuality", ct.c_short), + ("dmColor", ct.c_short), + ("dmDuplex", ct.c_short), + ("dmYResolution", ct.c_short), + ("dmTTOption", ct.c_short), + ("dmCollate", ct.c_short), + ("dmFormName", ct.c_char * 32), + ("dmLogPixels", ct.c_int), + ("dmBitsPerPel", ct.c_long), + ("dmPelsWidth", ct.c_long), + ("dmPelsHeight", ct.c_long), + ("dmDisplayFlags", ct.c_long), + ("dmDisplayFrequency", ct.c_long), ] -class JOB_INFO_2(Structure): +class JOB_INFO_2(ct.Structure): _fields_ = [ - ("JobId", c_ulong), - ("pPrinterName", c_char_p), - ("pMachineName", c_char_p), - ("pUserName", c_char_p), - ("pDocument", c_char_p), - ("pNotifyName", c_char_p), - ("pDatatype", c_char_p), - ("pPrintProcessor", c_char_p), - ("pParameters", c_char_p), - ("pDriverName", c_char_p), - ("pDevMode", POINTER(DEVMODE)), - ("pStatus", c_char_p), - ("pSecurityDescriptor", c_void_p), - ("Status", c_ulong), - ("Priority", c_ulong), - ("Position",c_ulong), - ("StartTime", c_ulong), - ("UntilTime", c_ulong), - ("TotalPages", c_ulong), - ("Size", c_ulong), + ("JobId", ct.c_ulong), + ("pPrinterName", ct.c_char_p), + ("pMachineName", ct.c_char_p), + ("pUserName", ct.c_char_p), + ("pDocument", ct.c_char_p), + ("pNotifyName", ct.c_char_p), + ("pDatatype", ct.c_char_p), + ("pPrintProcessor", ct.c_char_p), + ("pParameters", ct.c_char_p), + ("pDriverName", ct.c_char_p), + ("pDevMode", ct.POINTER(DEVMODE)), + ("pStatus", ct.c_char_p), + ("pSecurityDescriptor", ct.c_void_p), + ("Status", ct.c_ulong), + ("Priority", ct.c_ulong), + ("Position", ct.c_ulong), + ("StartTime", ct.c_ulong), + ("UntilTime", ct.c_ulong), + ("TotalPages", ct.c_ulong), + ("Size", ct.c_ulong), ("Submitted", SYSTEMTIME), - ("Time", c_ulong), - ("PagesPrinted", c_ulong), + ("Time", ct.c_ulong), + ("PagesPrinted", ct.c_ulong), ] @@ -132,11 +132,11 @@ class Printer: def ReadPrinterData(self, hPrinter): #-- Read Data from printer - pReadBuffer = c_buffer(500) # can make this dynamic depending on the job Size i.e. pJobInfo[i].Size - pBuf = addressof(pReadBuffer) - READ_BUFFER_SIZE = sizeof(pReadBuffer) - NoRead = c_ulong() - pNoRead = addressof(NoRead) + pReadBuffer = ct.c_buffer(500) # can make this dynamic depending on the job Size i.e. pJobInfo[i].Size + pBuf = ct.addressof(pReadBuffer) + READ_BUFFER_SIZE = ct.sizeof(pReadBuffer) + NoRead = ct.c_ulong() + pNoRead = ct.addressof(NoRead) #-- Lets try to get the spool file ret = ws.ReadPrinter(hPrinter, @@ -152,22 +152,22 @@ def ReadPrinterData(self, hPrinter): def GetDefaultPrinter(self): #-- Get the default printer plen = wt.DWORD() - ret = ws.GetDefaultPrinterA(None, byref(plen)) - pname = c_buffer(plen.value) - ret = ws.GetDefaultPrinterA(pname, byref(plen)) + ret = ws.GetDefaultPrinterA(None, ct.byref(plen)) + pname = ct.c_buffer(plen.value) + ret = ws.GetDefaultPrinterA(pname, ct.byref(plen)) return pname.value - def OpenPrinter(self, prtname = None): + def OpenPrinter(self, prtname=None): #-- Let open our printer - if prtname == None: + if prtname is None: self.prtname = self.GetDefaultPrinter() self.handle = wt.HANDLE() - ret = ws.OpenPrinterA(self.prtname, byref(self.handle), None) + ret = ws.OpenPrinterA(self.prtname, ct.byref(self.handle), None) return self.handle - def ClosePrinter(self, handle = None): + def ClosePrinter(self, handle=None): #-- Close our printer after opening it - if handle == None: + if handle is None: ws.ClosePrinter(self.handle) self.handle = None else: @@ -176,11 +176,11 @@ def ClosePrinter(self, handle = None): def EnumJobs(self, pJob, cbBuf): #-- Enumerates printer jobs - FirstJob = c_ulong(0) #Start from this job + FirstJob = ct.c_ulong(0) #Start from this job self.NoJobs = 20 #How many jobs do you want to get? Level = 2 #JOB_INFO_2 Structure - self.pcbNeeded = c_ulong(0) # Bytes needed to fill the structure - self.nReturned = c_ulong(0) # No. of jobs returned + self.pcbNeeded = ct.c_ulong(0) # Bytes needed to fill the structure + self.nReturned = ct.c_ulong(0) # No. of jobs returned ret = ws.EnumJobsA(self.OpenPrinter(), FirstJob, @@ -188,8 +188,8 @@ def EnumJobs(self, pJob, cbBuf): Level, pJob, cbBuf, - byref(self.pcbNeeded), - byref(self.nReturned)) + ct.byref(self.pcbNeeded), + ct.byref(self.nReturned)) return ret @@ -209,7 +209,7 @@ def EnumJobs(self, pJob, cbBuf): #-- Allocate JOB_INFO_2 structures pJobArray = JOB_INFO_2 * prt.NoJobs pJobInfo = pJobArray() - pJob = addressof(pJobInfo) + pJob = ct.addressof(pJobInfo) #-- Call EnumJobs now with the correct memory needed from the first call prt.EnumJobs(pJob, prt.pcbNeeded) From e6e28ba044411f6bf6a4ff379e0ee997bef46051 Mon Sep 17 00:00:00 2001 From: CristiFati Date: Fri, 3 Dec 2021 22:44:17 +0200 Subject: [PATCH 5/7] Fix errors --- .../recipe-305690.py | 41 ++++++++----------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py b/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py index be28a9b41..5c07d42a0 100644 --- a/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py +++ b/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py @@ -132,28 +132,25 @@ class Printer: def ReadPrinterData(self, hPrinter): #-- Read Data from printer - pReadBuffer = ct.c_buffer(500) # can make this dynamic depending on the job Size i.e. pJobInfo[i].Size - pBuf = ct.addressof(pReadBuffer) - READ_BUFFER_SIZE = ct.sizeof(pReadBuffer) + BufSize = 500 # can make this dynamic depending on the job Size i.e. pJobInfo[i].Size + pReadBuffer = ct.create_string_buffer(BufSize) NoRead = ct.c_ulong() - pNoRead = ct.addressof(NoRead) #-- Lets try to get the spool file ret = ws.ReadPrinter(hPrinter, - pBuf, - READ_BUFFER_SIZE, - pNoRead) + pReadBuffer, + BufSize, + ct.byref(NoRead)) if ret: - print("".join([i for i in pReadBuffer])) - pBuf = None + print("Printer buffer:", "".join([i for i in pReadBuffer])) pReadBuffer = None def GetDefaultPrinter(self): #-- Get the default printer plen = wt.DWORD() ret = ws.GetDefaultPrinterA(None, ct.byref(plen)) - pname = ct.c_buffer(plen.value) + pname = ct.create_string_buffer(plen.value) ret = ws.GetDefaultPrinterA(pname, ct.byref(plen)) return pname.value @@ -190,40 +187,39 @@ def EnumJobs(self, pJob, cbBuf): cbBuf, ct.byref(self.pcbNeeded), ct.byref(self.nReturned)) - return ret if __name__== "__main__": while 1: #-- Loop picking up printer jobs + print("Checking for printers...") prt = Printer() # we need to call EnumJobs() to find out how much memory you need # It should have failed if there are jobs on the printer - if not prt.EnumJobs(None,0): + if not prt.EnumJobs(None, 0): #-- Lets first close the printer prt.ClosePrinter() - #-- Allocate JOB_INFO_2 structures - pJobArray = JOB_INFO_2 * prt.NoJobs - pJobInfo = pJobArray() - pJob = ct.addressof(pJobInfo) - + #-- Allocate buffer for JOB_INFO_2 structures + pJobBuf = ct.create_string_buffer(prt.pcbNeeded.value) #-- Call EnumJobs now with the correct memory needed from the first call - prt.EnumJobs(pJob, prt.pcbNeeded) + prt.EnumJobs(ct.cast(pJobBuf, wt.LPBYTE), prt.pcbNeeded) #-- Lets check whether we got any job from the second call if prt.nReturned.value: - for i in range (prt.nReturned.value): - print(pJobInfo[i].JobId, pJobInfo[i].pDocument, pJobInfo[i].pUserName, pJobInfo[i].Status) + JobArray = JOB_INFO_2 * prt.nReturned.value + jobInfo = JobArray.from_buffer(pJobBuf) + for i in range(prt.nReturned.value): + print("Job {:}:".format(i), jobInfo[i].JobId, jobInfo[i].pDocument, jobInfo[i].pUserName, jobInfo[i].Status) prtName = prt.GetDefaultPrinter() #-- Lets try and get the spool file. The call to open printer must have the jobid: #-- Format "printername,Job xxxx" - prtJobName = prtName+","+"Job"+" "+str(pJobInfo[i].JobId) + prtJobName = "{:},Job {:}".format(prtName.decode(), jobInfo[i].JobId).encode() pHandle = prt.OpenPrinter(prtJobName) if pHandle.value: @@ -233,8 +229,7 @@ def EnumJobs(self, pJob, cbBuf): prt.ClosePrinter() #-- Clean up - pJob = None - pJobInfo = None + pJobBuf = None prt = None #-- Wait for the next printer job From ffc457cb03735faed649350fc3de7ac2913983ee Mon Sep 17 00:00:00 2001 From: CristiFati Date: Fri, 3 Dec 2021 23:51:02 +0200 Subject: [PATCH 6/7] Some error handling + ReadPrinter code fix (didn't execute before) --- .../recipe-305690.py | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py b/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py index 5c07d42a0..5c5669310 100644 --- a/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py +++ b/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py @@ -23,8 +23,12 @@ LPPRINTER_DEFAULTS = wt.LPVOID +k32 = ct.WinDLL("kernel32.dll") ws = ct.WinDLL("winspool.drv") +k32.GetLastError.argtypes = () +k32.GetLastError.restype = wt.DWORD + ws.ClosePrinter.argtypes = (wt.HANDLE,) ws.ClosePrinter.restype = wt.BOOL @@ -141,9 +145,10 @@ def ReadPrinterData(self, hPrinter): pReadBuffer, BufSize, ct.byref(NoRead)) - if ret: - print("Printer buffer:", "".join([i for i in pReadBuffer])) + print("Printer buffer:", b"".join([i for i in pReadBuffer])) + else: + print("ReadPrinter error: {:d}".format(k32.GetLastError())) pReadBuffer = None def GetDefaultPrinter(self): @@ -156,10 +161,12 @@ def GetDefaultPrinter(self): def OpenPrinter(self, prtname=None): #-- Let open our printer - if prtname is None: - self.prtname = self.GetDefaultPrinter() + self.prtname = self.GetDefaultPrinter() if prtname is None else prtname self.handle = wt.HANDLE() ret = ws.OpenPrinterA(self.prtname, ct.byref(self.handle), None) + if not ret: + print("OpenPrinter error: {:d}".format(k32.GetLastError())) + self.handle = wt.HANDLE() return self.handle def ClosePrinter(self, handle=None): @@ -193,7 +200,7 @@ def EnumJobs(self, pJob, cbBuf): if __name__== "__main__": while 1: #-- Loop picking up printer jobs - print("Checking for printers...") + print("Checking for printers (and jobs)...") prt = Printer() # we need to call EnumJobs() to find out how much memory you need @@ -218,8 +225,8 @@ def EnumJobs(self, pJob, cbBuf): prtName = prt.GetDefaultPrinter() #-- Lets try and get the spool file. The call to open printer must have the jobid: - #-- Format "printername,Job xxxx" - prtJobName = "{:},Job {:}".format(prtName.decode(), jobInfo[i].JobId).encode() + #-- Format "PrinterName, Job xxxx" + prtJobName = "{:}, Job {:}".format(prtName.decode(), jobInfo[i].JobId).encode() pHandle = prt.OpenPrinter(prtJobName) if pHandle.value: From 229c90bd5a80072cb08d62d606ab48ecc9208dcd Mon Sep 17 00:00:00 2001 From: CristiFati Date: Sat, 4 Dec 2021 00:02:43 +0200 Subject: [PATCH 7/7] Verbose output --- .../Python/305690_Enumerate_printer_job/recipe-305690.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py b/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py index 5c5669310..2ddb350ba 100644 --- a/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py +++ b/recipes/Python/305690_Enumerate_printer_job/recipe-305690.py @@ -162,6 +162,7 @@ def GetDefaultPrinter(self): def OpenPrinter(self, prtname=None): #-- Let open our printer self.prtname = self.GetDefaultPrinter() if prtname is None else prtname + print("Attempting to open printer {:}".format(self.prtname)) self.handle = wt.HANDLE() ret = ws.OpenPrinterA(self.prtname, ct.byref(self.handle), None) if not ret: @@ -200,7 +201,7 @@ def EnumJobs(self, pJob, cbBuf): if __name__== "__main__": while 1: #-- Loop picking up printer jobs - print("Checking for printers (and jobs)...") + print("\nChecking for printers (and jobs)...") prt = Printer() # we need to call EnumJobs() to find out how much memory you need @@ -220,9 +221,9 @@ def EnumJobs(self, pJob, cbBuf): JobArray = JOB_INFO_2 * prt.nReturned.value jobInfo = JobArray.from_buffer(pJobBuf) for i in range(prt.nReturned.value): - print("Job {:}:".format(i), jobInfo[i].JobId, jobInfo[i].pDocument, jobInfo[i].pUserName, jobInfo[i].Status) + print("\nJob {:}:".format(i), jobInfo[i].JobId, jobInfo[i].pDocument, jobInfo[i].pUserName, jobInfo[i].Status) - prtName = prt.GetDefaultPrinter() + prtName = prt.GetDefaultPrinter() #-- Lets try and get the spool file. The call to open printer must have the jobid: #-- Format "PrinterName, Job xxxx"