Запрос состояния принтера Zebra с использованием класса RawPrinterHelper - PullRequest
1 голос
/ 23 ноября 2011

Я использую класс RawPrinterHelper от Microsoft, http://support.microsoft.com/kb/322091, для печати на принтере Zebra KR403 из кода C #, и все работает нормально.

Я хочу отслеживать состояние принтера на наличие замятий бумаги и перебоев в работе.Я нашел запрос, который могу отправить на принтер "~ 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;

Используя этот метод, я попытался получить PrinterState, PrinterStatus и DetectedErrorState, но ни один из них не ответил с нужной мне информацией.PrinterState всегда возвращает 1024, PrinterStatus всегда возвращает 4, а DetectedErrorState всегда возвращает 2.Хотя PrinterState вернул 0 при правильной печати и 1024 на событии замятия бумаги или носителя для нескольких отпечатков, теперь он просто возвращает 1024 при каждом вызове.обнаружил, что Zebra создала собственное программное обеспечение для мониторинга принтеров в сети.Проблема в том, что наши принтеры не подключены к сети и подключены к клиентскому компьютеру только через USB.Кроме того, мы надеемся проверить состояние принтера до или после печати каждой квитанции.

Я надеюсь, что из winspool.Drv есть что-то, что я могу использовать для отправки необработанных данных на принтер иполучать данные обратно от принтера.

Сейчас я использую функцию ReadPrinter winspool.Drv, но функция возвращает 0, что означает, что ответ от принтера не доступен.Обычно это означает, что принтер не настроен для двунаправленной связи, но я уверен, что это так.Флажок «Включить двунаправленную поддержку» установлен на вкладке «Порты» свойств принтера.Кроме того, утилиты установки Zebra могут правильно запрашивать принтер и получать ответ в окне «Прямая связь».

Спасибо за любой совет,

Джереми

Ответы [ 2 ]

1 голос
/ 01 февраля 2012

Решением проблемы, которую мы в итоге использовали, было создание драйвера WinUSB для принтера. Таким образом, устройство рассматривается как устройство USB. Объект ZebraUSB был создан с использованием драйвера, а метод с именем WriteRead был создан. Используя метод WriteRead, мы отправили запрос ~HQES на принтер и получили ответ. Иногда между запросом и ответом существует некоторое отставание. Для борьбы с этим мы устанавливаем ответ переменной и извлекаем его другим способом.

Я не уверен в специфике кода, потому что я не кодировал драйвер WinUSB, и у меня нет доступа к его коду.

Суть этого ответа заключается в том, что нам пришлось создать драйвер WinUSB для принтера, прежде чем любой из запросов о состоянии мог работать.

1 голос
/ 08 декабря 2011

Я сделал что-то очень похожее, и я могу сказать вам, что практически нет способа контролировать задания на печать в .NET.

Я подошел близко, делая следующее:

  1. Создайте «PrinterDiagnosticsFacade», который запрашивает состояние объекта .NET PrintQueue и WMI. Ни один не всегда точен. Объедините данные обоих, чтобы определить истинное состояние принтера.

  2. Настройте параметры принтера так, чтобы задания печати оставались в очереди. Таким образом, вы можете точно прочитать состояние задания на печать, выполнив WMI-запрос для заданий на печать. (Вы можете сравнить с именем файла печати)

Вот как я приблизился к получению статуса принтера.

Добавление кода, чтобы показать, как это делается с использованием объекта очереди печати .NET:

См. http://msdn.microsoft.com/en-us/library/system.printing.printqueue.aspx для объекта 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");
}
...