Search code examples
c#wpfprintingspoolerprint-job-control

With a physical printer, the result of.CurrentPrintTicket.PageMediaSize.PageMediaSizeName is always ISOA4


When I use the PrintServer class in c#, I get the print queues as well as the print jobs, but with an iR-ADVC3525 or with other physical printers, the result of printJob.HostingPrintQueue.CurrentJobSettings.CurrentPrintTicket.PageMediaSize.PageMediaSizeName.ToString() is always ISOA4. Even when I define the ISOA3 or other format.

I tried to set my physical printer preferences to A3. So printJob.HostingPrintQueue.CurrentJobSettings.CurrentPrintTicket.PageMediaSize.PageMediaSizeName.ToString() is ISOA3.

However, I want to retrieve information from the print spooler and not from the preferences

I've tried with Microsoft Print to PDF (virtual printer used to create PDF) and I get the ISOA3 format when I define it.

Here's my code that iterates over print jobs:

 public void CatchJobs()
 {
     PrintServer printServer = new PrintServer();
     PrintQueueCollection printQueues = printServer.GetPrintQueues();
     foreach (PrintQueue printQueue in printQueues)
     {
         printQueue.Refresh();
         if (printQueue.GetPrintJobInfoCollection() != null)
         {
             PrintJobInfoCollection printJobs = printQueue.GetPrintJobInfoCollection();

             foreach (PrintSystemJobInfo printJob in printJobs)
             {
                 Job job = new Job(printJob);
                 if (printJob.JobStatus.HasFlag(PrintJobStatus.Printed) && !Jobs.Contains(job))
                 {
                     lock (Jobs)
                     {
                         Jobs.Add(job);
                     }
                 }
             }
         }
     }
 }

Here's the constructor of my Job class:

 public Job(PrintSystemJobInfo printJob)
 {
     Name = printJob.Name;
     Status = printJob.JobStatus.ToString();
     Owner = Environment.UserName;
     Priority = printJob.Priority.ToString();
     TimeSubmitted = printJob.TimeJobSubmitted;
     Color = printJob.HostingPrintQueue.CurrentJobSettings.CurrentPrintTicket.OutputColor.Value.ToString();
     DriverName = printJob.HostingPrintQueue.FullName;
     JobId = printJob.JobIdentifier;
// Problem HERE
     string? paperSize = printJob.HostingPrintQueue.CurrentJobSettings.CurrentPrintTicket.PageMediaSize.PageMediaSizeName.ToString();
// End problem
 
     PaperSize = paperSize is null ? "format inconnu" : paperSize;
     double? paperLenght = printJob.HostingPrintQueue.CurrentJobSettings.CurrentPrintTicket.PageMediaSize.Height;
     double? paperWidth = printJob.HostingPrintQueue.CurrentJobSettings.CurrentPrintTicket.PageMediaSize.Width;
     PaperLength = paperLenght is null ? 0 : Math.Round((double)paperLenght * _pixelSize);
     PaperWidth = paperWidth is null ? 0 : Math.Round((double)paperWidth * _pixelSize);
     TotalPages = printJob.NumberOfPages;
 }

can you help me?


Solution

  • I hope this solution will work with an iR-ADVC3525 or other physical printer.

    With a Brother MFC-L8690CDW series printer, using managementObject from System.Management. I get the right information with this constructor:

            public Job(ManagementObject printJob)
            {
                Name = printJob["Name"].ToString();
                Status = printJob["Status"].ToString();
                Owner = printJob["Owner"].ToString();
                Priority = printJob["Priority"].ToString();
                TimeSubmitted = ManagementDateTimeConverter.ToDateTime(printJob["TimeSubmitted"].ToString());
                Color = printJob["Color"].ToString();
                DriverName = printJob["DriverName"].ToString();
                JobId = int.Parse(printJob["JobId"].ToString());
                PaperSize = printJob["PaperSize"].ToString();
                PaperLength = double.Parse(printJob["PaperLength"].ToString()) / 10;
                PaperWidth = double.Parse(printJob["PaperWidth"].ToString()) / 10;
                TotalPages = int.Parse(printJob["TotalPages"].ToString());
            }
    

    to get the ManagementObject, i do this:

    public void CatchJobs()
    {
        string statusToCheck = "OK"; // Remplacez "Printed" par le statut recherché
    
        try
        {
            ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PrintJob");
            ManagementObjectCollection printJobs = searcher.Get();
    
            foreach (ManagementObject printJob in printJobs)
            {
                string status = printJob["Status"].ToString();
                if (status.Equals(statusToCheck, StringComparison.OrdinalIgnoreCase))
                {
                    Job job = new Job(printJob);
                    if (!Jobs.Contains(job))
                    {
                        lock (Jobs)
                        {
                            Jobs.Add(job);
                        }
                    }
                }
            }
        }
        catch (ManagementException e)
        {
            Console.WriteLine("Erreur : " + e.Message);
        }
    }