Link to home
Start Free TrialLog in
Avatar of terrakdr
terrakdr

asked on

Print Spool Monitor

I need to create a application that can monitor Printer Spooler. Shared or not. And how to manipulate it's JOBS. Like delete / Cancel / Purge etc.

Thanks

Avatar of AzraSound
AzraSound
Flag of United States of America image

Avatar of Ruchi
Ruchi

printer spool monitor --
http://www.vbcity.com/download/PrintSpool.zip
"This sample shows you how use EnumJobs Windows API function to monitor print jobs in the any printer spool. The sample's interface emulates Windows printer spool monitor application."

Avatar of terrakdr

ASKER

Edited text of question.
use techniques as in the link to enumerate all jobs then use this api:

Public Declare Function SetJob Lib "winspool.drv" Alias "SetJobA" (ByVal hPrinter As Long, ByVal JobId As Long, ByVal Level As Long, pJob As Byte, ByVal Command As Long) As Long

where Command can take these values:

Public Const JOB_CONTROL_CANCEL = 3
Public Const JOB_CONTROL_DELETE = 5
Public Const JOB_CONTROL_PAUSE = 1
Public Const JOB_CONTROL_RESTART = 4
Public Const JOB_CONTROL_RESUME = 2




here are a few links:

http://vbcode.webhostme.com/en/code.asp?id=70 

http://www.domaindlx.com/e_morcillo/scripts/cod/printer.asp 

http://www.freevbcode.com/ShowCode.Asp?ID=232 

http://www.freevbcode.com/ShowCode.Asp?ID=52 

http://www.visualstatement.com/vb/default.asp?Section=Printer&Title=Enum%20Printers 

type enum printer in the search -- click on the first one in the listbox ..
http://www.mvps.org/vbnet/




'Try this
Const CCHDEVICENAME = 32
Const CCHFORMNAME = 32
Public Const PRINTER_ACCESS_USE = &H8
Public Const PRINTER_ACCESS_ADMINISTER = &H4

Type SYSTEMTIME
        wYear As Integer
        wMonth As Integer
        wDayOfWeek As Integer
        wDay As Integer
        wHour As Integer
        wMinute As Integer
        wSecond As Integer
        wMilliseconds As Integer
End Type

Type JOB_INFO_1
        JobId As Long
        pPrinterName As String
        pMachineName As String
        pUserName As String
        pDocument As String
        pDatatype As String
        pStatus As String
        Status As Long
        Priority As Long
        Position As Long
        TotalPages As Long
        PagesPrinted As Long
        Submitted As SYSTEMTIME
End Type

Type DEVMODE
        dmDeviceName As String * CCHDEVICENAME
        dmSpecVersion As Integer
        dmDriverVersion As Integer
        dmSize As Integer
        dmDriverExtra As Integer
        dmFields As Long
        dmOrientation As Integer
        dmPaperSize As Integer
        dmPaperLength As Integer
        dmPaperWidth As Integer
        dmScale As Integer
        dmCopies As Integer
        dmDefaultSource As Integer
        dmPrintQuality As Integer
        dmColor As Integer
        dmDuplex As Integer
        dmYResolution As Integer
        dmTTOption As Integer
        dmCollate As Integer
        dmFormName As String * CCHFORMNAME
        dmUnusedPadding As Integer
        dmBitsPerPel As Integer
        dmPelsWidth As Long
        dmPelsHeight As Long
        dmDisplayFlags As Long
        dmDisplayFrequency As Long
End Type

Type PRINTER_DEFAULTS
        pDatatype As String
        pDevMode As DEVMODE
        DesiredAccess As Long
End Type

Type PRINTER_INFO_2
        pServerName As Long
        pPrinterName As Long
        pShareName As Long
        pPortName As Long
        pDriverName As Long
        pComment As Long
        pLocation As Long
        pDevMode As Long    ' Pointer to DEVMODE
        pSepFile As Long
        pPrintProcessor As Long
        pDatatype As Long
        pParameters As Long
        pSecurityDescriptor As Long ' Pointer to SECURITY_DESCRIPTOR
        Attributes As Long
        Priority As Long
        DefaultPriority As Long
        StartTime As Long
        UntilTime As Long
        Status As Long
        cJobs As Long
        AveragePPM As Long
End Type

Type MY_PRINTER_INFO 'UDT to store INFO
        pServerName As String
        Status As String
        pPrinterName As String
        pShareName As String
        pPortName As String
        pDriverName As String
        pComment As String
        pLocation As String
        pSepFile As String
        pPrintProcessor As String
        pDatatype As String
        pParameters As String
        Attributes As String
        Priority As Long
        DefaultPriority As Long
        StartTime As Long
        UntilTime As Long
        cJobs As Long
        AveragePPM As Long
        Orientation As String
        PagesTotal(127) As Long
        PagesPrinted(127) As Long
End Type

Public Const PRINTER_ATTRIBUTE_DEFAULT = &H4
Public Const PRINTER_ATTRIBUTE_DIRECT = &H2
Public Const PRINTER_ATTRIBUTE_ENABLE_BIDI = &H800
Public Const PRINTER_ATTRIBUTE_LOCAL = &H40
Public Const PRINTER_ATTRIBUTE_NETWORK = &H10
Public Const PRINTER_ATTRIBUTE_QUEUED = &H1
Public Const PRINTER_ATTRIBUTE_SHARED = &H8

Public Const PRINTER_ENUM_DEFAULT = &H1
Public Const PRINTER_ENUM_LOCAL = &H2
Public Const PRINTER_ENUM_CONNECTIONS = &H4
Public Const PRINTER_ENUM_FAVORITE = &H4
Public Const PRINTER_ENUM_NAME = &H8
Public Const PRINTER_ENUM_REMOTE = &H10
Public Const PRINTER_ENUM_SHARED = &H20
Public Const PRINTER_ENUM_NETWORK = &H40

Public Const PRINTER_STATUS_BUSY = &H200
Public Const PRINTER_STATUS_ERROR = &H2
Public Const PRINTER_STATUS_PAPER_OUT = &H10
'You can use other const from apiviewer
Public Const JOB_STATUS_PAUSED = &H1
Public Const JOB_STATUS_ERROR = &H2
'You can use other const from apiviewer

Private Declare Function apiEnumPrinters Lib "winspool.drv" Alias "EnumPrintersA" (ByVal Flags As Long, ByVal Name As String, ByVal Level As Long, pPrinterEnum As Byte, ByVal cdBuf As Long, pcbNeeded As Long, pcReturned As Long) As Long
Private Declare Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterA" (ByVal pPrinterName As String, phPrinter As Long, pDefault As PRINTER_DEFAULTS) As Long
Private Declare Function apiEnumJobs Lib "winspool.drv" Alias "EnumJobsA" (ByVal hPrinter As Long, ByVal FirstJob As Long, ByVal NoJobs As Long, ByVal Level As Long, pJob As Byte, ByVal cdBuf As Long, pcbNeeded As Long, pcReturned As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Declare Function CopyPointer2String Lib "kernel32" Alias "lstrcpyA" (ByVal NewString As String, ByVal OldString As Long) As Long

Private JI1 As JOB_INFO_1
Private PI2 As PRINTER_INFO_2
Public MyInfo() As MY_PRINTER_INFO

Public Function EnumPrinters() As Long
  Dim pName As String
  Dim Flags As Long, lRet As Long
  Dim ResBuffer() As Byte, tmpBuf As Byte
  Dim ByteNeed As Long, nPrinters As Long
  Dim i As Integer, p As Long
  pName = vbNullString
  Flags = PRINTER_ENUM_LOCAL
  lRet = apiEnumPrinters(Flags, pName, 2&, tmpBuf, 0&, ByteNeed, nPrinters)
  ReDim ResBuffer(ByteNeed) As Byte
  lRet = apiEnumPrinters(Flags, pName, 2&, ResBuffer(0), ByteNeed, ByteNeed, nPrinters)
  ReDim MyInfo(nPrinters)
  p = VarPtr(ResBuffer(0))
  For i = 0 To nPrinters - 1
      CopyMemory PI2, ByVal p, LenB(PI2)
      FillInfoPrn i
      p = p + LenB(PI2)
  Next i
  EnumPrinters = nPrinters
End Function

Private Sub FillInfoPrn(idx As Integer)
  Dim DM As DEVMODE
  MyInfo(idx).pServerName = PointerToString(PI2.pServerName)
  MyInfo(idx).pPrinterName = PointerToString(PI2.pPrinterName)
  MyInfo(idx).Status = GetPrnStatus(PI2.Status)
  MyInfo(idx).cJobs = PI2.cJobs
  MyInfo(idx).pPortName = PointerToString(PI2.pPortName)
  MyInfo(idx).Attributes = GetAttributes(PI2.Attributes)
  MyInfo(idx).pComment = PointerToString(PI2.pComment)
'and so on - you can fill any info you need
'if it's string - use PointerToString function
'you can get a lot  of info you need from DV structure
'Then you can add a member to your MY_PRINTER_INFO struct.
'For example I add Orientation
  CopyMemory DM, ByVal PI2.pDevMode, LenB(DM)
  MyInfo(idx).Orientation = IIf(DM.dmOrientation = 1, "Portrait", "Landscape")
End Sub

Private Function PointerToString(p As Long) As String
   Dim s As String
   s = String(255, Chr$(0))
   CopyPointer2String s, p
   PointerToString = Left(s, InStr(s, Chr$(0)) - 1)
End Function

Private Function GetPrnStatus(flg As Long) As String
  Dim s As String
  s = "" 
  If (flg And PRINTER_STATUS_BUSY) Then s = s & "Busy;"
  If (flg And PRINTER_STATUS_ERROR) Then s = s & "Error;"
  If (flg And PRINTER_STATUS_PAPER_OUT) Then s = s & "Paper out;"
' and so on for all flags you need
  GetPrnStatus = s
End Function

Private Function GetJobStatus(flg As Long) As String
  Dim s As String
  s = "" 
  If (flg And JOB_STATUS_PAUSED) Then s = s & "Paused;"
  If (flg And JOB_STATUS_ERROR) Then s = s & "Error;"
' and so on for all flags you need
  GetJobStatus = s
End Function

Private Function GetAttributes(flg As Long) As String
  Dim s As String
  s = "" 
  If (flg And PRINTER_ATTRIBUTE_DEFAULT) Then s = s & "Default;"
  If (flg And PRINTER_ATTRIBUTE_QUEUED) Then s = s & "Queued;"
  If (flg And PRINTER_ATTRIBUTE_SHARED) Then s = s & "Shared;"
  If (flg And PRINTER_ATTRIBUTE_NETWORK) Then s = s & "Network;"
  If (flg And PRINTER_ATTRIBUTE_LOCAL) Then s = s & "Local;"
' and so on for all flags you need
  GetAttributes = s
End Function

Public Function EnumJobs(pNum As Integer) As Long
  Dim ResBuffer(0 To 127) As Byte, tmpBuf As Byte
  Dim ByteNeed As Long, nJobs As Long
  Dim i As Integer, p As Long
  Dim lRet As Long
  Dim PD As PRINTER_DEFAULTS
  pName = MyInfo(pNum).pPrinterName
  PD.DesiredAccess = PRINTER_ACCESS_USE
  PD.pDatatype = vbNullString
  PD.pDevMode.dmSize = LenB(PD.pDevMode)
  lRet = OpenPrinter(pName, hPrn, PD)
  lRet = apiEnumJobs(hPrn, 0&, 127&, 1&, tmpBuf, 0&, ByteNeed, nJobs)
  If ByteNeed = 0 Then
     EnumJobs = 0
  Else
    lRet = apiEnumJobs(hPrn, 0&, 127&, 1&, ResBuffer(0), ByteNeed, ByteNeed, nJobs)
    p = VarPtr(ResBuffer(0))
    For i = 0 To nJobs - 1
        CopyMemory JI1, ByVal p, LenB(JI1)
        FillInfoJobs pNum, i
        p = p + LenB(JI1)
    Next i
    EnumJobs = nJobs
  End If
  lRet = CloseHandle(hPrn)
End Function

Private Sub FillInfoJobs(prnNum As Integer, idx As Integer)
'You can add members to your UDT or make another UDT for JobData. I use existing UDT
  MyInfo(prnNum).Status = GetJobStatus(JI1.Status)
  MyInfo(prnNum).PagesTotal(idx) = JI1.TotalPages
  MyInfo(prnNum).PagesPrinted(idx) = JI1.PagesPrinted
  'e.t.c
End Sub
if you use the setjob function just set Command parameter to action you want to take and set Level to 0 and pJob to NULL
Look at enumerates all of the jobs ---
http://www.vbapi.com/ref/e/enumjobs.html
ASKER CERTIFIED SOLUTION
Avatar of Ruchi
Ruchi

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thankyou Ruchi, it's help me verymuch

Thank you again