Mert Akcakaya
Mert Akcakaya

Reputation: 3149

How to catch print jobs in C# .NET

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.

Upvotes: 5

Views: 24699

Answers (2)

mabiyan
mabiyan

Reputation: 714

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
            }
        }

Upvotes: 2

Mert Akcakaya
Mert Akcakaya

Reputation: 3149

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

Upvotes: 5

Related Questions