我有一台打印机(HP PageWide MFP P57750)通过以太网电缆连接到专用网络。在简单的C#Web App中,用户将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 + @"\Logs\LogImportazione.txt", DateTime.Now.ToString() + " ---- \t\t\t 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);
}
}
答案 0 :(得分:1)
您可以获取打印队列上的作业集合,然后继续循环,直到获得您要查找的作业状态。
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循环中查看这些属性,但是这些会告诉你一般的打印机,而不是你的工作,所以如果其他人决定打印时你可能会得到误导性的信息
答案 1 :(得分:1)
所以我一直在使用 PDF24 打印机,但这应该适用于所有打印机。
感谢@mark_h 提供代码。使用他的代码示例,我设法找到了一种方法来了解打印队列何时“完成”。您将不得不在打印之前暂停打印队列,因此根据情况,应该留出一些执行时间。
添加到打印队列后,我会计算其中的文档数,以便知道打印机何时打印完所有文档。然后在第二个循环中,我们将在打印文档时不断减去文档。一旦我们到达队列中的最后一个文档,我们就会跳出循环并让线程休眠几秒钟,让打印机有时间完成它。
然后我们可以自由地执行任何代码,因为知道打印作业已经全部打印完毕。
为了赶上打印结束,以下代码将起作用:
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);
我希望这会有所帮助,否则请发表评论,如果需要,我可以提供更多代码示例。真不敢相信要弄清楚打印机是否完成了打印。