2014-09-04 1049 views
5

我是初學C#程序員。我有一個項目需要我通過USB將原始命令發送到Zebra打印機LP 2844,並使其工作。我做了很多研究,並試圖找出一種方法來做到這一點。我使用的代碼來自http://support.microsoft.com/kb/322091,但它不起作用。根據我的測試,似乎我已經將命令發送到打印機,但它沒有響應和打印。我不知道這件事。有人可以幫我嗎?如何使用C#通過USB將原始ZPL發送到斑馬打印機

我使用按鈕發送命令直接

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命令通常以'^'開始,然後是一個字母。 – 2014-09-04 18:23:13

回答

12

編輯:爲了解決您的更新,您遇到的問題是您正在使用SendStringToPrinter它發送一個ANSI字符串(終止空)字符串到打印機,這不是打印機所期望的。根據官方EPL2 programming guide page 23(這是你真正在做的,而不是你的例子中的ZPL)。

每個命令行必須以換行(LF)字符 (Dec. 10)終止。當Enter鍵爲 時,大多數基於PC的系統發送CR/LF。回車(CR)字符被打印機 忽略,不能用於LF的位置。

所以你必須修改SendStringToPrinter到字符串的結尾而不是\0發送\n或者你必須自己建立的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<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

謝謝你!它非常具體!我很感激! – 2014-09-04 18:46:53

+0

@ShawnLou如果我回答了您的問題,請將答案標記爲已接受。 – 2014-09-04 18:48:09

相關問題