Printing to a Zebra printer involves sending ZPL or EPL2 commands directly to the printer. You'll need to build up a string of commands, and then P/Invoke several Windows APIs to send the commands to the printer.
This is the code I use to write directly to the printer:
using System;
using System.ComponentModel;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
internal static class SafeNativeMethods
{
[StructLayout(LayoutKind.Sequential)]
private struct DOCINFO
{
[MarshalAs(UnmanagedType.LPWStr)]
public string pDocName;
[MarshalAs(UnmanagedType.LPWStr)]
public string pOutputFile;
[MarshalAs(UnmanagedType.LPWStr)]
public string pDataType;
public DOCINFO(string documentName) : this()
{
if (string.IsNullOrEmpty(documentName))
{
documentName = "RAW Document";
}
pDocName = documentName;
pDataType = "RAW";
}
}
private sealed class PrinterDocument : IDisposable
{
private SafePrinterHandle _printer;
public PrinterDocument(SafePrinterHandle printer)
{
_printer = printer;
}
public void Dispose()
{
var printer = Interlocked.Exchange(ref _printer, null);
if (null != printer) EndDocPrinter(printer);
}
}
private sealed class PrinterPage : IDisposable
{
private SafePrinterHandle _printer;
public PrinterPage(SafePrinterHandle printer)
{
_printer = printer;
}
public void Dispose()
{
var printer = Interlocked.Exchange(ref _printer, null);
if (null != printer) EndPagePrinter(printer);
}
}
private sealed class SafePrinterHandle : SafeHandle
{
private SafePrinterHandle() : base(IntPtr.Zero, true)
{
}
public override bool IsInvalid
{
get { return IntPtr.Zero == handle; }
}
protected override bool ReleaseHandle()
{
return ClosePrinter(handle);
}
public static SafePrinterHandle Open(string printerName)
{
SafePrinterHandle result;
if (!OpenPrinter(printerName, out result, IntPtr.Zero))
{
ThrowLastWin32Error();
}
return result;
}
public IDisposable StartDocument(string name)
{
if (IsInvalid || IsClosed) return null;
var di = new DOCINFO(name);
if (!StartDocPrinter(this, 1, ref di))
{
ThrowLastWin32Error();
}
return new PrinterDocument(this);
}
public IDisposable StartPage()
{
if (IsInvalid || IsClosed) return null;
if (!StartPagePrinter(this))
{
ThrowLastWin32Error();
}
return new PrinterPage(this);
}
public void Write(string data)
{
if (IsInvalid) throw new InvalidOperationException();
if (IsClosed) throw new ObjectDisposedException(typeof(SafePrinterHandle).Name);
int bytesWritten;
if (!WritePrinter(this, data, data.Length, out bytesWritten))
{
ThrowLastWin32Error();
}
}
}
[DllImport("winspool.drv", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
private static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPWStr)] string szPrinter, out SafePrinterHandle hPrinter, IntPtr pd);
[DllImport("winspool.drv", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
private static extern bool ClosePrinter(IntPtr hPrinter);
[DllImport("winspool.drv", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
private static extern bool StartDocPrinter(SafePrinterHandle hPrinter, int level, ref DOCINFO di);
[DllImport("winspool.drv", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
private static extern bool EndDocPrinter(SafePrinterHandle hPrinter);
[DllImport("winspool.drv", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
private static extern bool StartPagePrinter(SafePrinterHandle hPrinter);
[DllImport("winspool.drv", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
private static extern bool EndPagePrinter(SafePrinterHandle hPrinter);
[DllImport("winspool.drv", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
private static extern bool WritePrinter(SafePrinterHandle hPrinter, [MarshalAs(UnmanagedType.LPStr)] string data, int dwCount, out int dwWritten);
private static void ThrowLastWin32Error()
{
int errorCode = Marshal.GetLastWin32Error();
if (0 != errorCode) throw new Win32Exception(errorCode);
}
public static void SendStringToPrinter(string printerName, string valueToSend, string documentName)
{
if (string.IsNullOrWhiteSpace(printerName)) throw new ArgumentNullException("printerName");
if (string.IsNullOrEmpty(valueToSend)) throw new ArgumentNullException("valueToSend");
using (var printer = SafePrinterHandle.Open(printerName.Normalize()))
using (printer.StartDocument(documentName))
using (printer.StartPage())
{
printer.Write(valueToSend);
}
}
}
Alternatively, you might want to look at
SharpZebra[
^], which is described as "
a C# library that simplifies printing to Zebra printers in their native EPL2/ZPL languages without needing to know EPL2 or ZPL."