0

I'm trying to get the printer status of a Zebra label printer. I've tried WMI, checking PrinterState, PrinterStatus, ExtendedPrinterStatus, DetectedErrorState, ExtendedDetectedErrorState, but I'm always getting values such as Unknown, or Idle. The printer is actually out of paper, and I want to get that status. The Windows Printers area itself is also reporting "Ready" for the status. I installed a small Zebra Status Monitor app and it correctly reports "Out of Paper".

I think I may need to pInvoke some Windows APIs to directly query the printer. Zebra has this reference which shows the use of GetPrinter() and GetPrinterData(). I found this C# example of using GetPrinter() which works and includes good information, but the Status is 0 and I don't see anything that indicates Out of Paper.

Now, I'd like to try to use GetPrinterData() which that Zebra document uses and checks for PRINTER_STATUS_PAPER_OUT. Using that GetPrinter() code to OpenPrinter() (which is successful), I've tried a few variations of GetPrinterData(). Here's one:

uint pType = 0;
uint pcbNeeded = 0;
uint result1 = GetPrinterData(pHandle, "Error", out pType, null, 0, out pcbNeeded);

result1 is always a value of 2 and pcbNeeded is value of 0. Even if I turn off the printer, or if the printer has paper, I always get these same values.

Any help on how to correctly pInvoke GetPrinterData() or on how to get the actual printer status would be very helpful.

Community
  • 1
  • 1
Ben Amada
  • 706
  • 11
  • 22

2 Answers2

0

Although it is late for you, the post USB communications with Zebra printers in C# shows how to query the printer over USB.

Tony Edgecombe
  • 3,860
  • 3
  • 28
  • 34
Nule
  • 1
0

As it appears the pinvoke.net declaration for GetPrinterData is correct but doesn't work all the time. If you change the declaration to:

    [DllImport("winspool.drv",
    SetLastError = true,
    CharSet = CharSet.Ansi,
    CallingConvention = CallingConvention.StdCall)]
    static extern uint GetPrinterData(
        IntPtr hPrinter,
        string pValueName,
        out uint pType,
        out UInt32 pData,
        uint nSize,
        out uint pcbNeeded);

using UInt32 instead of the suggested byte[] seems to return "Error" status values as from a C++ application.