none
!!!!Help Como Imprimir directamente desde un Servicio Windows RRS feed

  • Pregunta

  • Hola a todos quisiera saber si es posible mandar a imprimir directamente los archivos de una carpeta especifica .

    Yo eh creado un servicio de windows que realize esa tarea , al inicio lo hise con un exe utilizando la clase printDocument pero al parecer necesitaba ser ejecutado por el usuario para que imprima, yo lo que intente hacer era poner el exe como tarea programada para que imprima los archivos de una carpeta pero no imprimia , era como si para imprimir necesitara ser ejecutado por el usuario.

    Por eso ahora me estoy inclinando por los Servicios de Windows pero no estoy seguro de que funcione

    lo eh probado pero no lo hace .

    Aqui les muestro el codigo del Servicio

     Protected Overrides Sub OnStart(ByVal args() As String)
         
            FileSystemWatcher1.Path = My.Settings.RutaCarpeta
            FileSystemWatcher1.EnableRaisingEvents = True
        End Sub
    
    
     Private Sub FileSystemWatcher1_Created(sender As Object, e As FileSystemEventArgs) Handles FileSystemWatcher1.Created
            Try
                'Threading.Thread.Sleep(3000)
                Dim folder As New DirectoryInfo(My.Settings.RutaCarpeta)
                Dim n As Integer = folder.GetFiles("*.txt").Count
                If n = 0 Then
                    'Timer1.Enabled = True
                    Exit Sub
                Else
                    Dim dt As DataTable = ObtenerColaImpresion()
                    If dt.Rows.Count = 0 Then
                        'Timer1.Enabled = True
                        Exit Sub
                    Else
                        Dim num As Integer = 0
                        Dim hilos() As Thread
                        Dim LIST As New List(Of Impresion)
                        For Each dr As DataRow In dt.Rows
                            For Each File As FileInfo In folder.GetFiles
                                With dr
                                    Dim name As String = .Item("NameFile")
                                    Dim Impresora As String = .Item("Impresora")
                                    Dim Listo As Boolean = .Item("bListo")
                                    If name.Trim = File.Name.Trim Then
                                        If Listo = True Then
    
    
                                            ReDim Preserve hilos(num)
                                            Dim obj As New Impresion(File.FullName, Impresora)
                                            LIST.Add(obj)
                                            hilos(num) = New Thread(New ThreadStart(AddressOf LIST(num).Imprimir))
                                            hilos(num).Start()
                                            num += 1
    
                                            
    
    
                                        End If
                                    End If
                                End With
    
    
    
                            Next
                        Next
                        Dim i, j As Integer
                        Do
                            j = 0
                            For i = 0 To UBound(hilos)
                                ' Comprobar si alguno de los Threads está "vivo"
                                ' si es así, indicarlo para que continue el bucle
                                If hilos(i).IsAlive() Then
                                    j = 1
                                End If
                            Next
                            ' Esto es necesario, para que todo siga funcionando
                            'DoEvents()
                        Loop While j = 1
                        
                        Erase hilos
                    End If
    
                End If
            Catch ex As Exception
                
                Try
                    EscribirLog(ex.Message)
                Catch ex2 As Exception
                    MsgBox(ex.Message + ", " + ex2.Message)
                   
                End Try
            End Try
        End Sub
    
    
    
    Public Class Impresion
        Private file As String = ""
        Private Impresora As String = ""
        Public Sub New(ByVal archivo As String, ByVal printer As String)
            Me.file = archivo
            Me.Impresora = printer
        End Sub
        Public Sub Imprimir()
            Dim sr As New StreamReader(file)
            Dim Str As String = sr.ReadToEnd
            sr.Close()
            Dim hPrinter As New IntPtr(0)
            'RawPrinterHelper.OpenPrinter(Impresora, hPrinter, IntPtr.Zero)
            Dim O = RawPrinterHelper.SendStringToPrinter(Str, Impresora)
            Dim fl As New FileInfo(file)
            fl.Delete()
            EliminarArchivoImpreso(fl.Name)
            'https://itraacv2-1.googlecode.com/svn-history/r14/trunk/App/Helpers/RawPrinterHelper.cs
            'http://www.codeproject.com/Tips/704989/Print-Direct-To-Windows-Printer-EPOS-Receipt
            fl = Nothing
        End Sub
    end class

    Mi gran duda es:

    si es posible imprimir directamente, sin que el usuario intervenga??

    yo necesito que el .exe o el servicio se este ejecutando en segundo plano, supervisando constantemente los archivos de una carpeta y mandarlos a imprimir directamente, sin que el usuario intervenga

    es posible esto??


    jeferson

    domingo, 22 de noviembre de 2015 23:39

Respuestas

  • Hola gracias por responder me interesa mas el codigo de tu metodo imprimir, la duda que tengo es si puedo leer un archivo config indicandole la impresora a solo se le tiene q mandar en el codigo, lo digo para hacerlo mas configurable

    jeferson

    Hola

    En mi servicio yo mando a imprimir PDF, lo hago de esta manera.

    private void imprimir(String rutaArchivo,String impresora)
            {
                ProcessStartInfo info = new ProcessStartInfo();
                info.Verb = "PrintTo";
                info.Arguments = "\""+impresora+"\"";
                info.FileName = @rutaArchivo;
                info.CreateNoWindow = true;
                info.WindowStyle = ProcessWindowStyle.Hidden;
    
                Process p = new Process();
                p.StartInfo = info;
                p.Start();
    
                p.WaitForInputIdle();
                System.Threading.Thread.Sleep(3000);
                if (false == p.CloseMainWindow())
                    p.Kill();
            }

    Si tu usas alguna impresora de tickets deberas hacerlo con tu rutina.

    Saludos

    martes, 24 de noviembre de 2015 4:49

Todas las respuestas

  • Hola a todos,

    Tengo un .exe que lo que hace es supervisar una carpeta cuando se crea un archivo txt en dicha carpeta el .exe se ejecuta y lee el contenido del txt y lo manda a imprimir a una impresora especifica despues de la impresion el exe elimina el txt

    Este exe lo puse como tarea programada pero no lo manda a imprimir es como si necesitara interaccion con el usuario.

    La impresora es una Zebra TLP 2844

    Mi duda es si  un .exe que esta como tarea programada  puede mandar a imprimir sin que el usuario intervenga????

    Aqui este el codigo del exe

    Imports System.IO
    Imports System.Threading
    Imports System.Data
    Public Class Form1
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Me.Visible = False
            Me.Hide()
            Try
               
                FileSystemWatcher1.Path = My.Settings.RutaCarpeta
                FileSystemWatcher1.EnableRaisingEvents = True
    
            Catch ex As Exception
               
                Try
    
                    EscribirLog(ex.Message)
                Catch ex2 As Exception
                    MsgBox(ex.Message + ", " + ex2.Message)
                End Try
            Finally
    
            End Try
           
        End Sub
        Dim str As String = ""
        
        
        Private Function ObtenerColaImpresion() As DataTable
            Using cn As New SqlClient.SqlConnection(My.Settings.Conexion)
                If cn.State <> ConnectionState.Open Then
                    cn.Open()
                End If
                Dim cmd As New SqlClient.SqlCommand("DMS_SP_SUPERVISAR_COLA_IMPRESION", cn)
                cmd.CommandType = CommandType.StoredProcedure
                Dim da As New SqlClient.SqlDataAdapter(cmd)
                Dim dt As New DataTable
                da.Fill(dt)
                Return dt
                dt = Nothing
            End Using
        End Function
        Private Sub EscribirLog(ByVal msj As String)
            Try
                Dim sw As New StreamWriter(Application.StartupPath + "\Log.txt", True)
                sw.WriteLine("Fecha: " + Date.Now.ToString("dd/MM/yyyy HH:mm:ss") + ", Error: " + msj)
                sw.Close()
            Catch ex As Exception
                Throw ex
            End Try
        End Sub
    
       
    
    
        Private Sub FileSystemWatcher1_Created(sender As Object, e As FileSystemEventArgs) Handles FileSystemWatcher1.Created
            Try
              
                Dim folder As New DirectoryInfo(My.Settings.RutaCarpeta)
                Dim n As Integer = folder.GetFiles("*.txt").Count
                If n = 0 Then
                   
                    Exit Sub
                Else
                    Dim dt As DataTable = ObtenerColaImpresion()
                    If dt.Rows.Count = 0 Then
                        
                        Exit Sub
                    Else
                        Dim num As Integer = 0
                        Dim hilos() As Thread
                        Dim LIST As New List(Of Impresion)
                        For Each dr As DataRow In dt.Rows
                            For Each File As FileInfo In folder.GetFiles
                                With dr
                                    Dim name As String = .Item("NameFile")
                                    Dim Impresora As String = .Item("Impresora")
                                    Dim Listo As Boolean = .Item("bListo")
                                    If name.Trim = File.Name.Trim Then
                                        If Listo = True Then
    
    
                                            ReDim Preserve hilos(num)
                                            Dim obj As New Impresion(File.FullName, Impresora)
                                            LIST.Add(obj)
                                            hilos(num) = New Thread(New ThreadStart(AddressOf LIST(num).Imprimir))
                                            hilos(num).Start()
                                            num += 1
    
                             
                                        End If
                                    End If
                                End With
    
    
    
                            Next
                        Next
                        Dim i, j As Integer
                        Do
                            j = 0
                            For i = 0 To UBound(hilos)
                                ' Comprobar si alguno de los Threads está "vivo"
                                ' si es así, indicarlo para que continue el bucle
                                If hilos(i).IsAlive() Then
                                    j = 1
                                End If
                            Next
                            ' Esto es necesario, para que todo siga funcionando
                            Application.DoEvents()
                        Loop While j = 1
                        'Timer1.Enabled = True
                        Erase hilos
                    End If
    
                End If
            Catch ex As Exception
                MessageBox.Show(ex.Message)
                Try
                    EscribirLog(ex.Message)
                Catch ex2 As Exception
                   
                End Try
            End Try
        End Sub
       
    End Class
    Public Class Impresion
        Private file As String = ""
        Private Impresora As String = ""
        Public Sub New(ByVal archivo As String, ByVal printer As String)
            Me.file = archivo
            Me.Impresora = printer
        End Sub
        Public Sub Imprimir()
            Dim sr As New StreamReader(file)
            Dim Str As String = sr.ReadToEnd
            sr.Close()
            Dim hPrinter As New IntPtr(0)
            'RawPrinterHelper.OpenPrinter(Impresora, hPrinter, IntPtr.Zero)
            Dim O = RawPrinterHelper.SendStringToPrinter(Str, Impresora)
            Dim fl As New FileInfo(file)
            fl.Delete()
            EliminarArchivoImpreso(fl.Name)
            'https://itraacv2-1.googlecode.com/svn-history/r14/trunk/App/Helpers/RawPrinterHelper.cs
            'http://www.codeproject.com/Tips/704989/Print-Direct-To-Windows-Printer-EPOS-Receipt
            fl = Nothing
        End Sub
        Private Sub EliminarArchivoImpreso(ByVal name As String)
            Using cn As New SqlClient.SqlConnection(My.Settings.Conexion)
                If cn.State <> ConnectionState.Open Then
                    cn.Open()
                End If
                Dim cmd As New SqlClient.SqlCommand("DMS_SP_ELIMINAR_FILE_IMPRESOS", cn)
                cmd.CommandType = CommandType.StoredProcedure
                cmd.Parameters.AddWithValue("@NAME", name)
                Dim N As Integer = cmd.ExecuteNonQuery()
                If N = 0 Then
                    Throw New Exception("No se elimino ningun registro impreson, archivo a eliminar: " + name)
    
                End If
            End Using
        End Sub
    End Class

    De antemano gracias


    jeferson


    domingo, 22 de noviembre de 2015 8:27
  • Hola

    Claro que es factible hacerlo, el usuario puede dejar los archivos en una carpeta y cada determinado tiempo ir por ellos para mandarlos a imprimir con tu rutina.

    En mi caso yo hago esto para leer archivos de una carpeta y procesarlos.

    Private Sub procesarDocumentos()
            Dim di As IO.DirectoryInfo
            Dim aryFi As IO.FileInfo()
            Dim fi As IO.FileInfo
    
            Dim strFileSize As String = ""
    
    
            Try
                wsclient = New WSClient
                wsclient.Parent = Me
                While procesando
                    di = New IO.DirectoryInfo("C:\archivosimprimir\")
                    aryFi = di.GetFiles("*.xml")
                    For Each fi In aryFi
                        Try
                           'lo mandamos a imprimir
                            imprimir(fi.Name)
                           ' se mueve para no mandarlo a imprimir
                            fi.MoveTo("C:\rutaprocesado\" & fi.Name)
                        Catch ex As Exception
                            'tu tratamiento por si no puedes leerlo
                        End Try
                    Next
                    'se pausa el proceso para esperar a que lleguen mas archivos
                    tCliente.Sleep(1000)
                End While
            Catch ex As Exception
                'por si pasa algo leyendo el archivo
            End Try
        End Sub
        
        
       Dim tCliente As Thread
        Protected Overrides Sub OnStart(ByVal args() As String)
    
            tCliente = New Thread(AddressOf procesarDocumentos)
            tCliente.Start()
    
        End Sub

    Saludos

    lunes, 23 de noviembre de 2015 1:50
  • Hola gracias por responder me interesa mas el codigo de tu metodo imprimir, la duda que tengo es si puedo leer un archivo config indicandole la impresora a solo se le tiene q mandar en el codigo, lo digo para hacerlo mas configurable

    jeferson

    martes, 24 de noviembre de 2015 4:40
  • Hola gracias por responder me interesa mas el codigo de tu metodo imprimir, la duda que tengo es si puedo leer un archivo config indicandole la impresora a solo se le tiene q mandar en el codigo, lo digo para hacerlo mas configurable

    jeferson

    Hola

    En mi servicio yo mando a imprimir PDF, lo hago de esta manera.

    private void imprimir(String rutaArchivo,String impresora)
            {
                ProcessStartInfo info = new ProcessStartInfo();
                info.Verb = "PrintTo";
                info.Arguments = "\""+impresora+"\"";
                info.FileName = @rutaArchivo;
                info.CreateNoWindow = true;
                info.WindowStyle = ProcessWindowStyle.Hidden;
    
                Process p = new Process();
                p.StartInfo = info;
                p.Start();
    
                p.WaitForInputIdle();
                System.Threading.Thread.Sleep(3000);
                if (false == p.CloseMainWindow())
                    p.Kill();
            }

    Si tu usas alguna impresora de tickets deberas hacerlo con tu rutina.

    Saludos

    martes, 24 de noviembre de 2015 4:49