C#-无法捕获打印结束



我有一台打印机(HP PageWide MFP P57750),通过以太网电缆连接到专用网络。在一个简单的C#Web应用程序中,用户向打印机发送一个pdf文件,并设置要打印的份数。打印结束时,应用程序应通知作业结束。

我尝试使用PrintDocument的EndPrint事件,但它似乎在错误的时间启动,因为打印机仍在打印。

我也尝试将PrintQueue与PrintJobInfoCollection一起使用,但它只是第一次返回"Printing"PrintJobStatus。然后,我等待了5秒钟,然后重新检查状态,但在打印机仍在打印时,队列中没有作业!

我在"控制面板"->"设备和打印机"中看到作业的进度。即使有许多副本并且打印机仍在打印,打印也只持续几秒钟。我认为在客户端将要打印的文件发送到打印机后,该作业会被删除。

我怎样才能看到打印的真正结束?

PdfDocument pdf = new PdfDocument();
pdf.LoadFromFile(filePath);
pdf.PrinterName = CicloStampa.Properties.Settings.Default.NomeStampante;
pdf.PrintDocument.PrinterSettings.Copies = (short)numeroCopie;          
pdf.PrintDocument.Print();
PrintServer myPrintServer = new PrintServer();
PrintQueue pq = myPrintServer.GetPrintQueue(CicloStampa.Properties.Settings.Default.NomeStampante);
var printing = true;
while (printing)
{
    pq.Refresh();
    PrintJobInfoCollection pCollection = pq.GetPrintJobInfoCollection();
    foreach (PrintSystemJobInfo job in pCollection)
    {
       //SpotTroubleUsingJobAttributes returns KO/OK by matching PrintJobStatus. First time returns PrintJobStatus.Priting. Second time, pCollection is empty and the printer is still printing.
       var res = SpotTroubleUsingJobAttributes(job);
       System.IO.File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + @"LogsLogImportazione.txt", DateTime.Now.ToString() + " ---- ttt RES: " + res + "n");
       if (res.StartsWith("KO"))
       {
          //DO STUFF                       
       }
       else
       {
          //END OF PRINT
          printing = false;
        }
     }
     if (pCollection.Count() == 0)
     {                                    
        printing = false;
     }
     if (printing)
     {                                                                       
         System.Threading.Thread.Sleep(5000);
     }
}

所以我一直在使用PDF24打印机,但这应该适用于所有打印机。

感谢@mark_h提供的代码。使用他的代码示例,我设法找到了一种方法来知道打印队列何时为"0";完成";。在打印之前,您必须暂停打印队列,因此根据具体情况,应该留出一些执行时间。

添加完打印队列后,我会对其中的文档进行计数,以便知道打印机何时打印完所有文档。然后在第二个循环中,我们将不断减去打印的文档。一旦我们到达队列中的最后一个文档,我们就会跳出循环,让线程休眠几秒钟,给打印机时间来完成它

然后,我们可以自由执行任何代码,因为我们知道打印作业都已打印完毕。

要赶上打印结束,以下代码将起作用:

            PrintServer printS = new PrintServer();
            PrintQueue printQ = new PrintQueue(printS, "PDF24", PrintSystemDesiredAccess.AdministratePrinter);
            printQ.Pause();

            // Now right here place printing logic, after queue is paused
          
            PrintJobInfoCollection jobs = printQ.GetPrintJobInfoCollection();
            int printCount = 0;
            foreach (var job in jobs)
            {
                printCount++;
            }
            printQ.Resume();
            foreach (var job in jobs)
            {
                var done = false;
                while (!done)
                {
                    printQ.Refresh();
                    job.Refresh();
                    done = job.IsCompleted || job.IsDeleted || job.IsPrinted;
                }
                if (done)
                {
                    printCount--;
                }
                if (printCount < 1)
                {
                    break;
                }
            }
            // Allow some time for the last document to execute, then run what ever code you want
            Thread.Sleep(3000);

我希望这会有所帮助,否则请留下评论,如果需要的话,我可以提供更多的代码示例。真不敢相信要弄清楚一台打印机是否完成了打印竟然如此困难。

您可以获得打印队列上的作业集合,然后继续循环,直到获得您要查找的作业状态。

        var myPrintServer = new LocalPrintServer();
        var pq = myPrintServer.GetPrintQueue("Printer Name");
        var jobs = pq.GetPrintJobInfoCollection();
        foreach (var job in jobs)
        {
            var done = false;
            while (!done)
            {
                pq.Refresh();
                job.Refresh();
                done = job.IsCompleted || job.IsDeleted || job.IsPrinted;
            }
        }

编辑

PrintQueue也有IsPrinting、IsWaiting、IsBusy等属性,您也可以在while循环中查看这些属性,但这些属性会告诉您打印机的一般情况,而不是您的工作,因此如果其他人决定在您打印时打印,您可能会得到误导性信息

最新更新