Printing 使用RawPrinterHelper类查询Zebra打印机状态

Printing 使用RawPrinterHelper类查询Zebra打印机状态,printing,status,zebra-printers,thermal-printer,zpl,Printing,Status,Zebra Printers,Thermal Printer,Zpl,我正在使用微软的RawPrinterHelper类,从C#code打印到Zebra KR403打印机上,一切正常 我希望监控打印机的卡纸和纸张中断状态。我找到了一个可以发送到打印机的查询,“~HQES”或“esc eng 6”,它将返回我需要的所有信息。问题是,我无法确定如何将此查询发送到打印机,以允许打印机响应。RawPrinterHelper类中的WritePrinter似乎只返回bool或long类型 我还尝试使用Win32\u打印机对象查找打印机的PrinterStatus/Printe

我正在使用微软的
RawPrinterHelper
类,从C#code打印到Zebra KR403打印机上,一切正常

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

我还尝试使用
Win32\u打印机
对象查找打印机的
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;
利用此方法,我尝试获取
PrinterState
PrinterStatus
、以及
DetectedErrorState
,但这些都没有响应我所需的信息
PrinterState
始终返回
1024
PrinterStatus
始终返回
4
DetectedErrorState
始终返回
2
。虽然
PrinterState
在正确打印时返回
0
,在卡纸或介质输出事件中返回
1024
进行一些打印,但现在每次调用时它只返回
1024

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

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

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

谢谢你的建议


Jeremy

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

但我已经接近了,做了以下工作:

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

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

  • 这就是我接近打印机状态的原因

    正在添加代码以显示如何使用.NET打印队列对象完成此操作:

    有关启动代码的printqueue对象,请参阅

    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");
    }
    

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

    我不确定代码的具体内容,因为我没有编写
    WinUSB
    驱动程序,也没有访问其代码的权限


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

    我已经有几年没有做过ZPL了……Zebra支持PJL吗?如果是这样的话,你也许可以使用它。谢谢道格拉斯。我认为这台打印机(KR403)不支持PJL。我不确定,但我还没有找到任何文献表明它确实如此。我可以将ZPL
    ~HQES
    命令发送到打印机,但无法在代码中读取打印机的回复。目前,我正在尝试实现中所述的
    GetPrinterData
    ,但每次启动线程时程序都会崩溃。在向Zebra支持团队发送电子邮件后,我被告知KR403打印机驱动程序不支持
    GetPrinterData
    。这是为Zebra生产的另一台kiosk打印机。谢谢你的回答,Micah。我能够查询WMI对象并接收一个代码,但这并没有使我能够接收到与打印机的
    ~HQES
    查询一样多的信息。
    ~HQES
    查询将告诉我打印机的纸张是否不足、页眉是否阻塞以及来自不同传感器的信息。我会对这个“PrinterDiagnosticFacade”做一些研究,看看我能找到什么。NET PrintQueue也有大量这样的信息--请查看从中可以获得的所有甜蜜的诊断布尔值。虽然如果您对~HQES感到满意,我不会为我的建议费心。NET打印队列肯定有一些很好的布尔值。我会尝试将它与WMI
    Win32\u Printer
    对象结合使用,但现在我已被转移到另一个项目。如果我没有使用
    System.Print
    进行打印,打印队列是否可用?谢谢演示。使用起来似乎很简单。如果我被重新分配到那个项目,我会试试的。我想要+1,但我没有足够的声誉。