我有一台打印机(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循环中查看这些属性,但这些属性会告诉您打印机的一般情况,而不是您的工作,因此如果其他人决定在您打印时打印,您可能会得到误导性信息