none
Collecting all printjobs with WMI query "Win32_Printjob" is taking a lot of time.Any alternatives? RRS feed

  • Question

  •  

    I use ManagementObjectSearcher class and using the query ,"SELECT * FROM Win32_PrintJob" to get all print job.But enumerating all printjob is taking lot of time.Is there any other ways to enumerate these printjob.How can i directly use the Win32 API to enumerate thses printjob

     

    //code snippet which i am using to get all the printjob, and it's causing problem(taking a long time)

    string query = "SELECT * FROM Win32_PrintJob"

    ManagementObjectsearcher search = new ManagementObjectsearcher(query);

    ManagementObjectCollection collection =  search.Get();

     

    Help me to solve it out.Any suggestion or solution will be of great help for me.

    Thanks,

     

    Thursday, May 8, 2008 10:51 AM

All replies

  • The time it takes will depend on how much stuff is on connected Printers at any given time.  The approach I use is to create a ManagementEventWatcher which allows you to receive Asynchronous notification of newly arrived Print Jobs, though you may need a different approach depending on what you actually want to do with the Print Jobs.  This code forms part of a class in an Application I'm building which Monitors Printers and required End Users to Confirm Print Jobs and Charges them for each Jop Printed.

    Creating the Event Watcher

    Me.objWatcher = New ManagementEventWatcher
    Me.objWatcher.Query = New EventQuery("SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_PrintJob'")
    Me.objWatcher.Scope = New ManagementScope("\\" & My.Computer.Name & "\root\cimv2")

    Me.objWatcher.Start()
    Handling the EventArrived event

    Private Sub objWatcher_EventArrived(ByVal sender As Object, ByVal e As System.Management.EventArrivedEventArgs) Handles objWatcher.EventArrived
        Dim intJobID As Integer

        Try
           Dim objMgmt As ManagementBaseObject
           objMgmt = e.NewEvent.Properties("TargetInstance").Value
           intJobID = objMgmt.Item("jobid")

           'Get the WMI Job
           Dim objQuery As New ManagementObjectSearcher("SELECT * FROM Win32_PrintJob WHERE jobid='" & intJobID & "'")
           Dim objPossJob, objJob As ManagementObject
           objJob = Nothing

           For Each objPossJob In objQuery.Get
               If CInt(objPossJob.Item("jobid")) = intJobID Then
                  objJob = objPossJob
                  Exit For
               End If
           Next

           If Not objJob Is Nothing Then
              RaiseEvent NewJob(objJob)
           Else
              RaiseEvent MissedJob(intJobID)
           End If
        Catch ex As Exception
           RaiseEvent Exception(ex)
        End Try
    End Sub

    Wednesday, June 11, 2008 11:59 AM
  • Hi,

    Did you guys get this sorted out? I'm trying to get the number of successfully printed pages using this approach but for some reason it goes brain dead when trying to get the JobId. Here is my code and where it goes brain dead is commented:
    static void Main(string[] args)  
            {  
                String strMachine = ".";  
                strMachine = Environment.MachineName;  
     
                ManagementEventWatcher mewPrintJobs = new ManagementEventWatcher();  
                //mewPrintJobs.Scope = new ManagementScope("winmgmts:\\\\" + strMachine + "\\root\\cimv2");  
                mewPrintJobs.Query =  
                    new EventQuery("SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA \"Win32_PrintJob\"");  
                mewPrintJobs.EventArrived += new EventArrivedEventHandler(mewPrintJobs_EventArrived);  
                mewPrintJobs.Start();  
     
                Console.ReadLine();  
     
                mewPrintJobs.Stop();  
            }  
     
            static void mewPrintJobs_EventArrived(object sender, EventArrivedEventArgs e)  
            {  
                ManagementObject moPagesSent = null;  
                Int32 iJobId = 0;  
                ManagementBaseObject mbo = e.NewEvent;  
     
                if(mbo != null)  
                    iJobId = (Int32)mbo["JobId"];// Gets "unplugged" here  
     
                ManagementObjectSearcher searcher =  
                    new ManagementObjectSearcher("SELECT * FROM Win32_PrintJob WHERE JobId=\'" + iJobId.ToString() + "\'");  
     
                foreach (ManagementObject obj in searcher.Get())  
                {  
                    if (((Int32)obj["JobId"]) == iJobId)  
                    {  
                        moPagesSent = obj;  
                        break;  
                    }  
                }  
     
                if(moPagesSent != null)  
                    Console.WriteLine("Printed " + ((UInt32)moPagesSent["PagesPrinted"]).ToString() + " pages.");  
            } 

    Thanks in advance,

    humble.apprentice
    Thursday, December 4, 2008 3:03 PM
  • Take a look at the EventArrived method:
    The e.NewEvent contains the InstanceCreationEvent that triggered the mewPrintJobs.EventArrived event.

    In order to reach the PrintJob and retrieve its JobId you will need to drilldown a little deeper.
    If you walk through all the e.NewEvent properties you will find one called "TargetInstance" and that is holding the print job you want.

    Try this:

            void printJobArrived_EventArrived(object sender, EventArrivedEventArgs e)
            {
                foreach (PropertyData prop in e.NewEvent.Properties)
                {
                    string val = prop.Value == null ? "null" : prop.Value.ToString();
                    Debug.WriteLine(prop.Name + ": " + val);
                }

                ManagementBaseObject printJob = (ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value;

                foreach (PropertyData prop in printJob.Properties)
                {
                    string val = prop.Value == null ? "null" : prop.Value.ToString();
                    Debug.WriteLine(prop.Name + ": " + val);
                }

            }

    After the InstanceCreationEvent properties, you will see all the properties of the PrintJob.

    Tuesday, January 6, 2009 5:58 PM
  • Thanks Rui, the EventArrivedEventArgs contained all I need as you said.

    Cheers,


    humble.apprentice
    Wednesday, February 11, 2009 11:06 AM
  • Hello.

    I'm trying to use this in VB / Windows7 with microsoft XPS virtual printer and it never return the good "totalpages" property value
    A document with 12 pages can return a number of totalpages between 1 and 12, and sometimes the print job is missed. 
    can someone help me ?

    _objWatcher = New ManagementEventWatcher
    _objWatcher.Query = New EventQuery("SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_PrintJob'")
    _objWatcher.Scope = New ManagementScope("\\" & My.Computer.Name & "\root\cimv2")
    AddHandler _objWatcher.EventArrived, AddressOf objWatcher_EventArrived    
    
    Private Sub objWatcher_EventArrived(ByVal sender As Object, ByVal e As System.Management.EventArrivedEventArgs)
    
            Try
                Dim job As ManagementBaseObject = CType(e.NewEvent.Properties("TargetInstance").Value, ManagementBaseObject)
    
                For Each p As PropertyData In job.Properties
                    Try
                        Console.WriteLine(p.Name & vbTab & vbTab & p.Value.ToString)
                    Catch ex As Exception
                        Console.WriteLine(p.Name & vbTab & vbTab & "NULL")
                    End Try
                Next
    
    
            Catch ex As Exception
                RaiseEvent Errlog(ex.ToString, True)
            End Try
    
        End Sub
    
    Wednesday, August 19, 2009 3:24 PM
  • Hello,

    You can use this, it works correctly.

     

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Dim objWatcher = New ManagementEventWatcher
        objWatcher.Query = New EventQuery("SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_PrintJob'")
        objWatcher.Scope = New ManagementScope("\\" & My.Computer.Name & "\root\cimv2")
        objWatcher.Start()
        AddHandler objWatcher.EventArrived, AddressOf objWatcher_EventArrived

    End Sub

    Private Sub objWatcher_EventArrived(ByVal sender As Object, ByVal e As System.Management.EventArrivedEventArgs)

        Dim job As ManagementBaseObject = CType(e.NewEvent.Properties("TargetInstance").Value, ManagementBaseObject)
        Dim StrHeader As String = ""
        Dim StrContent As String = ""
        For Each p As PropertyData In job.Properties
            Try
                MsgBox(p.Name & " : " & p.Value.ToString)
            Catch ex As Exception
                MsgBox(p.Name & " : Unknown")
            End Try
        Next

    End Sub

    Wednesday, February 2, 2011 8:24 PM