2014-09-04 2 views
5

Я начинающий программист на C#. У меня есть проект, который требует от меня отправить необработанную команду на принтер Zebra LP 2844 через USB и заставить его работать. Я провел много исследований и попытался выяснить, как это сделать. Я использую код от http://support.microsoft.com/kb/322091, но это не сработало. Основываясь на моем тесте, кажется, что я отправил команды на принтер, но он не ответил и не распечатал. Я понятия не имею об этом. Кто-нибудь может мне помочь?Как отправить необработанный ZPL на принтер Zebra с помощью C# через USB

Я использую кнопку, чтобы послать команду непосредственно

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

Это не похоже на ZPL, это похоже на EPL. Команды ZPL обычно начинаются с '^', а затем буквы. –

ответ

12

EDIT: Для того, чтобы решить ваши обновления, проблема у Вас есть это вы используете SendStringToPrinter который посылает ANSI строку (оканчивающийся нуль) на принтер, который не является ожидаемым принтером. По словам должностного лица EPL2 programming guide стр. 23 (Это то, что вы действительно делаете, а не ZPL в соответствии с вашим примером).

Каждая командная строка должна быть завершена символом линии подачи (LF) (10 декабря). Большинство систем на базе ПК отправляют CR/LF, когда нажата клавиша Enter . Символ возврата каретки (CR) игнорируется принтером и не может использоваться вместо LF.

Таким образом, вы должны либо изменить SendStringToPrinter отправить \n в конце строки вместо \0 или вы должны построить массив, ASCII BYTE себя и использовать 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; 
    } 
} 

Я сделал это со старым Ефл2 языка компанией Zebra, но он должен быть очень похож на то, что вам нужно делать с 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<byte> byteCollection = new List<byte>(); 

     //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<Epl2CommandBase> 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 
} 
+0

Спасибо u !! это очень специфично! Я оценил! –

+0

@ShawnLou, если я ответил на ваш вопрос, отметьте ответ как принятый. –