如何使用C#通过USB将原始ZPL发送到斑马打印机

我是初学C#程序员。 我有一个项目要求我通过USB将原始命令发送到Zebra打印机LP 2844并使其工作。 我做了很多研究,并试图找到一种方法来做到这一点。 我正在使用http://support.microsoft.com/kb/322091中的代码,但它无效。 根据我的测试,似乎我已经向打印机发送了命令,但它没有响应和打印。 我不知道这个。 有人可以帮我吗?

我正在使用按钮直接发送命令

private void button2_Click(object sender, EventArgs e) { string s = "A50,50,0,2,1,1,N,\"9129302\""; // Allow the user to select a printer. PrintDialog pd = new PrintDialog(); pd.PrinterSettings = new PrinterSettings(); if (DialogResult.OK == pd.ShowDialog(this)) { // Send a printer-specific to the printer. RawPrinterHelper.SendStringToPrinter(pd.PrinterSettings.PrinterName, s); MessageBox.Show("Data sent to printer."); } } 

编辑 :要解决您的更新,您遇到的问题是您正在使用SendStringToPrinter ,它发送一个ANSI字符串(一个空终止)字符串到打印机,这不是打印机所期望的。 根据官方EPL2编程指南第23页(这是你真正在做的,而不是根据你的例子的ZPL)。

每个命令行必须以换行(LF)字符终止(12月10日)。 大多数基于PC的系统在按下Enter键时发送CR / LF。 打印机忽略回车符(CR)字符,不能用于代替LF。

因此,您必须修改SendStringToPrinter以在字符串末尾发送\n而不是\0或者您必须自己构建ASCII字节数组并自己使用RawPrinterHelper.SendBytesToPrinter (就像我在下面的原始答案中所做的那样)。

因此,为了修复您的简单发布示例,我们更改了您的函数调用,我们还必须通过发送P1\n告诉打印机实际打印

 private void button2_Click(object sender, EventArgs e) { string s = "A50,50,0,2,1,1,N,\"9129302\"\n"; s += "P1\n"; // Allow the user to select a printer. PrintDialog pd = new PrintDialog(); pd.PrinterSettings = new PrinterSettings(); if (DialogResult.OK == pd.ShowDialog(this)) { var bytes = Encoding.ASCII.GetBytes(s); // Send a printer-specific to the printer. RawPrinterHelper.SendBytesToPrinter(pd.PrinterSettings.PrinterName, bytes, bytes.Length); MessageBox.Show("Data sent to printer."); } } //elsewhere public static class RawPrinterHelper { //(Snip) The rest of the code you already have from http://support.microsoft.com/kb/322091 [DllImport("winspool.Drv", EntryPoint="WritePrinter", SetLastError=true, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)] public static extern bool WritePrinter(IntPtr hPrinter, byte[] pBytes, Int32 dwCount, out Int32 dwWritten ); private static bool SendBytesToPrinter(string szPrinterName, byte[] bytes, Int32 dwCount) { Int32 dwError = 0, dwWritten = 0; IntPtr hPrinter = new IntPtr(0); DOCINFOA di = new DOCINFOA(); bool bSuccess = false; di.pDocName = "Zebra Label"; di.pDataType = "RAW"; if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero)) { if (StartDocPrinter(hPrinter, 1, di)) { if (StartPagePrinter(hPrinter)) { bSuccess = WritePrinter(hPrinter, bytes, dwCount, out dwWritten); EndPagePrinter(hPrinter); } EndDocPrinter(hPrinter); } ClosePrinter(hPrinter); } if (bSuccess == false) { dwError = Marshal.GetLastWin32Error(); throw new Win32Exception(dwError); } return bSuccess; } } 

我用Zebra的旧版EPL2语言做到了这一点,但它应该与你需要用ZPL做的非常相似。 也许它会让你开始朝着正确的方向前进。

 public class Label { #region Print logic. Taken from http://support.microsoft.com/kb/322091 //Snip stuff unchanged from the KB example. [DllImport("winspool.Drv", EntryPoint="WritePrinter", SetLastError=true, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)] public static extern bool WritePrinter(IntPtr hPrinter, byte[] pBytes, Int32 dwCount, out Int32 dwWritten ); private static bool SendBytesToPrinter(string szPrinterName, byte[] Bytes, Int32 dwCount) { Int32 dwError = 0, dwWritten = 0; IntPtr hPrinter = new IntPtr(0); DOCINFOA di = new DOCINFOA(); bool bSuccess = false; di.pDocName = "Zebra Label"; di.pDataType = "RAW"; if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero)) { if (StartDocPrinter(hPrinter, 1, di)) { if (StartPagePrinter(hPrinter)) { bSuccess = WritePrinter(hPrinter, Bytes, dwCount, out dwWritten); EndPagePrinter(hPrinter); } EndDocPrinter(hPrinter); } ClosePrinter(hPrinter); } if (bSuccess == false) { dwError = Marshal.GetLastWin32Error(); throw new Win32Exception(dwError); } return bSuccess; } #endregion public byte[] CreateCompleteCommand(bool headerAndFooter) { List byteCollection = new List(); //Static header content describing the label. if (headerAndFooter) { byteCollection.AddRange(Encoding.ASCII.GetBytes("\nN\n")); byteCollection.AddRange(Encoding.ASCII.GetBytes(String.Format("S{0}\n", this.Speed))); byteCollection.AddRange(Encoding.ASCII.GetBytes(String.Format("D{0}\n", this.Density))); byteCollection.AddRange(Encoding.ASCII.GetBytes(String.Format("q{0}\n", this.LabelHeight))); if (this.AdvancedLabelSizing) { byteCollection.AddRange(Encoding.ASCII.GetBytes(String.Format("Q{0},{1}\n", this.LableLength, this.GapLength))); } } //The content of the label. foreach (var command in this.Commands) { byteCollection.AddRange(command.GenerateByteCommand()); } //The footer content of the label. if(headerAndFooter) byteCollection.AddRange(Encoding.ASCII.GetBytes(String.Format("P{0}\n", this.Pages))); return byteCollection.ToArray(); } public bool PrintLabel(string printer) { byte[] command = this.CreateCompleteCommand(true); return SendBytesToPrinter(printer, command, command.Length); } public List Commands { get; private set; } //Snip rest of the code. } public abstract partial class Epl2CommandBase { protected Epl2CommandBase() { } public virtual byte[] GenerateByteCommand() { return Encoding.ASCII.GetBytes(CommandString + '\n'); } public abstract string CommandString { get; set; } } public class Text : Epl2CommandBase { public override string CommandString { get { string printText = TextValue; if (Font == Fonts.Pts24) printText = TextValue.ToUpperInvariant(); printText = printText.Replace("\\", "\\\\"); // Replace \ with \\ printText = printText.Replace("\"", "\\\""); // replace " with \" return String.Format("A{0},{1},{2},{3},{4},{5},{6},\"{7}\"", X, Y, (byte)TextRotation, (byte)Font, HorziontalMultiplier, VertricalMultiplier, Reverse, printText); } set { GenerateCommandFromText(value); } } private void GenerateCommandFromText(string command) { if (!command.StartsWith(GetFactoryKey())) throw new ArgumentException("Command must begin with " + GetFactoryKey()); string[] commands = command.Substring(1).Split(','); this.X = int.Parse(commands[0]); this.Y = int.Parse(commands[1]); this.TextRotation = (Rotation)byte.Parse(commands[2]); this.Font = (Fonts)byte.Parse(commands[3]); this.HorziontalMultiplier = int.Parse(commands[4]); this.VertricalMultiplier = int.Parse(commands[5]); this.ReverseImageColor = commands[6].Trim().ToUpper() == "R"; string message = String.Join(",", commands, 7, commands.Length - 7); this.TextValue = message.Substring(1, message.Length - 2); // Remove the " at the beginning and end of the string. } //Snip }