1
votes

I am working on building a website that will print ZPL code to a Zebra printer "140XiIII". The specifics are as follows:

  1. The Printer is connected to the computer via Parallel Port.

  2. The Printer is not connected to the network.

  3. Website Administrator wished to avoid Javascript use if at all possible and instead focus on C#.

I have tried using the code at .NET code to send ZPL to Zebra printers that states that it will work on any port. I run through the code and get no errors, but also nothing gets sent to the printer.

I have attempted to decipher and use the InpOut32/64 DLL, though that is more complicated than my meager learnings are able to understand.

Other options either require the printer be connected to the network, or are outdated and no longer an option due to no longer being in the Windows code.

Thank you.

3
the printer is on Client computer or on Host computer?, for print you has tryed send ZPL code or PrintDocument o how you send data to printer?henoc salinas
have you checked if your ZPL code is correct? There are online ZPL viewers where you can check if your ZPL code is working. I know for a fact that our own Zebra printers don't complain about ZPL errors, they just silently discard the print job.Dirk Trilsbeek
@HansPassant I have been attempting those code variations. the first on (11) uses a form that is no longer supported, FileStream. The second one (32) is trying to call forms, which makes me think that it seems to be intended for webforms and not .net. the third option, (System.IO.File.Copy(inputFilePath, printerPath);) is for a shared printer, this one is not shared, or even on the network. Option 4 (9) is currently being shoehorned into the code to try it. the other options are either VB or networked printer options, neither of which are viable for this situation.Ingram Yates
@DirkTrilsbeek I will see if i can dig one of those up and check. I'm pulling the code directly from the old method(VB6 code) and may be borking it.Ingram Yates

3 Answers

2
votes

I would suggest trying the following:

  • Log into the server, preferably as the user that the service is set to run as.
  • Ensure your Zebra printer is installed as a local printer, and the printer name is correct.
  • Print a test page from the printer properties.
  • Print your ZPL manually:

net use lpt1 "printer shared name" print "C:\Users\serviceuser\desktop\label.txt"

If you try the above and it works, I would be surprised that the code you linked does not work.

0
votes

i develop a websockt for this cases ZPLwebSocket

  1. Download the file and uncompress.
  2. Run SetUp.exe on client PC.
  3. Go to services and start 'Servicio de Impresion desde Navegador'
  4. open trysocket.html with GoogleChrome or mozilla
  5. write the name of local printer
  6. click on button 'enviar'
  7. show the messages of server

    this is javascriptcode on page.

    $(document).ready(function () {  var connection = new WebSocket('ws://localhost:2645/service/');  const reader = new FileReader();
    
      $('.sendZPL').on('click', function () {
    
        var tosend = {
          TipoArchivo: 0,
          nombre: "Etiqueta de Prueba",
          code: $(".sendZPL").val(),
          Tipo: 4,
          Impresora: $(".impresora").val()
        }
        connection.send(JSON.stringify(tosend));
      });
    
      connection.addEventListener('message', function (event) {
        reader.readAsText(event.data);
      });
    
      reader.addEventListener('loadend', (e) => {
        const text = e.srcElement.result;
        console.log(text);
        $(".serverResponse").val(text);
      });
    
    });
    

this is the socket code c# for run on ConsoleApp:

class Program
{

    private static Server.WebsocketServer websocketServer;
    private static System.Diagnostics.EventLog eventLog1= new EventLog();
    static void Main( string[] args )
    {
        if (!System.Diagnostics.EventLog.SourceExists( "MySource" ))
        {
            System.Diagnostics.EventLog.CreateEventSource(
                "MySource", "MyNewLog" );
        }

        eventLog1.Source = "MySource";
        eventLog1.Log = "MyNewLog";


        websocketServer = new Server.WebsocketServer();
        websocketServer.LogMessage += WebsocketServer_LogMessage; 

        websocketServer.Start( "http://localhost:2645/tryservice/" );

        Console.Read();
    }



    private static void WebsocketServer_LogMessage( object sender, Server.WebsocketServer.LogMessageEventArgs e )
    {
        // eventLog1.WriteEntry( e.Message );
        Console.ForegroundColor = ConsoleColor.Yellow;
        Console.WriteLine( e.Message );
        Console.ForegroundColor = ConsoleColor.White;
    }
public  class WebsocketServer
{
    public event OnLogMessage LogMessage;
    public delegate void OnLogMessage(Object sender, LogMessageEventArgs e);
    public class LogMessageEventArgs : EventArgs
    {
        public string Message { get; set; }
        public LogMessageEventArgs(string Message) {
            this.Message = Message;
        }
    }

    public bool started = false;
    public async void Start(string httpListenerPrefix)
    {
        HttpListener httpListener = new HttpListener();
        httpListener.Prefixes.Add(httpListenerPrefix);
        httpListener.Start();
        LogMessage(this, new LogMessageEventArgs("Listening..."));
        started = true;

        while (started)
        {
            HttpListenerContext httpListenerContext = await httpListener.GetContextAsync();
            if (httpListenerContext.Request.IsWebSocketRequest)
            {
                ProcessRequest(httpListenerContext);
            }
            else
            {
                httpListenerContext.Response.StatusCode = 400;
                httpListenerContext.Response.Close();
                LogMessage(this, new LogMessageEventArgs("Closed..."));
            }
        }
    }

    public void Stop()
    {
        started = false;
    }

    private List<string> _printers = new List<string>();
    public List<string> Printers { get
        {
            _printers.Clear();
            foreach (string imp in System.Drawing.Printing.PrinterSettings.InstalledPrinters)
            {
                _printers.Add(imp);
            }
            return _printers;
        }
    }

    private async void ProcessRequest(HttpListenerContext httpListenerContext)
    {
        WebSocketContext webSocketContext = null;

        try
        {
            webSocketContext = await httpListenerContext.AcceptWebSocketAsync(subProtocol: null);
            LogMessage(this, new LogMessageEventArgs("Connected"));
        }
        catch (Exception e)
        {
            httpListenerContext.Response.StatusCode = 500;
            httpListenerContext.Response.Close();
            LogMessage(this, new LogMessageEventArgs(String.Format("Exception: {0}", e)));
            return;
        }

        WebSocket webSocket = webSocketContext.WebSocket;
        try
        {


            while (webSocket.State == WebSocketState.Open)
            {

                ArraySegment<Byte> buffer = new ArraySegment<byte>(new Byte[8192]);

                WebSocketReceiveResult result = null;

                using (var ms = new System.IO.MemoryStream())
                {
                    do
                    {
                        result = await webSocket.ReceiveAsync(buffer, CancellationToken.None);
                        ms.Write(buffer.Array, buffer.Offset, result.Count);
                    }
                    while (!result.EndOfMessage);

                    ms.Seek(0, System.IO.SeekOrigin.Begin);

                    if (result.MessageType == WebSocketMessageType.Text)
                    {
                        using (var reader = new System.IO.StreamReader(ms, Encoding.UTF8))
                        {
                            var r = System.Text.Encoding.UTF8.GetString(ms.ToArray());
                            var t = Newtonsoft.Json.JsonConvert.DeserializeObject<Datos>(r);
                            bool valid = true;
                            byte[] toBytes = Encoding.UTF8.GetBytes("Error..."); ;

                            if (t != null)
                            {
                                if (t.Impresora.Trim() == string.Empty)
                                {
                                    var printers = "";
                                    Printers.ForEach(print => {
                                        printers += print + "\n";
                                    });

                                    toBytes = Encoding.UTF8.GetBytes("No se Indicó la Impresora\nLas Impresoras disponibles son:\n" + printers);
                                    valid = false;
                                }
                                else if(!Printers.Contains(t.Impresora))
                                {
                                    var printers = "";
                                    Printers.ForEach(print =>
                                    {
                                        printers += print + "\n";
                                    });

                                    toBytes = Encoding.UTF8.GetBytes("Impresora no valida\nLas Impresoras disponibles son:\n" + printers);
                                    valid = false;
                                }


                                if (t.nombre.Trim() == string.Empty)
                                {
                                    toBytes = Encoding.UTF8.GetBytes("No se Indicó el nombre del Documento");
                                    valid = false;
                                }
                                if (t.code== null)
                                {
                                    toBytes = Encoding.UTF8.GetBytes("No hay datos para enviar a la Impresora");
                                    valid = false;
                                }


                                if (valid && print.RawPrinter.SendStringToPrinter(t.Impresora, t.code, t.nombre))
                                {
                                    LogMessage(this, new LogMessageEventArgs(String.Format("Enviado: {0} => {1} => {2}", t.Impresora, t.nombre, t.code)));
                                    toBytes = Encoding.UTF8.GetBytes("Correcto...");
                                }

                                await webSocket.SendAsync(new ArraySegment<byte>(toBytes, 0, int.Parse(toBytes.Length.ToString())), WebSocketMessageType.Binary, result.EndOfMessage, CancellationToken.None);


                            }
                            else
                            {
                                toBytes = Encoding.UTF8.GetBytes("Error...");
                                await webSocket.SendAsync(new ArraySegment<byte>(toBytes, 0, int.Parse(toBytes.Length.ToString())), WebSocketMessageType.Binary, result.EndOfMessage, CancellationToken.None);
                            }
                        }
                    }
                }
            }
        }
        catch (Exception e)
        {
            LogMessage(this, new LogMessageEventArgs(String.Format("Exception: {0} \nLinea:{1}", e, e.StackTrace)));
        }
        finally
        {
            if (webSocket != null)
                webSocket.Dispose();
        }
    }


}

public class Datos {
    public enum TipoArchivo { zpl, pdf, doc, json, text}
    public string nombre { get; set; }
    public string code { get; set; }
    public TipoArchivo Tipo { get; set; } = TipoArchivo.text;
    public string Impresora { get; set; } = "";
}


}

the RAWPrinterClass link:

 public class RawPrinter
    {
        // 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, ref IntPtr hPriknter, 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, ref 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, string DocName = "")
        {
            Int32 dwError = 0;
            Int32 dwWritten = 0;
            IntPtr hPrinter = new IntPtr(0);
            DOCINFOA di = new DOCINFOA();
            bool bSuccess = false;
            // Assume failure unless you specifically succeed.
            di.pDocName = string.IsNullOrEmpty(DocName) ? "My C#.NET RAW Document" : DocName;
            di.pDataType = "RAW";

            // Open the printer.
            if (OpenPrinter(szPrinterName.Normalize(), ref 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, ref 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 = 0;

            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, string DocName = "")
        {
            IntPtr pBytes = default(IntPtr);
            Int32 dwCount = default(Int32);
            // 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.
            var t= SendBytesToPrinter(szPrinterName, pBytes, dwCount, DocName);
            Marshal.FreeCoTaskMem(pBytes);
            return t;
        }
    }
0
votes

what seems to be the correct answer for the specific situation we are looking to cover is that it is not possible to print to our zebra printer given the constraints we are under. Since this printer is NOT connected to the network, we are having to go with a stand-alone desktop app that will do what we need.

Thank you to everyone who assisted and offered their thoughts and ideas.