zplCore.comzplCore.com

13Printing

ZplPrinterClient sends raw TCP to port 9100 and queries the status via ~HS (ZplPrinterStatus: PaperOut, Paused, HeadOpen, RibbonOut, OverTemperature, UnderTemperature, LabelsRemainingInBatch, FormatsInBuffer).

var printer = new ZplPrinterClient("192.168.1.50")   // Port 9100 (Raw)
{
    Timeout = TimeSpan.FromSeconds(5),
};

ZplPrinterStatus status = await printer.GetStatusAsync();   // ~HS
if (!status.IsReady)
    throw new InvalidOperationException(
        $"Papier leer: {status.PaperOut}, Kopf offen: {status.HeadOpen}, Pause: {status.Paused}");

await printer.SendAsync(zpl);
await printer.SendAsync(label, dpi: 203, copies: 5);

Connections: IPrinterConnection

All transports implement IPrinterConnection (SendAsync(byte[]), QueryAsync); extension methods send ZPL strings and labels and query the ~HS status via GetStatusAsync(). PrinterSettings + PrinterConnectionFactory.Create make the transport configurable.

// one interface for all transports
await using IPrinterConnection printer = PrinterConnectionFactory.Create(new PrinterSettings
{
    CommunicationType = CommunicationType.Network,   // Network, Serial, Usb, File, WindowsDriver, Cups, Stream
    Host = "192.168.1.50", Port = 9100,
    Timeout = TimeSpan.FromSeconds(5),
});
ZplPrinterStatus? status = await printer.GetStatusAsync();   // ~HS (null for write-only transports)
await printer.SendAsync(zpl);
await printer.SendAsync(label, dpi: 203, copies: 2);

// generated directly
IPrinterConnection tcp = new TcpPrinterConnection("192.168.1.50");
IPrinterConnection serial = new SerialPrinterConnection("COM3", 9600, Parity.None, 8, StopBits.One, Handshake.XOnXOff);
IPrinterConnection usb = new RawFilePrinterConnection("/dev/usb/lp0");          // or \\.\USB001, file
IPrinterConnection cups = new CupsPrinterConnection("Zebra_ZD421") { JobTitle = "Versand" };
IPrinterConnection mem = new StreamPrinterConnection(new MemoryStream());        // Tests
if (OperatingSystem.IsWindows())
{
    IPrinterConnection spooler = new WindowsSpoolerPrinterConnection("ZDesigner ZD421-203dpi", documentName: "Versand");
}
ClassCommunicationTypeStatus (~HS)
TcpPrinterConnectionNetwork (Raw, port 9100)yes
SerialPrinterConnectionSerial (baud, parity, handshake)yes
RawFilePrinterConnectionUsb, File (device path or file)no
WindowsSpoolerPrinterConnectionWindowsDriver (RAW print job, Windows only)no
CupsPrinterConnectionCups (lp -o raw)no
StreamPrinterConnectionStream (any Stream, tests)if readable

Virtual printer (TCP 9100)

ZplVirtualPrinter listens on the raw port, renders incoming ZPL and EPL jobs (EPL is detected) and saves every label as PNG or PDF – ideal for testing applications that would otherwise print to a Zebra. Status queries are answered as a ready printer (HostQueryHandler for custom responses). As a console program: dotnet run --project samples/VirtualPrinter -- --port 9100 --out labels [--pdf] [--any].

await using var printer = new ZplVirtualPrinter(9100, IPAddress.Loopback)
{
    RenderSettings = new ZplRenderSettings { Dpi = 203, OutputFormat = ZplOutputFormat.Png },
    OutputDirectory = "labels",                // every label as labels/*.png
};
printer.LabelReceived += (_, e) => Console.WriteLine($"Etikett #{e.Index} → {e.FilePath}");
printer.Start();                               // answers ~HS, ~HI and ~HQ (ES, SN, OD …)

Print settings, extended status, discovery & dry run

ZplJobSettings generates ^MM (tear-off, peel-off, cutter, RFID …), ^MN (gap, mark, continuous), ^MT, ^LL/^ML, ^MD, ^PR and the orientation, and inserts them after every ^XA. GetExtendedStatusAsync evaluates ~HQES (error and warning flags), plus serial number, odometer and ~HI. PrinterDiscovery.FindUsbPrintersAsync finds USB printers; with EnablePrinting = false the factory returns a DryRunPrinterConnection that only logs. Further transports: TCP, serial, USB/file, parallel port, Windows spooler, CUPS, stream.

var settings = new PrinterSettings
{
    Host = "127.0.0.1", Port = 9100,
    EnablePrinting = true,                     // false = dry run (DryRunPrinterConnection)
    Job = new ZplJobSettings
    {
        PrintMode = PrintMode.Cutter,          // ^MMC
        MediaTracking = MediaTracking.Gap,     // ^MNY
        MediaType = MediaType.DirectThermal,   // ^MTD
        Darkness = 20, PrintSpeed = 4,         // ^MD, ^PR
        Orientation = JobOrientation.Portrait180,
    },
};
await using IPrinterConnection conn = PrinterConnectionFactory.Create(settings);
await conn.SendAsync(settings.Job.Apply(zpl));
ZplExtendedStatus? status = await conn.GetExtendedStatusAsync();      // ~HQES
if (status is { IsReady: false }) Console.WriteLine(status.Errors);

IReadOnlyList<DiscoveredPrinter> usb = await PrinterDiscovery.FindUsbPrintersAsync();

More on zplCloud.com: Guide: Print control (^MD, ^PR, cut, mirror)