Saltar al contenido

Enviar comandos ESC a una impresora en C #

Solución:

He escrito en un blog sobre esto antes después de tener que hacerlo yo mismo. No quiero tocar mi propia bocina demasiado fuerte, pero te recomiendo que leas esa entrada, ya que hablo de un comando de imagen complejo con la impresora. Si puede entender eso, ¡puede imprimir cualquier cosa!

(Hablo de ESC / POS, utilizado en impresoras de recibos minoristas, pero la semántica de la discusión también se aplica a ESC / P, el antiguo lenguaje de matriz de puntos).

En resumen, use un BinaryWriter en lugar de un string o te confundirás irremediablemente (como yo) cuando ciertos caracteres se “horneen” con la codificación incorrecta en su camino a la impresora. (¡Confía en mí en este caso! No uses un StringBuilder al intentar hablar en ESC / POS.)

Tenga cuidado de no utilizar el Write(string) sobrecarga del BinaryWriter ya que antepondrá la longitud de la cadena como un byte en la secuencia, que no es lo que desea. (También escribí en un blog sobre eso después de aprenderlo de la manera difícil, también, en el mismo proyecto).

Luego utilizo un código para enviar el byte matriz, como se obtiene de la BinaryWriter, directamente a la impresora mediante P / Invocando:

private static void Print(string printerName, byte[] document)
{
    NativeMethods.DOC_INFO_1 documentInfo;
    IntPtr printerHandle;

    documentInfo = new NativeMethods.DOC_INFO_1();
    documentInfo.pDataType = "RAW";
    documentInfo.pDocName = "Bit Image Test";

    printerHandle = new IntPtr(0);

    if (NativeMethods.OpenPrinter(printerName.Normalize(), out printerHandle, IntPtr.Zero))
    {
        if (NativeMethods.StartDocPrinter(printerHandle, 1, documentInfo))
        {
            int bytesWritten;
            byte[] managedData;
            IntPtr unmanagedData;

            managedData = document;
            unmanagedData = Marshal.AllocCoTaskMem(managedData.Length);
            Marshal.Copy(managedData, 0, unmanagedData, managedData.Length);

            if (NativeMethods.StartPagePrinter(printerHandle))
            {
                NativeMethods.WritePrinter(
                    printerHandle,
                    unmanagedData,
                    managedData.Length,
                    out bytesWritten);
                NativeMethods.EndPagePrinter(printerHandle);
            }
            else
            {
                throw new Win32Exception();
            }

            Marshal.FreeCoTaskMem(unmanagedData);

            NativeMethods.EndDocPrinter(printerHandle);
        }
        else
        {
            throw new Win32Exception();
        }

        NativeMethods.ClosePrinter(printerHandle);
    }
    else
    {
        throw new Win32Exception();
    }
}

¡Buena suerte!

Pasar por alto el controlador de la impresora y controlar la impresora directamente, utilizando su lenguaje de comandos nativo, es un escenario compatible. El P / Invoke se explica bien en este artículo de KB.

¿Seguro que quieres hacer esto? Es poco común, por decirlo suavemente, que solo se intenta con impresoras térmicas o matriciales de punto de venta de bajo costo. Si no le gusta la mecánica de PrintDocument.PrintPage, a nadie le gusta, podría considerar mi código en este hilo. Tenga en cuenta el método FormFeed.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *