it-swarm.com.de

Senden Sie das unformatierte ZPL über USB an den Zebra-Drucker

Normalerweise, wenn ich mein Zebra LP 2844-Z an den USB-Anschluss anschließe, sieht der Computer ihn als Drucker, und ich kann ihn wie jeder andere Drucker von Notepad aus drucken. Meine Anwendung verfügt jedoch über einige Barcode-Funktionen. Meine Anwendung analysiert einige Eingaben und generiert eine In-Memory-Zeichenfolge von ZPL. Wie sende ich diese ZPL-Daten an mein USB-Gerät?

18

Ich habe noch einen einfacheren Weg gefunden, einen Zebra-Drucker über einen COM-Anschluss zu schreiben. Ich ging zur Windows-Systemsteuerung und fügte einen neuen Drucker hinzu. Für den Port wählte ich COM1 (den Port, an den der Drucker angeschlossen wurde). Ich habe einen Druckertreiber "Generic/Text Only" verwendet. Ich habe den Druckerspooler (eine Standardoption in den Druckereinstellungen) sowie alle erweiterten Druckoptionen deaktiviert. Jetzt kann ich einfach eine beliebige Zeichenfolge auf diesem Drucker drucken. Wenn die Zeichenfolge ZPL enthält, wird die ZPL-Datei vom Drucker einwandfrei dargestellt. Keine speziellen "Startsequenzen" oder funky Sachen. Ja für die Einfachheit!

15

Ich habe die Antwort gefunden ... oder zumindest die einfachste Antwort (wenn es mehrere gibt). Bei der Installation des Druckers habe ich ihn in "ICS Label Printer" umbenannt. So ändern Sie die Optionen, um Passthrough-ZPL-Befehle zuzulassen:

  1. Klicken Sie mit der rechten Maustaste auf den "ICS-Etikettendrucker" und wählen Sie "Eigenschaften".
  2. Klicken Sie auf der Registerkarte "Allgemein" auf die Schaltfläche "Druckeinstellungen ...".
  3. Klicken Sie auf der Registerkarte "Advanced Setup" auf die Schaltfläche "Other".
  4. Stellen Sie sicher, dass das Kontrollkästchen "Passthrough-Modus aktivieren" aktiviert ist.
  5. Stellen Sie sicher, dass "Startsequenz:" "$ {" ist.
  6. Stellen Sie sicher, dass die "Endsequenz:" "} $" ist.
  7. Klicken Sie auf die Schaltfläche "Schließen".
  8. Klicken Sie auf die Schaltfläche "OK".
  9. Klicken Sie auf die Schaltfläche "OK".

In meinem Code muss ich nur "$ {" am Anfang meiner ZPL und "} $" am Ende hinzufügen und als reinen Text drucken. Dies ist bei dem "Windows-Treiber für ZDesigner LP 2844-Z Drucker Version 2.6.42 (Build 2382)" der Fall. Klappt wunderbar!

16

Visual Studio C # -Lösung (zu finden unter http://support.Microsoft.com/kb/322091 )

Schritt 1.) Klasse RawPrinterHelper erstellen ...

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;
    }
}

Schritt 2.) Erstellen Sie ein Formular mit Textfeld und Schaltfläche (Textfeld enthält die ZPL, die in diesem Beispiel gesendet werden soll). Klicken Sie im Button-Klick-Ereignis Code hinzufügen ...

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

Mit dieser Lösung können Sie an spezifische Anforderungen anpassen. Vielleicht den spezifischen Drucker hardcode. Leiten Sie den ZPL-Text möglicherweise dynamisch ab und nicht aus einem Textfeld. Was auch immer. Vielleicht benötigen Sie keine grafische Benutzeroberfläche, aber dies zeigt, wie Sie die ZPL versenden. Ihre Verwendung hängt von Ihren Bedürfnissen ab.

10
barrypicker

Sie haben keine Sprache erwähnt, daher werde ich Ihnen einige Hinweise geben, wie Sie dies mit der reinen Windows-API in C tun.

Öffnen Sie zunächst eine Verbindung zum Drucker mit OpenPrinter . Starten Sie anschließend ein Dokument mit StartDocPrinter , wobei das pDatatype-Feld der DOC_INFO_1 -Struktur auf "RAW" gesetzt ist. Dies gibt dem Druckertreiber an, nichts an den Drucker zu verschlüsseln, sondern unverändert weiterzuleiten. Verwenden Sie StartPagePrinter, um die erste Seite anzugeben, WritePrinter, um die Daten an den Drucker zu senden, und schließen Sie sie anschließend mit EndPagePrinter, EndDocPrinter und ClosePrinter.

8
Mark Ransom

ZPL ist der richtige Weg. In den meisten Fällen ist es richtig, einen Treiber zu verwenden, der zu GDI - Befehlen abstrahiert. Zebra-Etikettendrucker sind jedoch ein Sonderfall. Der beste Weg, um auf einem Zebra-Drucker zu drucken, besteht darin, ZPL direkt zu generieren. Beachten Sie, dass der eigentliche Druckertreiber für einen Zebra-Drucker ein "Nur-Text" -Drucker ist. Es gibt keinen "Treiber", der in dem Sinne aktualisiert werden könnte, in dem wir die meisten Drucker mit Treibern meinen. Es ist nur ein Fahrer im absoluten Minimalismus.

3
Ian

Installieren Sie eine Freigabe Ihres Druckers:\localhost\zebra Senden Sie ZPL als Text, versuchen Sie es mit Kopieren:

kopieren Sie file.zpl\localhost\zebra

sehr einfach, fast keine Kodierung.

0
Thomas

Ich habe 8 Stunden damit verbracht .. Das ist einfach ...

Sie sollten einen solchen Code haben:

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;

Ändern Sie den Inhalt der Variablen von 3 (geöffnete Datei ist bereits vorhanden) in 1 (neue Datei erstellen) . Dies funktioniert unter Windows 7 und XP.

0
Rodrigo Aquino