2012-08-02 81 views
14

我有一个应用程序,我需要打印一张票。每张票必须是唯一的。该应用程序是Windows窗体,并完全用C#编写。对于我们的应用,我们使用的是三星ML-2525激光单色打印机。有没有办法检查打印过程是否成功?

的流动基本上是下文中,操作者选取一个产品/票(这是唯一的),然后将其按下按钮,做两两件事:

  1. 连接数据库和所用更新的产品
  2. 在一段打印票据(这是使用System.Drawing中和GDI +完成)

出于某种原因,每一次,需要被印刷的图像不被发送到打印机。这是一种罕见的情况,但它发生了。

我试图使用Win32_Printer(http://msdn.microsoft.com/en-us/library/Aa394363)连接打印机,但无法获取当前打印机的状态(联机,脱机,墨粉不足,卡纸等)。我只能检查打印机是否存在,以及纸张尺寸是否正确安装。我尝试了类似于以下代码但它没有工作

private string MonitorPrintJobWmi() 
    { 
     var jobMessage = String.Empty; 
     var scope = new ManagementScope(ManagementPath.DefaultPath); 
     scope.Connect(); 

     var selectQuery = new SelectQuery { QueryString = @"select * from Win32_PrintJob" }; 

     var objSearcher = new ManagementObjectSearcher(scope, selectQuery); 
     var objCollection = objSearcher.Get(); 

     foreach (var job in objCollection) 
     { 
      if (job != null) 
      { 
       jobMessage += String.Format("{0} \r\n", job["Name"].ToString()); 
       jobMessage += String.Format("{0} \r\n", job["JobId"].ToString()); 
       _jobId = Convert.ToInt32(job["JobId"]); 
       jobMessage += String.Format("{0} \r\n", job["JobStatus"].ToString()); 
       jobMessage += String.Format("{0} \r\n", job["Status"].ToString()); 
      } 
     } 
     return jobMessage; 
    } 

我试图获得打印机的API,但我无法得到它的持有。顺便说一下,打印机的软件确实在窗口工具栏中指出了不同的错误。

我的问题是,如果任何人都可以带领我正确地确定如何连接到打印机并检查打印是否成功。

此外,如果有人知道某些其他特定的打印机,我可以在其中完成此操作(即更改硬件),将会有所帮助。

感谢,

+0

请参阅:http://stackoverflow.com/questions/1921487/confirm-successful-print-programmatically-in-windows – Eugene 2012-08-02 02:44:45

+0

我做了,但一些示例代码,以获得先机将是有益的。 – lopezbertoni 2012-08-02 03:04:22

+2

@lopezbertoni一个小谷歌会告诉你如何在C#应用程序中使用这些链接的方法...像http://www.codeproject.com/Articles/51085/Monitor-jobs-in-a-printer-queue-NET – 2012-08-02 03:08:25

回答

5

要获得打印队列的本地计算机上的列表,请尝试打印服务器的GetPrintQueues方法。

一旦您有与相关打印机关联的PrintQueue对象的实例,就可以使用它来访问打印机的状态(IsOffline,IsPaperOut等)。此外,您可以使用它来获取给定队列中的作业列表(GetPrintJobInfoCollection),然后该列表将允许您获取作业特定的状态信息(IsInError,IsCompleted,IsBlocked等)。

希望这会有所帮助!

+1

感谢您的意见。我确实尝试过使用你提到的方法,但我没有成功。主要问题是作业进入队列,然后从中消失,并且打印机不能完成打印作业。 – lopezbertoni 2012-09-15 19:00:27

+0

如果您在将作业发送到打印机之前开始观看队列,我想知道是否可以在队列中出现时立即赶上作业.... – 2012-09-17 12:29:58

+0

为什么这不会被标记为答案?这对我非常有帮助。我能够通过查看特定客户端PrintQueue.Submitter发送的作业数量来实现这一目标,然后在尝试打印后,我得到了新添加的作业列表并进行简单检查以确保它们已完成。您还可以通过此API获取每一项作业或打印机本身的状态。甚至有工作ID和票证信息。 – 2014-11-04 16:49:58

0

尝试打印PrintDocument(System.Drawing.Printing)后,尝试检查printjobs的状态。

第一步:初始化您的printDocument。

第二步:获取您的打印机名称从System.Drawing.Printing.PrinterSettings.InstalledPrinters.Cast<string>();

并将其复制到您的printerDocument.PrinterSettings.PrinterName

第三步:尝试打印和处理。

printerDocument.Print(); 
printerDocument.Dispose(); 

最后一步:在任务中运行检查(不要屏蔽UI线程)。

Task.Run(()=>{ 
    if (!IsPrinterOk(printerDocument.PrinterSettings.PrinterName,checkTimeInMillisec)) 
    { 
     // failed printing, do something... 
    } 
    }); 

下面是执行:

private bool IsPrinterOk(string name,int checkTimeInMillisec) 
    { 
     System.Collections.IList value = null; 
     do 
     { 
      //checkTimeInMillisec should be between 2000 and 5000 
      System.Threading.Thread.Sleep(checkTimeInMillisec); 
      // or use Timer with Threading.Monitor instead of thread sleep 

      using (System.Management.ManagementObjectSearcher searcher = new System.Management.ManagementObjectSearcher("SELECT * FROM Win32_PrintJob WHERE Name like '%" + name + "%'")) 
      { 
       value = null; 

       if (searcher.Get().Count == 0) // Number of pending document. 
        return true; // return because we haven't got any pending document. 
       else 
       { 
        foreach (System.Management.ManagementObject printer in searcher.Get()) 
        { 
         value = printer.Properties.Cast<System.Management.PropertyData>().Where(p => p.Name.Equals("Status")).Select(p => p.Value).ToList(); 
         break; 
        } 
       } 
      } 
     } 
     while (value.Contains("Printing") || value.Contains("UNKNOWN") || value.Contains("OK")); 

     return value.Contains("Error") ? false : true;  
    } 

好运。

相关问题