如何在VB.NET中通过USB向Zebra打印机发送ZPL字符串打印
解决VB.NET下USB连接Zebra打印机打印FedEx ZPL运单的问题
第一步:验证ZPL内容有效性
先将FedEx API返回的ZPL字符串保存为.zpl文件,用Zebra官方的ZPL Viewer工具或在线预览工具确认格式正确,排除ZPL本身的语法错误。
第二步:VB.NET原生API发送原始ZPL数据
直接调用Windows打印API发送原始数据是最可靠的方式,以下是完整的VB.NET实现:
Imports System Imports System.Runtime.InteropServices Imports System.Windows.Forms Public Class ZplPrinterHelper ' Windows打印API声明 <DllImport("winspool.drv", EntryPoint:="OpenPrinterA", SetLastError:=True, CharSet:=CharSet.Ansi, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> Private Shared Function OpenPrinter(ByVal szPrinter As String, ByRef hPrinter As IntPtr, ByVal pd As IntPtr) As Boolean End Function <DllImport("winspool.drv", EntryPoint:="ClosePrinter", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> Private Shared Function ClosePrinter(ByVal hPrinter As IntPtr) As Boolean End Function <DllImport("winspool.drv", EntryPoint:="StartDocPrinterA", SetLastError:=True, CharSet:=CharSet.Ansi, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> Private Shared Function StartDocPrinter(ByVal hPrinter As IntPtr, ByVal level As Integer, ByVal di As DOCINFOA) As Boolean End Function <DllImport("winspool.drv", EntryPoint:="EndDocPrinter", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> Private Shared Function EndDocPrinter(ByVal hPrinter As IntPtr) As Boolean End Function <DllImport("winspool.drv", EntryPoint:="StartPagePrinter", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> Private Shared Function StartPagePrinter(ByVal hPrinter As IntPtr) As Boolean End Function <DllImport("winspool.drv", EntryPoint:="EndPagePrinter", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> Private Shared Function EndPagePrinter(ByVal hPrinter As IntPtr) As Boolean End Function <DllImport("winspool.drv", EntryPoint:="WritePrinter", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> Private Shared Function WritePrinter(ByVal hPrinter As IntPtr, ByVal pBytes As IntPtr, ByVal dwCount As Integer, ByRef dwWritten As Integer) As Boolean End Function <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> Private Structure DOCINFOA <MarshalAs(UnmanagedType.LPStr)> Public pDocName As String <MarshalAs(UnmanagedType.LPStr)> Public pOutputFile As String <MarshalAs(UnmanagedType.LPStr)> Public pDataType As String End Structure ''' <summary> ''' 发送ZPL字符串到指定USB打印机 ''' </summary> ''' <param name="printerName">控制面板中显示的打印机全名</param> ''' <param name="zplContent">FedEx API返回的ZPL格式字符串</param> ''' <returns>是否发送成功</returns> Public Shared Function SendZplToPrinter(ByVal printerName As String, ByVal zplContent As String) As Boolean Dim hPrinter As IntPtr = IntPtr.Zero Dim di As New DOCINFOA() Dim dwWritten As Integer = 0 Dim success As Boolean = False Try di.pDocName = "FedEx Shipping Label" di.pDataType = "RAW" ' 必须指定为原始数据模式,否则打印机无法识别ZPL If OpenPrinter(printerName, hPrinter, IntPtr.Zero) Then If StartDocPrinter(hPrinter, 1, di) Then If StartPagePrinter(hPrinter) Then ' ZPL使用ASCII编码,避免UTF-8导致的乱码 Dim zplBytes As Byte() = System.Text.Encoding.ASCII.GetBytes(zplContent) Dim pBytes As IntPtr = Marshal.AllocCoTaskMem(zplBytes.Length) Marshal.Copy(zplBytes, 0, pBytes, zplBytes.Length) success = WritePrinter(hPrinter, pBytes, zplBytes.Length, dwWritten) Marshal.FreeCoTaskMem(pBytes) EndPagePrinter(hPrinter) End If EndDocPrinter(hPrinter) End If ClosePrinter(hPrinter) End If If Not success Then Throw New Exception($"打印失败,Windows错误码:{Marshal.GetLastWin32Error()}") End If Catch ex As Exception MessageBox.Show($"打印异常:{ex.Message}") success = False End Try Return success End Function End Class
第三步:业务逻辑调用示例
获取FedEx返回的ZPL字符串后,直接调用工具类:
' 替换为你的Zebra打印机全名(从控制面板复制,确保完全一致) Dim targetPrinter As String = "Zebra ZD420 (USB)" ' 假设zplContent是从FedEx API获取的ZPL内容 Dim zplContent As String = "你的FedEx ZPL字符串" ZplPrinterHelper.SendZplToPrinter(targetPrinter, zplContent)
常见问题排查
- 打印机名称错误:必须使用控制面板中显示的完整打印机名称,不要手动简写。
- USB连接异常:确保打印机驱动安装正确,能打印Windows测试页。
- 编码问题:严格使用ASCII编码转换ZPL字符串,UTF-8会导致ZPL指令解析失败。
- 权限不足:若程序以服务或受限账号运行,需给账号分配打印权限。
内容的提问来源于stack exchange,提问作者Joseph Davenport
相关产品推荐
相关产品推荐

