Show / Hide Table of Contents

Print Jobs

PrintJob, WindowsPrintJob, UnixPrintJob & WebPrintJob

Note

For sample code about using the PrintJob, WindowsPrintJob, UnixPrintJob and WebPrintJob classes, please refer to the ThermalLabel sample projects.

Class Assembly Platform Purpose
PrintJob Neodynamic.SDK.ThermalLabel.dll any Generates the raw printer commands (ZPL, EPL, Fingerprint/Direct Protocol...) for a ThermalLabel, and exports labels to image, PDF or HTML. It does not talk to printers; it is very useful in development/test phase or when you have no physical thermal printer. See Export Labels to Image, PDF and HTML.
WindowsPrintJob Neodynamic.SDK.ThermalLabel.WindowsPrinting.dll (...WindowsPrinting.NetCore.dll for .NET Core / .NET 5+) Windows Prints a ThermalLabel using the printer device settings and communication, label orientation, number of copies, etc. Supports bidirectional (BIDI) communication.
UnixPrintJob Neodynamic.SDK.ThermalLabel.UnixPrinting.dll macOS / Linux Same idea as WindowsPrintJob for Unix client apps, with the differences listed below.
WebPrintJob Neodynamic.SDK.ThermalLabel.WebPrinting.dll ASP.NET Prints from an ASP.NET project.

WindowsPrintJob and UnixPrintJob implement IDisposable: always create them in a using block (or call Dispose()). With a Windows printer driver, the spooler document is only closed (and the labels released) when the job is disposed, see Printing through a printer driver.

Raw printing and graphic printing

Both jobs offer two ways of printing a label:

Method What is sent to the printer Typical use
Print(), Print(ThermalLabel), Print(List<ThermalLabel>) Raw printer commands in the language set in PrinterSettings.ProgrammingLanguage (ZPL, EPL, Fingerprint...). Thermal printers. Fast and sharp.
PrintAsGraphic(...) The label rendered as an image (Windows: through GDI+ PrintDocument; Unix: as a PDF through CUPS lpr). Regular/laser/inkjet printers and any printer driven by its OS driver.
PrintFiles(byte[]) Previously exported label images (single image or a ZIP of images, as generated by PrintJob.ExportToImage). Print images you already exported.

VB

Using pj As New WindowsPrintJob()
    pj.PrinterSettings = New PrinterSettings()
    pj.PrinterSettings.Communication.CommunicationType = CommunicationType.Network
    pj.PrinterSettings.Communication.NetworkIPAddress = System.Net.IPAddress.Parse("192.168.1.50")
    pj.PrinterSettings.Communication.NetworkPort = 9100
    pj.PrinterSettings.ProgrammingLanguage = ProgrammingLanguage.ZPL
    pj.PrinterSettings.Dpi = 203

    pj.Copies = 2
    pj.Print(tLabel)   ' raw ZPL commands
End Using

CS

using (var pj = new WindowsPrintJob())
{
    pj.PrinterSettings = new PrinterSettings();
    pj.PrinterSettings.Communication.CommunicationType = CommunicationType.Network;
    pj.PrinterSettings.Communication.NetworkIPAddress = System.Net.IPAddress.Parse("192.168.1.50");
    pj.PrinterSettings.Communication.NetworkPort = 9100;
    pj.PrinterSettings.ProgrammingLanguage = ProgrammingLanguage.ZPL;
    pj.PrinterSettings.Dpi = 203;

    pj.Copies = 2;
    pj.Print(tLabel);   // raw ZPL commands
}

Common properties

Property Description
PrinterSettings Target printer: name, Dpi (default 203), ProgrammingLanguage (default ZPL), Communication, UseDefaultPrinter. Required by every print method.
ThermalLabel Label used by the parameterless Print() / PrintAsGraphic(). It is set automatically when you pass a label to a print method.
Copies Number of copies. Default 1; values lower than 1 throw.
Replicates Number of replicates. Default 0; negative values throw.
PrintOrientation Portrait (default), Landscape90, Portrait180, Landscape270.
CommandsOptimizationEnabled Optimizations when generating raw commands. Default true.
FingerprintSettings Fingerprint custom settings (DisableRun).
DocumentName Name of the document shown in the spooler (Windows print queue / CUPS job title). Default is empty (Windows then uses Document). It is also used by raw Print when the target goes through the printer driver (Windows) or a CUPS queue (Unix).
MarginLeft, MarginTop Margins when printing as graphic, in the label's unit. Default -1 = centered. Windows only.
Duplex Double-sided printing when printing as graphic. Default false. A label designed as duplex (IsDuplexDesign with 2 pages) is also printed double-sided.

Windows vs Unix

Feature WindowsPrintJob UnixPrintJob
Communication types for Print USB, PrinterDriver, Parallel, Serial, Network, HID, Stream USB and PrinterDriver (both through a CUPS queue by name), Network, Stream. Serial and Parallel throw not supported under Unix. HID is not handled.
PrintAsGraphic GDI+ (PrintDocument); scale, target size and List overloads; honors MarginLeft/Top and DocumentName PDF sent with lpr; only PrintAsGraphic() / (ThermalLabel) / (List); no scale overloads; MarginLeft/Top have no effect; DocumentName is the CUPS job title
PrintAsGraphic target PrinterDriver, USB or UseDefaultPrinter PrinterDriver, USB (CUPS queue) or UseDefaultPrinter
PrintFiles Any image format GDI+ reads (or a ZIP of them) JPEG only (single file or ZIP of JPEGs), converted to PDF
BIDI USB, PrinterDriver, Parallel, Network, Serial, HID Network (TCP/IP) only
PrintUtils.GetInstalledPrinters() static static (CUPS queues, from lpstat -v)
Important

PrintAsGraphic only makes sense for a printer that is driven by an OS driver (Windows driver / CUPS queue). With the other communication types, the Windows implementation throws a NotSupportedException (older builds silently printed to the default Windows printer), and the Unix implementation sends the PDF bytes unchanged to the network port.

Printer Utilities

ThermalLabel SDK does not only provide thermal label designing and printing but also a set of commands for Zebra, Eltron/EPL and Honeywell/Intermec printers administration. They are available in the static PrintUtils class (found in Neodynamic.SDK.ThermalLabel.WindowsPrinting.dll and Neodynamic.SDK.ThermalLabel.UnixPrinting.dll). See the PrintUtils class reference for details.

Set the target printer before calling any method: PrintUtils.PrinterSettings = ps; (it is static, so it is shared by the whole process; it is not thread-safe). Only ExecuteCommand has overloads that take a PrinterSettings.

PrintUtils.PrinterSettings = ps;
PrintUtils.SetDarkness(10);
PrintUtils.PrintConfiguration();
Method ZPL EPL Fingerprint / Direct Protocol Other
ExecuteCommand(string / byte[]) ✔ ✔ ✔ any language; string commands are encoded in code page 850 unless you pass an Encoding
PrintDirectory ✔
PrintConfiguration ✔ ✔
DeleteObject, CopyObject ✔ ✔
ResetPrinter ✔ ✔
SetPrinterFactoryConfiguration ✔ ✔
SetDarkness ✔ (-30..30) ✔ (0..15) ✔
SetPrintMode ✔
CutLabel ✔ ✔ ✔ ESC/POS (partial cut)
SetMediaTracking ✔
SetMediaType ✔ ✔ ✔
PausePrinting, StartPrinting ✔
AutoSetLabelLength ✔ ✔ ✔
UploadUnboundedTrueTypeFont, UploadImageItem by language of PrinterSettings

A method that is not available for the printer's language throws "<Language>: The specified command is not supported.".

GetInstalledPrinters() is a static method on both platforms (Unix lists the CUPS queues reported by lpstat -v). GetUsbDevices(), GetHidDevices() and FindHidDevice(vendorId, productId, usagePage, usageId) are Windows only. GetInstalledPrinters, GetUsbDevices and GetHidDevices return null if the enumeration fails.

PrintUtils methods throw the localized printer settings null error (not a NullReferenceException) when PrintUtils.PrinterSettings has not been set. SetDarkness throws an ArgumentOutOfRangeException for an EPL darkness outside 0–15.

Thermal Printer Communication

Thermal printers can be connected by Serial Port (RS-232), Parallel Port (Centronics), USB, HID and IP Ethernet network depending on the printer model. The communication is handled internally by the PrinterCommunication class, which you configure through PrinterSettings.Communication and use through a WindowsPrintJob, UnixPrintJob or the PrintUtils class.

Important

The Serial Port (RS-232) and Parallel Port (Centronics) communications are not available under Unix (macOS / Linux). HID is available only under Windows.

Note

The code snippets below use WindowsPrintJob but the same applies to UnixPrintJob unless noted.

CommunicationType defaults to USB. UseDefaultPrinter = true makes the SDK use the system default printer through its driver/queue, whatever the communication type is (PrinterSettings.PrinterName is left untouched).

USB

If your printer is connected by USB you can print in two ways:

  1. Through the printer driver (default). Install the Zebra Universal Driver (ZUD) or the Windows built-in Generic / Text Only driver, and set PrinterName to the printer name as shown in Windows. These same settings are valid for the PrinterDriver option. On Unix, PrinterName is the name of the CUPS queue.
  2. Directly to the USB device (Windows). If PrinterName is a USB device path (it contains VID_xxxx and PID_xxxx, e.g. one returned by PrintUtils.GetUsbDevices()), the commands are written straight to the device.

VB

'Create a WindowsPrintJob object
Dim pj As New WindowsPrintJob()
pj.PrinterSettings = New PrinterSettings()
'Thermal Printer is connected through USB
pj.PrinterSettings.Communication.CommunicationType = CommunicationType.USB
'Set Thermal Printer resolution
pj.PrinterSettings.Dpi = 203
'Set Thermal Printer language
pj.PrinterSettings.ProgrammingLanguage = ProgrammingLanguage.ZPL
'Set Thermal Printer name
pj.PrinterSettings.PrinterName = "Zebra TLP2844-Z"

CS

//Create a WindowsPrintJob object
WindowsPrintJob pj = new WindowsPrintJob();
pj.PrinterSettings = new PrinterSettings();
//Thermal Printer is connected through USB
pj.PrinterSettings.Communication.CommunicationType = CommunicationType.USB;
//Set Thermal Printer resolution
pj.PrinterSettings.Dpi = 203;
//Set Thermal Printer language
pj.PrinterSettings.ProgrammingLanguage = ProgrammingLanguage.ZPL;
//Set Thermal Printer name
pj.PrinterSettings.PrinterName = "Zebra TLP2844-Z";

USB HID (Windows)

HID printers need no driver. The SDK finds the device by Vendor ID / Product ID and sends the commands split in fixed-size HID output reports. Use PrintUtils.GetHidDevices() to list the devices.

pj.PrinterSettings.Communication.CommunicationType = CommunicationType.HID;
pj.PrinterSettings.Communication.HidVendorId = 0x0A5F;   // Zebra
pj.PrinterSettings.Communication.HidProductId = 0x0164;  // sample
// Optional: HidUsagePage / HidUsageId (default -1) to choose a collection of a composite device
// Optional: HidReportId (default 0, correct for most printers)

PrinterName can also hold a full HID device path (containing VID_xxxx and PID_xxxx) instead.

Parallel Port (Centronics)

If your printer is connected by a Parallel Port (Centronics), you just need to know the parallel port name. The port name is a Communication property (default "LPT1").

VB

'Create a WindowsPrintJob object
Dim pj As New WindowsPrintJob()
pj.PrinterSettings = New PrinterSettings()
'Thermal Printer is connected through Parallel Port
pj.PrinterSettings.Communication.CommunicationType = CommunicationType.Parallel
'Set Thermal Printer resolution
pj.PrinterSettings.Dpi = 203
'Set Thermal Printer language
pj.PrinterSettings.ProgrammingLanguage = ProgrammingLanguage.ZPL
'Set Thermal Printer parallel port name
pj.PrinterSettings.Communication.ParallelPortName = "LPT1"

CS

//Create a WindowsPrintJob object
WindowsPrintJob pj = new WindowsPrintJob();
pj.PrinterSettings = new PrinterSettings();
//Thermal Printer is connected through Parallel Port
pj.PrinterSettings.Communication.CommunicationType = CommunicationType.Parallel;
//Set Thermal Printer resolution
pj.PrinterSettings.Dpi = 203;
//Set Thermal Printer language
pj.PrinterSettings.ProgrammingLanguage = ProgrammingLanguage.ZPL;
//Set Thermal Printer parallel port name
pj.PrinterSettings.Communication.ParallelPortName = "LPT1";

Serial Port (RS-232)

If your printer is connected by a Serial Port (RS-232), you need to know the printer's serial communication parameters; refer to your printer's user manual. Defaults: COM1, 9600 baud, 8 data bits, 1 stop bit, no parity, XOn/XOff flow control.

VB

'Create a WindowsPrintJob object
Dim pj As New WindowsPrintJob()
pj.PrinterSettings = New PrinterSettings()
'Thermal Printer is connected through Serial Port
pj.PrinterSettings.Communication.CommunicationType = CommunicationType.Serial
'Set Thermal Printer resolution
pj.PrinterSettings.Dpi = 203
'Set Thermal Printer language
pj.PrinterSettings.ProgrammingLanguage = ProgrammingLanguage.ZPL
'Set Thermal Printer serial port settings
pj.PrinterSettings.Communication.SerialPortName = "COM1"
pj.PrinterSettings.Communication.SerialPortBaudRate = 9600
pj.PrinterSettings.Communication.SerialPortDataBits = 8
pj.PrinterSettings.Communication.SerialPortStopBits = SerialPortStopBits.One
pj.PrinterSettings.Communication.SerialPortParity = SerialPortParity.None
pj.PrinterSettings.Communication.SerialPortFlowControl = SerialPortHandshake.XOnXOff

CS

//Create a WindowsPrintJob object
WindowsPrintJob pj = new WindowsPrintJob();
pj.PrinterSettings = new PrinterSettings();
//Thermal Printer is connected through Serial Port
pj.PrinterSettings.Communication.CommunicationType = CommunicationType.Serial;
//Set Thermal Printer resolution
pj.PrinterSettings.Dpi = 203;
//Set Thermal Printer language
pj.PrinterSettings.ProgrammingLanguage = ProgrammingLanguage.ZPL;
//Set Thermal Printer serial port settings
pj.PrinterSettings.Communication.SerialPortName = "COM1";
pj.PrinterSettings.Communication.SerialPortBaudRate = 9600;
pj.PrinterSettings.Communication.SerialPortDataBits = 8;
pj.PrinterSettings.Communication.SerialPortStopBits = SerialPortStopBits.One;
pj.PrinterSettings.Communication.SerialPortParity = SerialPortParity.None;
pj.PrinterSettings.Communication.SerialPortFlowControl = SerialPortHandshake.XOnXOff;

IP Ethernet Network

If your printer is connected by an IP Ethernet network, you need the IP address and the port number of the printer (the port has no default: it is 0 until you set it; Zebra printers use 9100). NetworkTimeout (default 1500 ms) applies to send and receive.

VB

'Create a WindowsPrintJob object
Dim pj As New WindowsPrintJob()
pj.PrinterSettings = New PrinterSettings()
'Thermal Printer is connected through IP network
pj.PrinterSettings.Communication.CommunicationType = CommunicationType.Network
'Set Thermal Printer resolution
pj.PrinterSettings.Dpi = 203
'Set Thermal Printer language
pj.PrinterSettings.ProgrammingLanguage = ProgrammingLanguage.ZPL
'Set Thermal Printer network info
pj.PrinterSettings.Communication.NetworkIPAddress = System.Net.IPAddress.Parse("127.0.0.1")
pj.PrinterSettings.Communication.NetworkPort = 9100

CS

//Create a WindowsPrintJob object
WindowsPrintJob pj = new WindowsPrintJob();
pj.PrinterSettings = new PrinterSettings();
//Thermal Printer is connected through IP network
pj.PrinterSettings.Communication.CommunicationType = CommunicationType.Network;
//Set Thermal Printer resolution
pj.PrinterSettings.Dpi = 203;
//Set Thermal Printer language
pj.PrinterSettings.ProgrammingLanguage = ProgrammingLanguage.ZPL;
//Set Thermal Printer network info
pj.PrinterSettings.Communication.NetworkIPAddress = System.Net.IPAddress.Parse("127.0.0.1");
pj.PrinterSettings.Communication.NetworkPort = 9100;
  • If you do not know the IP address but the host name, leave NetworkIPAddress as is (IPAddress.None, the default) and set the host name in PrinterName:

VB

'Create a WindowsPrintJob object
Dim pj As New WindowsPrintJob()
pj.PrinterSettings = New PrinterSettings()
'Thermal Printer is connected through IP network
pj.PrinterSettings.Communication.CommunicationType = CommunicationType.Network
'Set Thermal Printer resolution
pj.PrinterSettings.Dpi = 203
'Set Thermal Printer language
pj.PrinterSettings.ProgrammingLanguage = ProgrammingLanguage.ZPL
'Set Thermal Printer network info
pj.PrinterSettings.PrinterName = "PRINTER HOST NAME"
pj.PrinterSettings.Communication.NetworkPort = 9100

CS

//Create a WindowsPrintJob object
WindowsPrintJob pj = new WindowsPrintJob();
pj.PrinterSettings = new PrinterSettings();
//Thermal Printer is connected through IP network
pj.PrinterSettings.Communication.CommunicationType = CommunicationType.Network;
//Set Thermal Printer resolution
pj.PrinterSettings.Dpi = 203;
//Set Thermal Printer language
pj.PrinterSettings.ProgrammingLanguage = ProgrammingLanguage.ZPL;
//Set Thermal Printer network info
pj.PrinterSettings.PrinterName = "PRINTER HOST NAME";
pj.PrinterSettings.Communication.NetworkPort = 9100;

Stream

With CommunicationType.Stream, the printer commands are written to the System.IO.Stream set in PrinterSettings.Communication.Stream (a file, a MemoryStream, a network stream...). Nothing is sent to a printer.

Printing through a printer driver

With PrinterDriver (and USB by printer name) on Windows, the SDK opens the spooler once per job object and keeps one spooler document open; every Print call adds its commands to it, and the document is ended when the job is disposed. So, to make sure everything leaves the spooler:

  • wrap the job in using, or call Dispose() when you finish printing;
  • if you print many labels, reuse one job and dispose it at the end instead of creating one job per label.

BiDirectional (BIDI) Communication

A print job can send and receive data to/from the printer: call OpenBidiComm(), send commands with Write(string), receive with the DataRead event and handle problems with the Error event, then call CloseBidiComm().

Windows Unix
USB / PrinterDriver / Parallel ✔ (USB device path, or the printer name when its port is USBnnn) not supported (throws)
Network (TCP/IP) ✔ ✔
Serial ✔ not supported (throws)
HID ✔ not supported (throws)

Things to know:

  • Write(string) sends the text as is, without adding a new line. Many commands (EPL, for example) need the line terminator, so include \n yourself.
  • Errors while opening a channel, reading or writing are reported through the Error event, so subscribe to it before calling OpenBidiComm(). Some configuration problems (no USB printers found, a non-USB printer, a Unix communication type without BIDI support) are thrown by OpenBidiComm() itself.
  • Text is encoded with the job's BidiEncoding property (default UTF-8). Set it before OpenBidiComm(); it applies to what you Write and to the data you receive.
  • A channel that stops delivering data does not block CloseBidiComm(). On a Serial link, Write waits for the printer to assert the DSR line and reports an Error after 5 seconds if it never does.
  • Calling OpenBidiComm() closes a previously opened channel first. Always pair it with CloseBidiComm() (disposing the job closes it too).
  • For a USB printer, PrinterName can be the device path (PrintUtils.GetUsbDevices()) or the name of an installed USB printer; for a printer that is not USB, a "is not a USB device" error is raised.

WindowsPrintJob BiDirectional Communication Sample

The following is a Console sample application about BIDI communication. Read the source code and uncomment/change it based on your needs.

Important

Be sure your Console app references the following assemblies: Neodynamic.SDK.ThermalLabel.dll Neodynamic.SDK.ThermalLabel.WindowsPrinting.NetCore.dll or Neodynamic.SDK.ThermalLabel.WindowsPrinting.dll

VB

Imports System
Imports System.Linq
Imports Neodynamic.SDK.Printing

Namespace TLBidiSample
    Class Program
        Shared Sub Main(args As String())
            Console.WriteLine("Starting BIDI Comm...")

            ' The target printer settings for BIDI comm
            Dim ps As New PrinterSettings()

            ' Targeting driver installed printer
            '
            ' ps.Communication.CommunicationType = CommunicationType.PrinterDriver
            ' ps.PrinterName = "ZDesigner GK420t"
            '

            ' Targeting IP Network Printer
            '
            ' ps.Communication.CommunicationType = CommunicationType.Network
            ' ps.Communication.NetworkIPAddress = System.Net.IPAddress.Parse("127.0.0.1")
            ' ps.Communication.NetworkPort = 9100
            '

            ' Targeting USB printer
            '
            ' ps.Communication.CommunicationType = CommunicationType.USB
            ' Dim usbDevices = PrintUtils.GetUsbDevices()
            ' If usbDevices Is Nothing OrElse usbDevices.Count = 0 Then
            '     Console.Error.WriteLine("USB Device error: no USB devices found")
            '     Return
            ' End If
            ' ps.PrinterName = usbDevices.First().DevicePath
            '

            ' Targeting USB HID printer
            '
            ' ps.Communication.CommunicationType = CommunicationType.HID
            ' ps.Communication.HidVendorId = &HA5F   ' Zebra
            ' ps.Communication.HidProductId = &H164  ' sample
            ' ps.Communication.HidReportId = 0
            '
            ' ' list HID devices
            ' Dim hidDevices = PrintUtils.GetHidDevices()
            ' For Each d In hidDevices
            '     Console.WriteLine(d)
            ' Next
            '

            ' The WindowsPrintJob obj
            Using wpj As New WindowsPrintJob(ps)

                ' Handle errors
                AddHandler wpj.Error, Sub(sender, e)
                                          Console.Error.WriteLine(e.Exception.Message)
                                      End Sub

                ' Handle data received from the target device
                AddHandler wpj.DataRead, Sub(sender, e)
                                             Console.WriteLine($"Received: {e.Data}")
                                         End Sub

                ' Open a BIDI comm
                wpj.OpenBidiComm()

                Dim input As String = ""
                Console.WriteLine("Enter printer commands, or type 'exit' to quit.")

                While True
                    Console.Write("> ")
                    input = Console.ReadLine()

                    If input IsNot Nothing AndAlso (input.ToLower() = "quit" OrElse input.ToLower() = "exit") Then
                        Console.WriteLine("Exit command received. Exiting application.")
                        Exit While
                    End If

                    ' Write (send) data to the target device
                    wpj.Write(input)
                End While

                ' Close BIDI comm
                wpj.CloseBidiComm()

            End Using

        End Sub
    End Class
End Namespace

CS

using System;
using System.Linq;
using Neodynamic.SDK.Printing;

namespace TLBidiSample
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Starting BIDI Comm...");

            // The target printer settings for BIDI comm
            var ps = new PrinterSettings();

            // Targeting driver installed printer
            /*
            ps.Communication.CommunicationType = CommunicationType.PrinterDriver;
            ps.PrinterName = "ZDesigner GK420t";
            */

            // Targeting IP Network Printer
            /*
            ps.Communication.CommunicationType = CommunicationType.Network;
            ps.Communication.NetworkIPAddress = System.Net.IPAddress.Parse("127.0.0.1");
            ps.Communication.NetworkPort = 9100;
            */

            // Targeting USB printer
            /*
            ps.Communication.CommunicationType = CommunicationType.USB;
            var usbDevices = PrintUtils.GetUsbDevices();
            if (usbDevices == null || usbDevices.Count == 0)
            {
                Console.Error.WriteLine("USB Device error: no USB devices found");
                return;
            }
            ps.PrinterName = usbDevices.First().DevicePath;
            */

            // Targeting USB HID printer
            /*
            ps.Communication.CommunicationType = CommunicationType.HID;
            ps.Communication.HidVendorId = 0x0A5F;   // Zebra
            ps.Communication.HidProductId = 0x0164;  // sample
            // ps.Communication.HidReportId = 0;     // usually 0

            //// list HID devices
            //var hidDevices = PrintUtils.GetHidDevices();
            //foreach (var d in hidDevices)
            //    Console.WriteLine(d);
            */

            // The WindowsPrintJob obj
            using var wpj = new WindowsPrintJob(ps);

            // Handle errors
            wpj.Error += (sender, e) =>
            {
                Console.Error.WriteLine(e.Exception.Message);
            };

            // Handle data received from the target device
            wpj.DataRead += (sender, e) =>
            {
                Console.WriteLine($"Received: {e.Data}");
            };

            // Open a BIDI comm
            wpj.OpenBidiComm();

            string input = "";
            Console.WriteLine("Enter printer commands, or type 'exit' to quit.");

            while (true)
            {
                Console.Write("> ");
                input = Console.ReadLine();

                if (input != null && (input.ToLower() == "quit" || input.ToLower() == "exit"))
                {
                    Console.WriteLine("Exit command received. Exiting application.");
                    break;
                }

                // Write (send) data to the target device
                wpj.Write(input);

            }

            // Close BIDI comm
            wpj.CloseBidiComm();

        }
    }
}

UnixPrintJob BiDirectional Communication Sample

Under Unix only Network (TCP/IP) printers are supported for BIDI. The following Console sample application shows how to use it.

Important

Be sure your Console app references the following assemblies: Neodynamic.SDK.ThermalLabel.dll Neodynamic.SDK.ThermalLabel.UnixPrinting.dll

VB

Imports System
Imports System.Linq
Imports Neodynamic.SDK.Printing

Namespace TLBidiSample
    Class Program
        Shared Sub Main(args As String())
            Console.WriteLine("Starting BIDI Comm...")

            ' The target printer settings for BIDI comm
            Dim ps As New PrinterSettings()

            ' Targeting IP Network Printer
            ps.Communication.CommunicationType = CommunicationType.Network
            ps.Communication.NetworkIPAddress = System.Net.IPAddress.Parse("127.0.0.1")
            ps.Communication.NetworkPort = 9100

            ' The UnixPrintJob obj
            Using upj As New UnixPrintJob(ps)

                ' Handle errors
                AddHandler upj.Error, Sub(sender, e)
                                          Console.Error.WriteLine(e.Exception.Message)
                                      End Sub

                ' Handle data received from the target device
                AddHandler upj.DataRead, Sub(sender, e)
                                             Console.WriteLine($"Received: {e.Data}")
                                         End Sub

                ' Open a BIDI comm
                upj.OpenBidiComm()

                Dim input As String = ""
                Console.WriteLine("Enter printer commands, or type 'exit' to quit.")

                While True
                    Console.Write("> ")
                    input = Console.ReadLine()

                    If input IsNot Nothing AndAlso (input.ToLower() = "quit" OrElse input.ToLower() = "exit") Then
                        Console.WriteLine("Exit command received. Exiting application.")
                        Exit While
                    End If

                    ' Write (send) data to the target device
                    upj.Write(input)
                End While

                ' Close BIDI comm
                upj.CloseBidiComm()

            End Using

        End Sub
    End Class
End Namespace

CS

using System;
using System.Linq;
using Neodynamic.SDK.Printing;

namespace TLBidiSample
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Starting BIDI Comm...");

            // The target printer settings for BIDI comm
            var ps = new PrinterSettings();

            // Targeting IP Network Printer
            ps.Communication.CommunicationType = CommunicationType.Network;
            ps.Communication.NetworkIPAddress = System.Net.IPAddress.Parse("127.0.0.1");
            ps.Communication.NetworkPort = 9100;

            // The UnixPrintJob obj
            using var upj = new UnixPrintJob(ps);

            // Handle errors
            upj.Error += (sender, e) =>
            {
                Console.Error.WriteLine(e.Exception.Message);
            };

            // Handle data received from the target device
            upj.DataRead += (sender, e) =>
            {
                Console.WriteLine($"Received: {e.Data}");
            };

            // Open a BIDI comm
            upj.OpenBidiComm();

            string input = "";
            Console.WriteLine("Enter printer commands, or type 'exit' to quit.");

            while (true)
            {
                Console.Write("> ");
                input = Console.ReadLine();

                if (input != null && (input.ToLower() == "quit" || input.ToLower() == "exit"))
                {
                    Console.WriteLine("Exit command received. Exiting application.");
                    break;
                }

                // Write (send) data to the target device
                upj.Write(input);

            }

            // Close BIDI comm
            upj.CloseBidiComm();

        }
    }
}

Common mistakes

Problem Cause / fix
Labels stay in the spooler until the app closes The WindowsPrintJob was not disposed (driver/USB-by-name printing). Use using.
PrintAsGraphic throws NotSupportedException (Windows) The communication type is not PrinterDriver/USB and UseDefaultPrinter is false. Graphic printing always goes through an installed printer driver.
NetworkPort is 0 and nothing prints The port has no default. Set it (usually 9100).
ParallelPortName does not compile on PrinterSettings It is PrinterSettings.Communication.ParallelPortName.
NullReferenceException calling PrintUtils.PrintConfiguration() etc. PrintUtils.PrinterSettings was not set.
PrintFiles fails on Unix Only JPEG images (or a PKZip of JPEGs) are supported. GZip content is rejected with an explicit error on both platforms.
Printer name with spaces does not print on Unix CUPS queue names have no spaces: the SDK sends the name with spaces replaced by _ (the CUPS convention). A name starting with - is rejected.
Print fails on Unix with lpr failed with exit code N lpr was found but refused the job; the message includes its error text (queue does not exist, CUPS stopped...).
GetUsbDevices() returned null The enumeration failed (also when there are no permissions); check for null before using it.
Back to top Copyright © 2003- Neodynamic SRL
http://www.neodynamic.com