Canceling a print job

  • Thread starter Thread starter nobody
  • Start date Start date
N

nobody

If I know the name of a print job, how can I cancel it? I've been tasked
with writing an application that monitors another application and prevents
it from printing. I can monitor the Windows Print Queue and get called
everytime a new job appears (using System.Management.ManagementEventWatcher)
and check it's name to see if it's my print job. But then how can I
actually cancel that job? Is there a PrintQueue class somewhere in the vast
..NET framework?
 
Thanks. If I have too, I'm not adverse to the idea of canceling all
printjobs if they try to print from that application. Hmm... I wontder if
my client would accept dissabling all printing from the machines this app is
installed... I could cancel all print jobs everytime one is started from
any application. :)

My only question is... Why would MS not put something as obvious as Cancel
on the Win32_PrintJob class?
 
It's not working. If I pause the printer and start my app, then print
something, it pops into the queue and my program cancels it. No problem.
But if I don't pause the printer, then the job squeeks by and prints before
my app can cancel it.

Here's the code I'm currently using. Any suggestions? Alternate ideas? I
originally didn't think it would be so difficult to prevent a program from
printing. :(

Imports System.Windows.Forms
Imports System.ComponentModel
Imports System.Runtime.InteropServices
Imports System.Management

Friend Class PrintJobStopper
Private WithEvents m_Watcher As ManagementEventWatcher = Nothing
Private m_PrintJobName As String

Public Sub New(ByVal PrintJobName As String)
m_PrintJobName = PrintJobName.Trim().ToUpper()
StartPrintMonitor()
End Sub

Private Sub StartPrintMonitor()
Dim q As WqlEventQuery
' Bind to local machine
Dim scope As New ManagementScope("root\CIMV2")
Try
q = New WqlEventQuery
q.EventClassName = "__InstanceOperationEvent"
q.Condition = "TargetInstance ISA 'Win32_PrintJob'"
q.WithinInterval = New TimeSpan(0, 0, 0, 1, 250)
m_Watcher = New ManagementEventWatcher(scope, q)
m_Watcher.Start()

Catch ex As Exception
' Just rudely throw it back to the caller.
Throw ex
End Try
End Sub

Friend Sub StopPrintJobMonitor()
If Not m_Watcher Is Nothing Then
m_Watcher.Stop()
End If
End Sub

Private Sub m_Watcher_EventArrived(ByVal sender As Object, ByVal e As
System.Management.EventArrivedEventArgs) Handles m_Watcher.EventArrived
Dim Msg As String = ""
For Each pd As PropertyData In e.NewEvent.Properties
Dim mbo As ManagementBaseObject = CType(pd.Value,
ManagementBaseObject)
If Not mbo Is Nothing Then
If mbo.ClassPath.ToString.ToUpper.EndsWith("WIN32_PRINTJOB")
Then
If
mbo("Document").ToString.Trim.ToUpper.IndexOf(m_PrintJobName) > -1 Then
Dim Printers As New
Management.ManagementObjectSearcher("SELECT * FROM Win32_Printer")
For Each Printer As Management.ManagementObject In
Printers.Get()
Printer.InvokeMethod("CancelAllJobs", Nothing)
Next Printer
Printers = Nothing
Exit For
End If ' Our print job?
End If ' Win32_PrintJob class?
End If ' Not mbo Is Nothing
Next pd
End Sub
End Class
 
Back
Top