2012-08-02 12 views
14

Tengo una aplicación donde necesito imprimir un ticket. Cada boleto debe ser único. La aplicación es formularios de Windows y está escrita completamente en C#. Para nuestra aplicación, utilizamos impresoras láser monocromáticas Samsung ML-2525.¿Hay alguna manera de verificar si un proceso de impresión fue exitoso?

El flujo es básicamente el siguiente, el operador retira un producto/billete (que es única) y luego se presiona un botón que hace 2 cosas:

  1. se conecta a una base de datos y actualiza el producto tal como se utiliza
  2. imprime el billete (esto se hace usando System.Drawing y GDI +)

Por alguna razón, cada vez en cuando, la imagen que necesita ser impreso no se envía a la impresora. Es un caso raro, pero sucede.

Intenté conectarme a la impresora usando Win32_Printer (http://msdn.microsoft.com/en-us/library/Aa394363) pero no puedo obtener el estado actual de la impresora (en línea, fuera de línea, bajo tóner, atasco de papel, etc.). Solo puedo verificar si la impresora existe y si el tamaño del papel está instalado correctamente. Probé un código similar al siguiente, pero no funcionó

private string MonitorPrintJobWmi() 
    { 
     var jobMessage = String.Empty; 
     var scope = new ManagementScope(ManagementPath.DefaultPath); 
     scope.Connect(); 

     var selectQuery = new SelectQuery { QueryString = @"select * from Win32_PrintJob" }; 

     var objSearcher = new ManagementObjectSearcher(scope, selectQuery); 
     var objCollection = objSearcher.Get(); 

     foreach (var job in objCollection) 
     { 
      if (job != null) 
      { 
       jobMessage += String.Format("{0} \r\n", job["Name"].ToString()); 
       jobMessage += String.Format("{0} \r\n", job["JobId"].ToString()); 
       _jobId = Convert.ToInt32(job["JobId"]); 
       jobMessage += String.Format("{0} \r\n", job["JobStatus"].ToString()); 
       jobMessage += String.Format("{0} \r\n", job["Status"].ToString()); 
      } 
     } 
     return jobMessage; 
    } 

He intentado conseguir una API para la impresora, pero no pude conseguir un asimiento de él. Por cierto, el software de la impresora indica diferentes errores en la barra de herramientas de Windows.

Mi pregunta es si alguien me puede orientar en la dirección correcta sobre cómo conectarse a una impresora y verificar si la impresión fue exitosa.

Además, sería útil si alguien sabe de alguna otra impresora específica en la que pueda lograr esto, es decir, cambiar el hardware.

Gracias,

+0

See related: http://stackoverflow.com/questions/1921487/confirm-successful-print-programmatically-in- windows – Eugene

+0

Lo hice, pero un código de ejemplo para obtener una ventaja sería beneficioso. – lopezbertoni

+2

@lopezbertoni Un poco de Google le mostrará cómo usar esos métodos vinculados en aplicaciones C# ... como http://www.codeproject.com/Articles/51085/Monitor-jobs-in-a-printer-queue-NET –

Respuesta

5

Para obtener una lista de colas de impresión en la máquina local, probar el método el servidor de impresión GetPrintQueues.

Una vez que tenga una instancia del objeto PrintQueue asociado con la impresora correspondiente, puede usarla para acceder al estado de la impresora (IsOffline, IsPaperOut, etc.). Además, puede usarlo para obtener una lista de los trabajos en la cola dada (GetPrintJobInfoCollection) que luego le permitirá obtener información de estado específica del trabajo (IsInError, IsCompleted, IsBlocked, etc.).

Espero que esto ayude!

+1

gracias por la entrada. Intenté usar el enfoque que mencionaste pero no tuve éxito. El principal problema es que el trabajo llega a la cola y luego desaparece de ella, y la impresora no completa el trabajo de impresión. – lopezbertoni

+0

Si comienza a mirar la cola antes de enviar el trabajo a la impresora, me pregunto si puede ver el trabajo tan pronto como aparezca en la cola .... –

+0

¿Por qué no está marcado como respuesta? Esto me ha ayudado mucho. Pude hacer que esto funcionara al observar el número de trabajos enviados desde el cliente específico 'PrintQueue.Submitter', luego de intentar la impresión, obtuve la lista de los trabajos recién agregados y simplemente verifiqué que estuvieran completos . También puede obtener el estado de cada trabajo o la propia impresora a través de esta API. Incluso hay una identificación de trabajo y la información del boleto. –

0

Después de intentar imprimir su PrintDocument (System.Drawing.Printing), intente verificar el estado de printjobs.

Primer paso: Inicialice su printDocument.

Segundo paso: Obtener el nombre de la impresora System.Drawing.Printing.PrinterSettings.InstalledPrinters.Cast<string>();

y copiarlo en su printerDocument.PrinterSettings.PrinterName

Tercer paso: Trate de imprimir y desechar.

printerDocument.Print(); 
printerDocument.Dispose(); 

Último paso: Ejecute el control en una Tarea (NO bloquee el hilo de la IU).

Task.Run(()=>{ 
    if (!IsPrinterOk(printerDocument.PrinterSettings.PrinterName,checkTimeInMillisec)) 
    { 
     // failed printing, do something... 
    } 
    }); 

Aquí es la implementación:

private bool IsPrinterOk(string name,int checkTimeInMillisec) 
    { 
     System.Collections.IList value = null; 
     do 
     { 
      //checkTimeInMillisec should be between 2000 and 5000 
      System.Threading.Thread.Sleep(checkTimeInMillisec); 
      // or use Timer with Threading.Monitor instead of thread sleep 

      using (System.Management.ManagementObjectSearcher searcher = new System.Management.ManagementObjectSearcher("SELECT * FROM Win32_PrintJob WHERE Name like '%" + name + "%'")) 
      { 
       value = null; 

       if (searcher.Get().Count == 0) // Number of pending document. 
        return true; // return because we haven't got any pending document. 
       else 
       { 
        foreach (System.Management.ManagementObject printer in searcher.Get()) 
        { 
         value = printer.Properties.Cast<System.Management.PropertyData>().Where(p => p.Name.Equals("Status")).Select(p => p.Value).ToList(); 
         break; 
        } 
       } 
      } 
     } 
     while (value.Contains("Printing") || value.Contains("UNKNOWN") || value.Contains("OK")); 

     return value.Contains("Error") ? false : true;  
    } 

Buena suerte.

Cuestiones relacionadas