2012-08-02 3 views
14

Ho un'applicazione in cui ho bisogno di stampare un biglietto. Ogni biglietto deve essere unico. L'applicazione è form di Windows e scritta interamente in C#. Per la nostra applicazione utilizziamo stampanti laser monocromatiche Samsung ML-2525.C'è un modo per verificare se un processo di stampa è andato a buon fine?

Il flusso è sostanzialmente il seguente, l'operatore preleva un prodotto/biglietto (che è unico) e poi si preme un pulsante che fa 2 cose:

  1. connette a un database e aggiorna il prodotto ed usati
  2. di stampare il biglietto (questo viene fatto utilizzando System.Drawing e GDI +)

per qualche motivo, ogni tanto un po ', l'immagine che deve essere stampata non viene inviato alla stampante. È un caso raro, ma succede.

Ho provato a collegarmi alla stampante utilizzando Win32_Printer (http://msdn.microsoft.com/en-us/library/Aa394363) ma non riesco a ottenere lo stato corrente della stampante (online, offline, toner basso, inceppamento carta, ecc.). Posso solo verificare se la stampante esiste e che il formato della carta è installato correttamente. Ho provato codice simile di seguito, ma non ha funzionato

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; 
    } 

Ho cercato di ottenere un'API per la stampante, ma non ho potuto ottenere una sospensione di esso. A proposito, il software della stampante indica diversi errori nella barra degli strumenti di Windows.

La mia domanda è se qualcuno mi può guidare nella giusta direzione su come connettersi a una stampante e controllare se la stampa ha avuto successo.

Inoltre, sarebbe utile se qualcuno fosse a conoscenza di qualche altra stampante specifica in cui potrei realizzare ciò, ad es. Cambiare l'hardware.

Grazie,

+0

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

+0

Ho fatto, ma alcuni codice di esempio per ottenere un vantaggio iniziale sarebbe utile. – lopezbertoni

+2

@lopezbertoni Un piccolo googling ti mostrerà come usare quei metodi collegati in app C# ... come http://www.codeproject.com/Articles/51085/Monitor-jobs-in-a-printer-queue-NET –

risposta

5

per ottenere un elenco di code di stampa sulla macchina locale, provare il metodo di PrintServer GetPrintQueues.

Dopo avere un'istanza dell'oggetto PrintQueue associata alla stampante in questione, è possibile utilizzarla per accedere allo stato della stampante (IsOffline, IsPaperOut, ecc.). Inoltre, è possibile utilizzarlo per ottenere un elenco dei lavori nella coda specificata (GetPrintJobInfoCollection) che consentirà di ottenere informazioni sullo stato specifiche del lavoro (IsInError, IsCompleted, IsBlocked, ecc.).

Spero che questo aiuti!

+1

grazie per l'input. Ho provato a utilizzare l'approccio che hai menzionato, ma non ho avuto successo. Il problema principale è che il lavoro arriva alla coda e quindi scompare da esso e la stampante non completa il lavoro di stampa. – lopezbertoni

+0

Se si inizia a guardare la coda prima di inviare il lavoro alla stampante, mi chiedo se è possibile riprendere il lavoro non appena viene visualizzato nella coda .... –

+0

Perché non è contrassegnato come risposta? Questo mi ha aiutato molto. Sono stato in grado di farlo funzionare osservando il numero di lavori inviati dal client specifico 'PrintQueue.Submitter', quindi dopo aver tentato la stampa, ho ottenuto l'elenco dei nuovi lavori aggiunti e ho semplicemente controllato per assicurarmi che fossero completati . Tramite questa API puoi anche ottenere lo stato di ogni singolo lavoro o della stampante stessa. C'è anche un ID di lavoro e informazioni sui biglietti. –

0

Dopo aver provato a stampare il documento PrintDocument (System.Drawing.Printing), provare a verificare lo stato dei lavori di stampa.

Primo passo: inizializzare il documento di stampa.

Secondo passo: ottenere il vostro nome della stampante Da System.Drawing.Printing.PrinterSettings.InstalledPrinters.Cast<string>();

e copiarlo nella tua printerDocument.PrinterSettings.PrinterName

Terzo passo: Provare a stampare e smaltire.

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

Ultimo passaggio: eseguire il controllo in un'attività (NON bloccare il thread dell'interfaccia utente).

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

Ecco l'attuazione:

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;  
    } 

Buona fortuna.