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.
In Windows, a built-in service called Print Spooler temporarily stores all print jobs until they're printed. These print jobs are stored by Windows as files in a folder associated with the Print Spooler service.
Use the qchk command to display the current status information regarding specified print jobs, print queues, or users. Note: The base operating system also supports the BSD UNIX check print queue command (lpq) and the System V UNIX check print queue command (lpstat).
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
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
            }
        }
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With