I'm working on a project where we need to use a Zebra Printer for barcode labels. We're using C#, and we're doing OK on the printing side of things, sending raw ZPL strings to the printer (using winspool.drv).
However, we also need to read from the printer, and no luck there.
We need to get the status from the printer, which is the output to the ZPL command "~HS", so we can tell how many labels are in memory waiting to be printed. The EnumJobs() from winspool.drv only has jobs on the windows spool, and once they're sent to the printer, they're gone from that list. But that doesn't mean the label has been printed, since the printer has a peel sensor and only prints one label at a time, and we're obviously interested in sending batches of labels to the printer.
I've tried something like (using the winspool.drv calls):
OpenPrinter(szPrinterName, out hPrinter, IntPtr.Zero);
WritePrinter(hPrinter, pBytes, dwCount, out dwWritten); // send the string "~HS"
ReadPrinter(hPrinter, data, buff, out pcRead);
But I get nothing on the ReadPrinter call. I don't even know if this is the right way of going at it.
Anyone out there tackled this before?
Thanks.
Ribbon In ErrorThe printer is detecting ribbon but configured for Direct Thermal (no ribbon mode). Change the LCD Print Mode to Thermal Transfer if using ribbon or if using Direct Thermal remove the ribbon. Verify the driver/software settings match the printer settings.
I'm facing the same problem. Did you already manage anything on this subject?
Ax Perez Parra Castro, this is how I did it:
-get the RawPrinterHelper class from here http://support.microsoft.com/kb/322091
-my printer (zebra 2030) doesn't support ZPL, so as far as I know the only way is to send unicode to it
-I made a list of characters I need e.g.
string enq = Convert.ToChar(5).ToString();
string esc = Convert.ToChar(27).ToString();
string nul = Convert.ToChar(0).ToString();
string rs = Convert.ToChar(30).ToString();
string lf = Convert.ToChar(10).ToString();
string cr = Convert.ToChar(13).ToString();
(get those int values from en.wikipedia.org/wiki/ASCII)
-compose the command - e.g. sb.Append(esc + enq + Convert.ToChar(7).ToString());
(from the printer manual, the command < ESC>< ENQ><7> should get the firmware version)
-send the command RawPrinterHelper.SendStringToPrinter(printerName, sb.ToString());
(printerName in my case is "Zebra TTP 2030")
ReadPrinter
will not help in this situation. It will read back the print job you have submitted to the printer, not the printer's response. However, for the sake of completeness: In order to use ReadPrinter
, you must open the printer again, using the combined "printer name - job id" syntax:
OpenPrinter("Zebra,Job 12345", ...);
ReadPrinter(hPrinter, ...);
This will only work if the job 12345 has not been removed yet.
As for answering the question, you have to use WriteFile
to send data and ReadFile
to get the response. To use those functions, you need to open the printer with CreateFile
. After you've done that, the rest is absolutely trivial.
The problem here is getting the device path that must be passed to CreateFile
in order to open the printer. If your printer is an LPT one, that's as simple as "LPT:"
, but for a USB printer you have to obtain the device path, which looks like this:
\\?\usb#vid_0a5f&pid_0027#46a072900549#{28d78fad-5a12-11d1-ae5b-0000f803a8c2}
I have found a way to obtain this path, but it only works if you have just one printer installed. If you have more, you will need a relation between the device path and the printer name you see in the control panel, and that relation is something I haven't figured yet. I've created a question for that: Figuring which printer name corresponds to which device ID.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With