2010-12-14 411 views
18

通常,当我将Zebra LP 2844-Z插入USB端口时,计算机将其视为打印机,并且可以像记事本一样通过其他普通打印机进行打印。不过,我的应用程序有一些条码功能。我的应用程序解析一些输入并生成一个ZPL的内存字符串。我将如何将这个ZPL数据发送到我的USB设备?通过USB发送原始ZPL到Zebra打印机

回答

14

我发现通过COM端口写入Zebra打印机的更简单的方法。我去了Windows控制面板并添加了一台新的打印机。对于端口,我选择了COM1(打印机所插入的端口)。我使用了“通用/纯文本”打印机驱动程序。我禁用了打印后台处理程序(打印机首选项中的标准选项)以及所有高级打印选项。现在,我可以打印任何字符串到打印机,如果字符串包含ZPL,打印机呈现ZPL就好了!不需要特殊的“开始序列”或类似的时髦的东西。耶为了简单!

+0

我有两个问题。 ** 1。**你是什么意思*“打印任何字符串到该打印机”*? ** 2。**禁用假脱机和高级打印选项是否会干扰其他打印机? – 2013-05-06 12:17:30

+1

您可以基于每台打印机禁用后台打印,因此关闭此打印机的后台打印程序不会影响任何其他打印机。 “打印任何字符串”表示我通过任何方式发送给打印机的任何内容都将被打印机视为ZPL。因此,如果您发送二进制数据(如Word文档或PDF),则Zebra打印机会将其解释为垃圾。如果打印文本文件和该文件中的文本包含有效的ZPL语句,则打印机将解释有效的ZPL语句并呈现标签。 – 2013-05-06 14:24:10

-1

您可以使用COM或从.Net的P/Invoke打开Winspool.drv驱动程序并将字节直接发送到设备。但你不想这样做;这通常只适用于您测试的一个驱动程序的一个版本上的一个设备,并且在其他所有设备上都会中断。从漫长而痛苦的个人体验中获取。

你想要做的是获得一个条形码字体或库,使用普通的旧GDI或GDI +命令绘制条形码;有一个用于.Net here。即使在Zebra更改驱动程序后,这也适用于所有设备。

+0

当你说......“你想要做的是获得一个条形码字体或库 GDI ......” - 这可能不是Jason想要的。也许他想发送原始的ZPL,而不是图形到打印机设备。 – barrypicker 2012-11-02 17:58:12

+1

由于Zebra ZPL语言包含各种类型的条形码,因此您可以使用斑马条码打印条形码,因此不需要此类解决方案。因此,您为所需的条形码编码,然后输入要打印的数字或字符串。它并不那么复杂..但并非所有的ZPL语言都很清楚,只是作为一个警告,它没有正确记录这个ZPL语言,我曾经有过一次文档,但仍有很多解释的余地​​。 (难怪因为他们也销售只写ZPL宏的软件,所以要求斑马人澄清是不能保护他们的产品的)。 – user613326 2013-03-20 18:20:20

7

您还没有提到的语言,所以我想给你一些一些提示如何与直的Windows API做在C.

首先,打开与OpenPrinter到打印机的连接。接下来,启动一个StartDocPrinter文档,将结构的DOC_INFO_1结构设置为"RAW" - 这会告诉打印机驱动程序不要对打印机进行任何编码,而是将其传递给打印机。使用StartPagePrinter指示第一页,WritePrinter将数据发送到打印机,并在完成后用EndPagePrinter,EndDocPrinterClosePrinter关闭。

+0

这看起来像它将正是我所需要的。当我有机会充分测试时,我会让你知道它对我有多好。谢谢! – 2010-12-14 19:41:31

16

我找到了答案......或者至少是最简单的答案(如果有多个答案的话)。当我安装打印机时,我将其重命名为“ICS标签打印机”。以下是如何更改的选项,允许直通ZPL命令:对“ICS标签打印机”

  1. 单击鼠标右键,选择“属性”。
  2. 在“常规”选项卡上,单击“打印首选项...”按钮。
  3. 在“高级设置”选项卡上,单击“其他”按钮。
  4. 确保在标有“Enable Passthrough Mode”的框中有一个检查。
  5. 确保“开始序列:”是“$ {”。
  6. 确保“结束序列:”是“} $”。
  7. 点击“关闭”按钮。
  8. 点击“确定”按钮。
  9. 点击“确定”按钮。

在我的代码中,我只需要将“$ {”添加到我的ZPL开头,然后将“} $”添加到最后并以纯文本的形式打印出来。这是“ZDesigner LP 2844-Z打印机版本2.6.42(Build 2382)的Windows驱动程序”。奇迹般有效!

+0

有趣。我不认为这是一个标准的驱动程序功能,它必须是Zebra驱动程序特有的。 – 2011-06-24 13:24:48

+0

@mark,它有一个基本的窗口功能,可以将一些东西放在流的前面,然后发送到设备。 ZPL是打印机的语言,确实是斑马特有的。 – user613326 2013-03-20 18:15:33

+0

@ user613326,我再也无法使用Zebra打印机,但是我只打开了另一台打印机驱动程序。高级选项卡上没有“其他”按钮,我找不到任何其他对直通模式的引用。所以不,它不是一个“基本的Windows功能”,它是这个驱动程序非常具体的东西。 – 2013-03-20 21:23:24

2

ZPL是正确的选择。在大多数情况下,使用抽象为GDI命令的驱动程序是正确的;然而斑马标签打印机是一种特殊情况。打印到Zebra打印机的最佳方式是直接生成ZPL。请注意,Zebra打印机的实际打印机驱动程序是“纯文本”打印机 - 没有一个“驱动程序”可以更新或更改,因为我们认为大多数具有驱动程序的打印机。这只是一个绝对极简主义的驱动力。

9

Visual Studio的C#解决方案(在http://support.microsoft.com/kb/322091找到)

步骤1)创建类RawPrinterHelper ...

using System; 
using System.IO; 
using System.Runtime.InteropServices; 

public class RawPrinterHelper 
{ 
    // Structure and API declarions: 
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
    public class DOCINFOA 
    { 
     [MarshalAs(UnmanagedType.LPStr)] 
     public string pDocName; 
     [MarshalAs(UnmanagedType.LPStr)] 
     public string pOutputFile; 
     [MarshalAs(UnmanagedType.LPStr)] 
     public string pDataType; 
    } 
    [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
    public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd); 

    [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
    public static extern bool ClosePrinter(IntPtr hPrinter); 

    [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
    public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di); 

    [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
    public static extern bool EndDocPrinter(IntPtr hPrinter); 

    [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
    public static extern bool StartPagePrinter(IntPtr hPrinter); 

    [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
    public static extern bool EndPagePrinter(IntPtr hPrinter); 

    [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
    public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten); 

    // SendBytesToPrinter() 
    // When the function is given a printer name and an unmanaged array 
    // of bytes, the function sends those bytes to the print queue. 
    // Returns true on success, false on failure. 
    public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount) 
    { 
     Int32 dwError = 0, dwWritten = 0; 
     IntPtr hPrinter = new IntPtr(0); 
     DOCINFOA di = new DOCINFOA(); 
     bool bSuccess = false; // Assume failure unless you specifically succeed. 

     di.pDocName = "My C#.NET RAW Document"; 
     di.pDataType = "RAW"; 

     // Open the printer. 
     if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero)) 
     { 
      // Start a document. 
      if (StartDocPrinter(hPrinter, 1, di)) 
      { 
       // Start a page. 
       if (StartPagePrinter(hPrinter)) 
       { 
        // Write your bytes. 
        bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten); 
        EndPagePrinter(hPrinter); 
       } 
       EndDocPrinter(hPrinter); 
      } 
      ClosePrinter(hPrinter); 
     } 
     // If you did not succeed, GetLastError may give more information 
     // about why not. 
     if (bSuccess == false) 
     { 
      dwError = Marshal.GetLastWin32Error(); 
     } 
     return bSuccess; 
    } 

    public static bool SendFileToPrinter(string szPrinterName, string szFileName) 
    { 
     // Open the file. 
     FileStream fs = new FileStream(szFileName, FileMode.Open); 
     // Create a BinaryReader on the file. 
     BinaryReader br = new BinaryReader(fs); 
     // Dim an array of bytes big enough to hold the file's contents. 
     Byte[] bytes = new Byte[fs.Length]; 
     bool bSuccess = false; 
     // Your unmanaged pointer. 
     IntPtr pUnmanagedBytes = new IntPtr(0); 
     int nLength; 

     nLength = Convert.ToInt32(fs.Length); 
     // Read the contents of the file into the array. 
     bytes = br.ReadBytes(nLength); 
     // Allocate some unmanaged memory for those bytes. 
     pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength); 
     // Copy the managed byte array into the unmanaged array. 
     Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength); 
     // Send the unmanaged bytes to the printer. 
     bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength); 
     // Free the unmanaged memory that you allocated earlier. 
     Marshal.FreeCoTaskMem(pUnmanagedBytes); 
     return bSuccess; 
    } 
    public static bool SendStringToPrinter(string szPrinterName, string szString) 
    { 
     IntPtr pBytes; 
     Int32 dwCount; 
     // How many characters are in the string? 
     dwCount = szString.Length; 
     // Assume that the printer is expecting ANSI text, and then convert 
     // the string to ANSI text. 
     pBytes = Marshal.StringToCoTaskMemAnsi(szString); 
     // Send the converted ANSI string to the printer. 
     SendBytesToPrinter(szPrinterName, pBytes, dwCount); 
     Marshal.FreeCoTaskMem(pBytes); 
     return true; 
    } 
} 

步骤2)创建文本框格式和按钮(在本例中,文本框将保存ZPL发送)。在按钮点击事件中添加代码...

private void button1_Click(object sender, EventArgs e) 
     { 
      // 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, textBox1.Text); 
       MessageBox.Show("Data sent to printer."); 
      } 
      else 
      { 
       MessageBox.Show("Data not sent to printer."); 
      } 
     } 

使用此解决方案,您可以调整以满足特定要求。也许硬编码特定的打印机。也许从文本框中动态获取ZPL文本。随你。也许你不需要图形界面,但是这显示了如何发送ZPL。您的使用取决于您的需求。

0

我花了8个小时做到这一点。 这是简单...

您768,16有一个这样的代码:

private const int GENERIC_WRITE = 0x40000000; 

//private const int OPEN_EXISTING = 3; 
private const int OPEN_EXISTING = 1; 
private const int FILE_SHARE_WRITE = 0x2; 
private StreamWriter _fileWriter; 
private FileStream _outFile; 
private int _hPort; 

。更改至1可变的内容从3(打开的文件已经存在)(创建新文件)。 它将在Windows 7和XP上运行。

0

安装的共享打印机:\本地主机\斑马 发送ZPL为文本,先用拷贝尝试:

副本file.zpl \本地主机\斑马

很简单,几乎没有编码。

相关问题