Frage

Normalerweise, wenn ich in meinem Zebra LP 2844-Z an den USB-Port anschließen, sieht der Computer es als Drucker und ich kann wie jede andere generische Drucker aus Notizblock drucken. Allerdings hat meine Anwendung einige Barcode-Funktionen. Meine Anwendung parst eine Eingabe und erzeugt eine In-Memory-Zeichenfolge von ZPL. Wie würde ich diese ZPL Daten zu meinem USB-Gerät senden?

War es hilfreich?

Lösung 2

Ich habe noch einen einfacheren Weg zu schreiben, an einen Zebra-Drucker über ein COM-Port gefunden. Ich ging in die Windows-Systemsteuerung und hat einen neuen Drucker. Für den Port, wähle ich COM1 (Anschluss für den Drucker eingesteckt wurde). Ich benutzte einen „Allgemein / Nur Text“ Druckertreiber. die Druck-Spooler (eine Standard-Option in den Druckereinstellungen) sowie alle erweiterten Druckoptionen I deaktiviert. Jetzt kann ich nur drucken Sie beliebige Zeichenfolge an den Drucker und wenn die Zeichenfolge ZPL enthält, macht der Drucker die ZPL einfach gut! Keine Notwendigkeit für spezielle „Startsequenzen“ oder flippige Sachen. Yay für Einfachheit!

Andere Tipps

fand ich die Antwort ... oder zumindest, die einfachste Antwort (wenn es mehrere sind). Wenn ich den Drucker installiert ist, umbenannt ich es auf „ICS Label Printer“. Hier ist, wie die Optionen zu ändern Passthrough-ZPL-Befehle zu ermöglichen:

  1. Rechtsklick auf das "ICS Label Printer" und wählen Sie "Eigenschaften".
  2. Auf der Registerkarte "Allgemein", klicken Sie auf den "Druckeinstellungen ..." Button.
  3. Auf der "Advanced Setup", klicken Sie auf den "Anderen" Taste.
  4. Stellen Sie sicher, dass es ein Häkchen in dem Feld mit der Bezeichnung „Enable Pass-Through-Modus“.
  5. Achten Sie auf die "Start-Sequenz:". Ist "$ {"
  6. Stellen Sie sicher, die "End-Sequenz:". 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, ich habe nur noch hinzufügen „$ {“ zu Beginn meiner ZPL und „} $“ bis zum Ende und drucken Sie es als Klartext. Dies ist mit den "Windows-Treiber für ZDesigner LP 2844-Z-Drucker Version 2.6.42 (Build 2382)". Arbeiten wie ein Charme!

Visual Studio C # Lösung (unter http://support.microsoft gefunden. com / kb / 322091 )

Schritt 1). Erstellen Klasse 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;
    }
}

Schritt 2). Erstellen Sie ein Formular mit Textfeld und Schaltfläche (Textfeld wird die ZPL hält in diesem Beispiel zu senden). In Schaltfläche klicken Ereignis Add Code ...

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 erfüllen spezifische Anforderungen zwicken. Vielleicht codiert den jeweiligen Drucker. Vielleicht leitet den ZPL Text dynamisch anstatt von einem Textfeld ein. Wie auch immer. Vielleicht brauchen Sie nicht eine grafische Oberfläche, aber dies zeigt, wie die ZPL zu senden. Ihre Nutzung hängt von Ihren Bedürfnissen.

Sie haben keine Sprache erwähnt, also werde ich Ihnen einige einige Hinweise geben, wie es mit dem geraden Windows-API in C zu tun.

Öffnen Sie zunächst eine Verbindung zum Drucker mit OpenPrinter . Als nächstes starten Sie ein Dokument mit StartDocPrinter dem pDatatype Feld des mit DOC_INFO_1 Struktur Set "RAW" - dies teilt den Druckertreiber nicht kodieren etwas mit dem Drucker, aber es entlang unverändert passieren. Verwenden StartPagePrinter, um anzuzeigen, um die erste Seite, WritePrinter die Daten an den Drucker zu senden, und schließen Sie es mit EndPagePrinter, EndDocPrinter und ClosePrinter wenn Sie fertig sind.

ZPL is the correct way to go. In most cases it is correct to use a driver that abstracts to GDI commands; however Zebra label printers are a special case. The best way to print to a Zebra printer is to generate ZPL directly. Note that the actual printer driver for a Zebra printer is a "plain text" printer - there is not a "driver" that could be updated or changed in the sense we think of most printers having drivers. It's just a driver in the absolute minimalist sense.

I spent 8 hours to do that. It is simple...

You shoud have a code like that:

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;

Change that variable content from 3 (open file already exist) to 1 (create a new file). It'll work at Windows 7 and XP.

Install an share your printer: \localhost\zebra Send ZPL as text, try with copy first:

copy file.zpl \localhost\zebra

very simple, almost no coding.

You can use COM, or P/Invoke from .Net, to open the Winspool.drv driver and send bytes directly to devices. But you don't want to do that; this typically works only for the one device on the one version of the one driver you test with, and breaks on everything else. Take this from long, painful, personal experience.

What you want to do is get a barcode font or library that draws barcodes using plain old GDI or GDI+ commands; there's one for .Net here. This works on all devices, even after Zebra changes the driver.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top