1

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

我希望监控打印机的卡纸和断纸状态。我找到了一个可以发送到打印机的查询“~HQES”或“esc eng 6”,它将返回我需要的所有内容。问题是我无法弄清楚如何将此查询发送到允许打印机响应的打印机。WritePrinter类中的似乎RawPrinterHelper只返回 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总是返回 a 1024PrinterStatus总是返回 a 4DetectedErrorState总是返回 a 2。虽然PrinterState确实0在正确打印和1024卡纸或媒体输出事件中返回了几次打印,但现在它只是1024在每次调用时返回。

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

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

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

感谢您的任何建议,

杰里米

4

2 回答 2

1

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

不过,我已经接近了,执行以下操作:

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

  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");
}
于 2011-12-08T17:13:05.937 回答
1

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

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

这个答案的要点是,WinUSB在任何状态查询可以工作之前,我们必须为打印机创建一个驱动程序。

于 2012-02-01T16:45:02.320 回答