Cómo enviar un ZPL en bruto a una impresora cebra usando C # a través de USB

Soy un progtwigdor principiante de C #. Tengo un proyecto que me exige enviar el comando raw a la impresora Zebra LP 2844 a través de USB y hacer que funcione. Hice mucha investigación e intenté encontrar una manera de hacerlo. Estoy usando el código de http://support.microsoft.com/kb/322091 , pero no funcionó. Según mi prueba, parece que he enviado comandos a la impresora, pero no respondió e imprimió. No tengo idea sobre esto. ¿Alguien me puede ayudar?

Estoy usando el botón para enviar el comando directamente

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."); } } 

EDIT : para solucionar su actualización, el problema que tiene es que está usando SendStringToPrinter que envía una cadena ANSI (terminada en nulo) a la impresora, que no es lo que la impresora espera. De acuerdo con la guía de progtwigción oficial de EPL2, página 23 (que es lo que realmente estás haciendo, no ZPL según tu ejemplo).

Cada línea de comando debe terminar con un carácter de avance de línea (LF) (10 de diciembre). La mayoría de los sistemas basados ​​en PC envían CR / LF cuando se presiona la tecla Enter. La impresora ignora el carácter de retorno de carro (CR) y no se puede utilizar en lugar de LF.

Por lo tanto, debe modificar SendStringToPrinter para enviar un \n al final de la cadena en lugar de un \0 o debe crear la matriz de bytes ASCII usted mismo y usar RawPrinterHelper.SendBytesToPrinter (como lo hice en mi respuesta original).

Por lo tanto, para corregir su ejemplo simple publicado, cambiamos su llamada de función, también debemos decirle a la impresora que imprima realmente enviando un 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; } } 

Hice esto con el lenguaje EPL2 más antiguo de Zebra, pero debería ser muy similar a lo que necesitas hacer con ZPL. Tal vez te ayude a comenzar en la dirección correcta.

 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 }