【问题标题】:Is there a way to check if a printing process was successful?有没有办法检查打印过程是否成功?
【发布时间】:2023-03-09 22:13:01
【问题描述】:

我有一个需要打印票证的应用程序。每张票必须是唯一的。该应用程序是 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,但无法获得它。顺便说一句,打印机的软件确实会在 windows 工具栏中显示不同的错误。

我的问题是,是否有人可以引导我了解如何连接打印机并检查打印是否成功。

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

谢谢,

【问题讨论】:

  • 我做到了,但是一些示例代码可以帮助您抢占先机。
  • @lopezbertoni 用谷歌搜索一下会告诉你如何在 C# 应用程序中使用这些链接方法...比如 codeproject.com/Articles/51085/…
  • 您的方案是否允许您的“重印”按钮首先使后端的第一个“独特”产品无效,这样如果有人要展示它,它将被拒绝,从而防止滥用? (是带有条形码的东西吗?)
  • @tomfanning 我们考虑过,但是这会让 POS 的收银员多次重印同一张票(窃取)。即使这张票可能被拒绝,客户仍然支付了它,并且不知道收银员重新打印了它。这就是为什么我们认为与打印机通信是使操作更容易的关键。希望这可以帮助。是的,它是带有条形码的东西。

标签: c# winforms printing system.printing


【解决方案1】:

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

第一步:初始化你的 printDocument。

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

并将其复制到您的打印机Document.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;    
    }

祝你好运。

【讨论】:

    【解决方案2】:

    要获取本地计算机上的打印队列列表,请尝试 PrintServer 的 GetPrintQueues 方法。

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

    希望这会有所帮助!

    【讨论】:

    • 感谢您的意见。我确实尝试过使用您提到的方法,但没有成功。主要问题是作业进入队列,然后从队列中消失,打印机没有完成打印作业。
    • 如果您在将作业发送到打印机之前就开始查看队列,我想知道您是否可以在作业出现在队列中时立即捕获它......
    • 为什么这没有被标记为答案?这对我帮助很大。通过查看从特定客户端PrintQueue.Submitter 发送的作业数量,我能够使其工作,然后在尝试打印后,我得到了新添加的作业列表并简单地检查以确保它们已完成。您还可以通过此 API 获取每个作业或打印机本身的状态。甚至还有工作 ID 和工单信息。
    • 它没有被标记为答案,因为这只是报告作业已发送到打印机。并不是说打印机实际上已成功完成。
    猜你喜欢
    • 1970-01-01
    • 2013-08-26
    • 2021-08-11
    • 2022-11-24
    • 1970-01-01
    • 2023-01-14
    • 1970-01-01
    • 2011-07-17
    • 1970-01-01
    相关资源
    最近更新 更多