1

I am using this C++ code to successfully send a command to a thermal printer (Citizen CT S310II) that is attached via USB:

bool SendPrinterCommand(char* printerName, unsigned char* command, int size)
{
    HANDLE printer = NULL;
    BOOL result = OpenPrinter((LPSTR)printerName, &printer, NULL);

    DOC_INFO_1 doc = { TEXT("PrinterCommand"), 0, TEXT("RAW") };

    DWORD jobId = StartDocPrinter(printer, 1, (LPBYTE)&doc);

    if (jobId)
    {
        if (StartPagePrinter(printer))
        {
            DWORD dwBytesWritten = 0;

            if (WritePrinter(printer, command, size, &dwBytesWritten))
            {
                // read back from the printer

                HANDLE printerJob = NULL;
                String jobName = printerName + STRING(",Job %d", jobId);
                BOOL result = OpenPrinter((LPSTR)jobName.c_str(), &printerJob, NULL);

                if (result)
                {
                    const int SIZE = 2048;
                    char* buffer = new char[SIZE];
                    DWORD size = 0;

                    if (ReadPrinter(printerJob, buffer, SIZE, &size))
                    {
                        REPORT("received %d bytes from the printer", size);
                    }

                    delete[] buffer;
                    ClosePrinter(printerJob);
                }
            }
            EndPagePrinter(printer);
        }
        EndDocPrinter(printer);
    }
    ClosePrinter(printer);
}

To open up an attached cash-drawer I call it like this:

        // ESC p m t1 t2
        unsigned char command[] = "\33p\0\31\372";

        SendPrinterCommand("Citizen CT S310II", command, 5);

This command works fine, and it shows me that sending ESC-sequence commands basically work through WritePrinter().

Now I would like to send a command that allows me to check the paper-status of the thermal-printer:

        // DLE EOT n 
        // n=1 Transmit printer status
        // n=2 Transmit off-line status
        // n=3 Transmit error status
        // n=4 Transmit paper roll sensor status
        unsigned char command[] = "\20\4\4";

        SendPrinterCommand("Citizen CT S310II", command, 3);

This command requires to read back the result. However, while ReadPrinter() succeeds, it always returns 0 bytes read. From another thread I learned that ReadPrinter() only works on a HANDLE to the printer job. Using the HANDLE of the printer instead made the call to ReadPrinter fail - so I am certain that this approach is better.

However, I am not sure if sending ESC-commands (other than the open cash-drawer) are even accepted/processed by the thermal printer, because all the commands I know, none had an effect - like line-feed, cutting, etc. So I wonder if that would even work?

However, communicating with the printer directly through the serial port works, and delivers the correct result, demonstrated in this C# code:

            var serial = new SerialPort
            {
                PortName = "COM6",
                BaudRate = 9600,
                DataBits = 8,
                Parity = Parity.None,
                StopBits = StopBits.One,
                Handshake = Handshake.None,
            };

            try
            {
                serial.Open();

                byte[] command = { 16, 4, 4 };      // DLE EOT 4
                serial.Write(command, 0, 3);

                byte[] buffer = new byte[256];
                int bytesRead = serial.Read(buffer, 0, 100);

                if (bytesRead > 0 && (buffer[0] & 0x60) != 0)
                    Log.Information("no paper in printer");

                serial.Close();
            }
            catch (Exception e)
            {
                Log.Warning("failed to check printer paper status (Error: {0}", e.Message);
            }

Question: has anyone successfully sent ESC-commands to a USB-attached printer using WritePrinter() and received data back using ReadPrinter()?

  • It may be helpful to extract information from these articles and put them together. [c# RawPrinterHelper sends data to printer, printer spools and states "printed" but doesnt actually print](https://stackoverflow.com/q/43363847/9014308), [frogmorecs/RawPrint](https://github.com/frogmorecs/RawPrint), [How to use the WritePrinter / ReadPrinter method to read/write data from zebra printer GX420t using C#](https://social.msdn.microsoft.com/Forums/vstudio/zh-CN/3bb9648b-0d71-4828-b5e8-e807810f311f/) – kunif Aug 23 '22 at 18:28
  • [\[RESOLVED\] VS2008 / VS 2012. Win 7. USB Printing to Zebra - Bidirectional Communications. USB004](https://www.vbforums.com/showthread.php?770307), [Reading status from Zebra Printer](https://stackoverflow.com/q/1846340/9014308) – kunif Aug 23 '22 at 18:28
  • Thanks for your comment! The USB Zebra project looked promising, especially since people reported it worked for them. So I modified it to attach to my CT S310II. While I succeeded to transmit/print raw text, I had no success sending ESC sequences (they all resulted in a single line form-feed), neither did they return any data. The remaining links you provided did not provide any new insight nor solutions. – Erwin Kloibhofer Aug 23 '22 at 21:03

0 Answers0