2010-12-14 787 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 \本地主機\斑馬

很簡單,幾乎沒有編碼。

相關問題