【问题标题】:Querying Zebra printer status using RawPrinterHelper class使用 RawPrinterHelper 类查询 Zebra 打印机状态
【发布时间】:2012-01-04 05:21:48
【问题描述】:

我正在使用 Microsoft 的 RawPrinterHelperhttp://support.microsoft.com/kb/322091 从 C# 代码打印到 Zebra KR403 打印机,一切正常。

我希望监控打印机的卡纸和断纸状态。我找到了一个可以发送到打印机的查询“~HQES”或“esc eng 6”,它将返回我需要的所有内容。问题是我无法弄清楚如何将此查询发送到允许打印机响应的打印机。 RawPrinterHelper 类中的 WritePrinter 似乎只返回 bool 或 long 类型。

我还尝试使用Win32_printer 对象来查找打印机的PrinterStatus/PrinterState/Errors。使用以下方法:

public static string PrinterStateCheck(string szPrinterName)
    {
        string query = string.Format("SELECT * from Win32_Printer WHERE Name LIKE '%{0}%'", szPrinterName);
        ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
        ManagementObjectCollection collection = searcher.Get();
        string errorName = "";
        foreach (ManagementObject printer in collection)
        {
            int state = Convert.ToInt32(printer["PrinterState"]);
            errorName = state.ToString();
        }
        return errorName;

使用此方法,我尝试获取PrinterStatePrinterStatusDetectedErrorState,但这些都没有响应我需要的信息。 PrinterState 总是返回 1024PrinterStatus 总是返回 4DetectedErrorState 总是返回 2。尽管PrinterState 确实在正确打印时返回了0,在卡纸或媒体输出事件中返回了1024,但现在它只是在每次调用时返回1024

我还发现 Zebra 开发了自己的软件来监控网络上的打印机。问题是我们的打印机不在网络上,仅通过 USB 连接到客户端计算机。此外,我们希望在打印每张收据之前或之后检查打印机的状态。

我希望 winspool.Drv 有一些东西可以用来将原始数据发送到打印机并从打印机接收数据。

现在我正在使用winspool.DrvReadPrinter 函数,但该函数返回0,这意味着无法访问来自打印机的响应。这通常意味着打印机没有设置为双向通信,但我确信它是。在打印机属性的“端口”选项卡中选中“启用双向支持”复选框。此外,Zebra Setup Utilities 可以正确查询打印机并在其直接通信窗口中接收响应。

感谢您的建议,

杰里米

【问题讨论】:

  • 我已经有几年没有做过 ZPL了……Zebra 是否支持 PJL?如果是这样,您也许可以使用它。
  • 谢谢道格拉斯。我认为这台打印机(KR403)不支持 PJL。我不确定,但我还没有找到任何文献说它确实如此。我可以将 ZPL ~HQES 命令发送到打印机,但我无法在我的代码中读取打印机的回复。目前我正在尝试按照Zebra Language MonitorRC 中的描述实现GetPrinterData,但是每次启动线程时程序都会崩溃。
  • 在给 Zebra 支持团队发送电子邮件后,我被告知 KR403 打印机驱动程序不支持 GetPrinterData。它用于 Zebra 生产的另一台自助服务终端打印机。

标签: printing status zebra-printers thermal-printer zpl


【解决方案1】:

我做过一些非常相似的事情,我可以告诉你,在 .NET 中几乎没有办法监控打印作业。

我已经接近了,做了以下事情:

  1. 创建一个“PrinterDiagnosticsFacade”,用于查询 .NET PrintQueue 对象的状态和 WMI。两者都不总是准确的。合并两者的数据以确定打印机的真实状态。

  2. 调整打印机的设置,使打印作业留在队列中。这样,您可以通过对打印假脱机作业执行 WMI 查询来准确读取打印作业的状态。 (可以根据打印文件名进行匹配)

这就是我接近打印机状态的方式。

添加代码以显示它是如何使用 .NET 打印队列对象完成的:

有关启动代码的 printqueue 对象,请参见 http://msdn.microsoft.com/en-us/library/system.printing.printqueue.aspx

PrintQueue me = Queue; 
if (me != null)
{
    me.Refresh();
    //in this if else,
    //i purposefully put the ones that error out first
    //so that if multiple can be true at the same time
    //the errors will definitely take precedence
    if (me.HasPaperProblem)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Error, "Error: Has paper problem");
    }
    else if (me.IsDoorOpened)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Error, "Error: Door is open");
    }
    else if (me.IsManualFeedRequired)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Error, "Error: Printer needs manually fed");
    }
    else if (me.IsNotAvailable)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Error, "Error: Printer not available");
    }

    else if (me.IsOutOfMemory)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Error, "Error: Printer is out of memory");
    }
    else if (me.IsOutOfPaper)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Error, "Error: Printer is out of paper");
    }
    else if (me.IsOutputBinFull)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Error, "Error: Printer output bin is full");
    }
    else if (me.IsPaperJammed)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Error, "Error: Paper jam");
    }
    else if (me.IsOffline)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Offline, "Offline");
    }
    else if (me.IsBusy)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Busy, "Busy");
    }
    else if (me.IsInitializing)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Busy, "Initializing");
    }
    else if (me.IsIOActive)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Busy, "Sending and recieving data");
    }
    else if (me.IsProcessing)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Busy, "Processing");
    }
    else if (me.IsWarmingUp)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Busy, "Warming up");
    }
    else if (me.IsPendingDeletion)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Busy, "Deleting a job");
    }
    else if (me.IsPaused)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Paused, "Paused");
    }
    else if (me.IsPrinting)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Printing, "Printing");
    }
    else if (me.IsPowerSaveOn)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Ready, "In power save mode");
    }
    else
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Ready, "Ready");
}

【讨论】:

  • 感谢米卡的回答。我能够查询 WMI 对象并接收代码,但这并没有使我能够接收到与打印机的~HQES 查询一样多的信息。 ~HQES 查询会告诉我打印机是否缺纸,是否页眉被阻塞,以及来自不同传感器的信息。我将对这个“PrinterDiagnosticFacade”进行一些研究,看看能找到什么。
  • .NET PrintQueue 也有大量类似的信息——查看msdn.microsoft.com/en-us/library/… 以查看您可以从中获得的所有可靠的诊断布尔值。虽然如果您对 ~HQES 感到满意,我不会理会我的建议。
  • .NET PrintQueue 肯定有一些不错的布尔值。我会结合 WMI Win32_Printer 对象尝试此操作,但我现在已转移到另一个项目。如果我不使用 System.Print 进行打印,PrintQueue 是否可用?
  • 感谢演示。似乎真的很容易使用。如果我被重新分配到那个项目,我会试一试。我想 +1,但我的声望不够。
【解决方案2】:

我们最终利用的问题的解决方案是为打印机创建一个WinUSB 驱动程序。这样,设备就被视为 USB 设备。使用驱动程序创建了一个ZebraUSB 对象,并创建了一个名为WriteRead 的方法。使用WriteRead 方法,我们将~HQES 查询发送到打印机并收到响应。有时查询和响应之间会有一些滞后时间。为了解决这个问题,我们将响应设置为一个变量并使用不同的方法检索它。

我不确定代码的具体细节,因为我没有编写 WinUSB 驱动程序,也无权访问它的代码。

这个答案的要点是,我们必须先为打印机创建一个WinUSB 驱动程序,然后才能进行任何状态查询。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-17
    • 2013-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-20
    相关资源
    最近更新 更多