lukevp / ESC-POS-.NET

Efficient, Easy to Use Thermal Printing & POS (Windows/Linux/OSX, WiFi/BT/USB/Ethernet)
MIT License
523 stars 171 forks source link

Error "Device or resourse busy" When I impress more the one time. #246

Closed detectivejd closed 11 months ago

detectivejd commented 11 months ago

Hi, how are you? I wait that you are good. I have the next trouble in Linux using this library:

image

I need to doing lots of impressions and only it impress the first ticket of the impress queue.

This is my code:

private byte[][] ObtenerTicketDeIngreso(Entrada tick, EPSON e)
{
    try
    {
        var sector = tick.NombrePuerta;
        var mensaje1 = tick.Mensaje1;
        var mensaje2 = tick.Mensaje2;
        var entradaFech = tick.FechaEntrada.ToString("dd-MM-yyyy HH:mm");

        var lineasImp = new List<byte[]>
        {
            e.CenterAlign()
        };

        //agrega lineas en blanco en el cabezal 
        for (int i = 0; i < CantLineasEnBlancoAntesDelCabezal; i++)
        {
            lineasImp.Add(e.PrintLine(""));
        }

        //Acomodo la razón social
        lineasImp.Add(e.SetStyles(PrintStyle.DoubleHeight | PrintStyle.DoubleWidth | PrintStyle.Bold));
        lineasImp.Add(e.PrintLine(tick.NombreEmpresa));
        lineasImp.Add(e.SetStyles(PrintStyle.None));

        if (!string.IsNullOrEmpty(tick.TelefonoEmpresa))
        {
            lineasImp.Add(e.PrintLine("Tel.: " + tick.TelefonoEmpresa));
        }

        lineasImp.Add(e.PrintLine(""));

        //Fin acomodo la razón social
        lineasImp.Add(e.PrintLine("MATRICULA"));
        lineasImp.Add(e.SetStyles(PrintStyle.DoubleHeight | PrintStyle.DoubleWidth | PrintStyle.Bold));
        lineasImp.Add(e.PrintLine(tick.Matricula));
        lineasImp.Add(e.SetStyles(PrintStyle.None));

        if (!string.IsNullOrEmpty(tick.DetallesVehiculo))
        {
            var detalles = tick.DetallesVehiculo.ToUpperInvariant().Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (var linea in detalles)
            {
                lineasImp.Add(e.PrintLine(linea));
            }
        }

        // 1 salto de linea
        lineasImp.Add(e.PrintLine(""));

        lineasImp.Add(e.PrintLine("HORA ENTRADA"));
        lineasImp.Add(e.PrintLine(entradaFech));
        // 1 salto de linea
        lineasImp.Add(e.PrintLine(""));

        //autonumerar el ticket 
        //TODO: aquí lo ideal sería poner el IdEntrada (de la tabla EntradaSalida que
        //sabemos es unico y nos sirve para rastraer en el sistema)
        //el servicio no resuelve eso 
        if (ActivarNumeracionTickets)
        {
            lineasImp.Add(e.PrintLine("NRO.: " + tick.FechaEntrada.ToString("MMddHHmmss")));
        }

        //ESCRIBE EL SECTOR si hay 
        if (!string.IsNullOrEmpty(sector))
        {
            lineasImp.Add(e.PrintLine("SECTOR: " + sector));
            lineasImp.Add(e.PrintLine("")); // 1 salto de linea
        }

        //texto al pie desde el config y parametro de salida 
        if (!string.IsNullOrWhiteSpace(mensaje1))
        {
            lineasImp.Add(e.PrintLine(mensaje1));
            lineasImp.Add(e.PrintLine(""));
        }

        if (!string.IsNullOrWhiteSpace(mensaje2))
        {
            lineasImp.Add(e.PrintLine(mensaje2));
            lineasImp.Add(e.PrintLine(""));
        }

        //agrega lineas en blanco en el pie
        for (int i = 0; i < CantLineasEnBlancoDespuesDelPie; i++)
        {
            lineasImp.Add(e.PrintLine(""));
        }

        lineasImp.Add(e.PrintLine("-"));
        lineasImp.Add(e.FullCutAfterFeed(0));

        //RealizarImpresion(lineasImp.ToArray());
        return lineasImp.ToArray();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        return Array.Empty<byte[]>();
    }
}

public void RealizarImpresionTicketIngreso(Entrada tick) {
    var e = new EPSON();

    try 
    {            
        var printer = new FilePrinter(filePath: Destino);
        printer.Write(ObtenerTicketDeIngreso(tick, e));
    } 
    catch(Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
    finally
    {
        e = null;
    }
}

I need to help with urgency, if you can answer me, I will appreciate it.

Greetings.

detectivejd commented 11 months ago

Please!, I need to help with this code, this proyect was migrated from .net framework 4.6.2 to .net 7 and it has a great value to the principal proyect that execute it.

You response me, please!.

igorocampos commented 11 months ago

So, is it printing the full receipt? What do you do to get it printing once again? Do you have to restart the application, do you have to unplug and replug the printer?

igorocampos commented 11 months ago

Have you tried to use the same printer instance for all your printing? Sounds like you are not destroying your FilePrinter instance after you have used it, and probably that's what is holding the connection. I would suggest looking at the ConsoleTests class to see how you could do it properly. But either you keep using the same instance of FilePrinter for all your prints, or you have to dispose of it, before trying to create a new instance. You could do that with using as showed below:

 using (FilePrinter printer = new FilePrinter(filePath: Destino))
detectivejd commented 11 months ago

Thank you for your answer, the issue was resolved, I needed that impress was a atribute class:

public FilePrinter Impresora { get; set; }

after of the new instance, I use my impress method of this way:

public void RealizarImpresionTicketIngreso(Entrada tick) { try { var e = new EPSON(); Impresora.Write(ObtenerTicketDeIngreso(tick, e)); } catch (Exception ex) { Console.WriteLine(ex.Message); } }

And it worked it:

image

Thanks for all. Greetings.

igorocampos commented 11 months ago

Sure thing, you created a property and persisted the instance of FilePrinter. Just a heads-up, that will not solve 100% of your problems, if you ever try to have a second instance of that class of yours, with a new FilePrinter property, you will get the same behavior as before.

mtarlac commented 1 month ago

Sorry for digging this up but what is the difference between 1.6 and 3.0?

After it prints the first time, I'm facing an error

System.IO.IOException: Device or resource busy : '/dev/usb/lp3'

I tried both options

var printerLinUsb = new FilePrinter(filePath: '/dev/usb/lp3'`, false);
...
printerLinUsb.Dispose();

and

using (var printerLinUsb = new FilePrinter(filePath: '/dev/usb/lp3'`, false))
{
...
}