How to catch print jobs in C# .NET

21,335

Solution 1

I found the solution. For those are searching for a way to handle print job events take a look:

FindFirstPrinterChangeNotification

and also a working code can be found Monitoring print jobs

Solution 2

I had the same requirement where I tried implementing as suggested by Mert Akcakaya in his answer. This works all fine but might stop if by any chance a windows service Print Spooler stops working.

So instead, I have implemented using WMI. A detail explanation is provided in this Codeproject article here

Referring to this article, I had written a below piece of code that keeps monitoring the printer jobs. Here I am only interested in the print job Spooling.

   internal void MonitorPrinterJobs()
        {                
            try
            {
                Task.Run(async delegate
                   {
                       while (true)
                       {
                           string searchQuery = "SELECT * FROM Win32_PrintJob";
                           ManagementObjectSearcher searchPrintJobs = new ManagementObjectSearcher(searchQuery);
                           ManagementObjectCollection prntJobCollection = searchPrintJobs.Get();
                           foreach (ManagementObject prntJob in prntJobCollection)
                           {
                               string jobName = prntJob.Properties["Name"].Value.ToString();
                               string jobStatus = Convert.ToString(prntJob.Properties["JobStatus"]?.Value);

                               if (jobStatus == "Spooling")
                               {
                                  // do job
                               }
                           }
                           await Task.Delay(100);
                       }
                   });
            }
            catch (Exception ex)
            {
               // handle exception
            }
        }
Share:
21,335
Mert Akcakaya
Author by

Mert Akcakaya

Updated on April 28, 2020

Comments

  • Mert Akcakaya
    Mert Akcakaya about 4 years

    I am trying to catch every print jobs submitted to printer in our local network. I want to display some properties of the job like job name, submit time and so on.

    I tried a while loop but it didn't catch my print job, maybe beacuse it happened while the thread was sleeping. Is there an event that I can register and handle? I don't want to spend all of the CPU resource for this task infinetly looping.

    I tried this:

    public static void WritePrinterJobs()
        {
            while (true)
            {
                foreach (var job in LocalPrintServer.GetDefaultPrintQueue().GetPrintJobInfoCollection())
                {
                    Console.WriteLine(job.Submitter + " " + job.TimeJobSubmitted.ToShortDateString());
                }
                Thread.Sleep(100);
            }
        }
    

    EDIT: The code above actually works, you don't need to go lower level if it does work for you, my mistake was not configuring default printer correctly.