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:
- Through the printer driver (default). Install the Zebra Universal Driver (ZUD) or the Windows built-in Generic / Text Only driver, and set
PrinterNameto the printer name as shown in Windows. These same settings are valid for thePrinterDriveroption. On Unix,PrinterNameis the name of the CUPS queue. - Directly to the USB device (Windows). If
PrinterNameis a USB device path (it containsVID_xxxxandPID_xxxx, e.g. one returned byPrintUtils.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
NetworkIPAddressas is (IPAddress.None, the default) and set the host name inPrinterName:
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 callDispose()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\nyourself.- Errors while opening a channel, reading or writing are reported through the
Errorevent, so subscribe to it before callingOpenBidiComm(). Some configuration problems (no USB printers found, a non-USB printer, a Unix communication type without BIDI support) are thrown byOpenBidiComm()itself. - Text is encoded with the job's
BidiEncodingproperty (default UTF-8). Set it beforeOpenBidiComm(); it applies to what youWriteand to the data you receive. - A channel that stops delivering data does not block
CloseBidiComm(). On a Serial link,Writewaits for the printer to assert the DSR line and reports anErrorafter 5 seconds if it never does. - Calling
OpenBidiComm()closes a previously opened channel first. Always pair it withCloseBidiComm()(disposing the job closes it too). - For a USB printer,
PrinterNamecan 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. |