Abfragen ob ein Druckspooler ungedruckte Aufträge enthält

    • VB.NET
    • .NET 4.5

    Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von dive26.

      Abfragen ob ein Druckspooler ungedruckte Aufträge enthält

      Ich habe lange nach einer Lösung dafür gesucht und heute auch gefunden. Ich möchte Euch mein Codeschnippsel zur Verfügung stellen, da in keinem Forum eine praktikable Lösung mit überschaubarem Code zu finden war.


      Zuerst muss man den Dienstverweis zur System.Printing hinzufügen (siehe Screenshot)

      Zur Info: Ich übergebe der Routine keine Parameter. Die einzelnen Druckernamen befinden sich in einer Auflistung DruckerHardware(0-256).Druckername

      VB.NET-Quellcode

      1. Imports System.Printing
      2. ''' <summary>
      3. ''' Überprüft ob ungedruckte Druckaufträge in den Drucker-Spoolern existieren
      4. ''' Die Druckernamen befinden sich in einem globalen Array
      5. ''' </summary>
      6. ''' <remarks></remarks>
      7. Public Sub DruckSpoolerPruefung()
      8. Dim ps As New LocalPrintServer()
      9. Dim myPrintQueues As New PrintQueueCollection
      10. Dim Alarm As Boolean = False
      11. For i As Integer = 0 To 256
      12. Alarm = False
      13. If DruckerHardware(i).Druckername <> "" Then 'Die Druckernamen befinden sich in einem globalen Array
      14. Dim PrQu As PrintQueue = ps.GetPrintQueue(DruckerHardware(i).Druckername)
      15. Dim jobs As PrintJobInfoCollection = PrQu.GetPrintJobInfoCollection()
      16. For Each job As PrintSystemJobInfo In jobs
      17. 'Sobald hier durchlaufen wird, existiert ein Job im Druckspooler
      18. Alarm = True
      19. Next job
      20. If Alarm = True Then MessageBox.Show("Es befinden sich ungedruckte Aufträge im Spooler von " + _
      21. DruckerHardware(i).Druckername + "." , "Spooler-Alarm", MessageBoxButtons.OK, MessageBoxIcon.Information)
      22. jobs = Nothing
      23. PrQu = Nothing
      24. End If
      25. Next i
      26. myPrintQueues = Nothing
      27. ps = Nothing
      28. End Sub
      Bilder
      • Dienstverweis.jpg

        302,22 kB, 1.135×251, 75 mal angesehen
      Liebe Grüße
      Roland Berghöfer

      Bei der Entwicklung meiner Anwendung(en) steht nicht "Code nach .NET Lehrbuch" im Vordergrund, sondern eine stabile und brauchbare Anwendung die der Anwender ordentlich verwenden kann. Usability für den Kunden und Supportbarkeit beim Kunden stehen an oberster Stelle. Das spiegelt sich auch in meinen Fragen und Antworten wider. Bitte verzeiht, dass meine VB.NET Quellcodes etwas VB6-lastig sind aber das ist für das funktionierende Endergebnis nicht wirklich relevant.
      Das kann man aber an der Qualität noch wesentlich verbessern:
      1. Alles sollte Englisch sein (Methodennamen, Variablennamen, ...)
      2. Ob ein String leer ist überprüft man mit String.IsNullOrEmpty()
      3. Strings verknüpft man nicht mit + sondern mit &, aber in dem Fall wäre String.Format() sinnvoll
      4. Ob etwas in einem Array ist kann man mit .Length > 0 oder bei einer Liste mit .Count > 0 überprüfen
      5. Wenn etwas nicht IDisponsable implementiert musst du nichts mit dem Objekt tun, wenn du es nicht mehr brauchst. Wenn etwas IDisponsable solltest du es Disponsen.
      6. Übergib doch bitte die Drucker als Parameter, das ist so ziemlich unschön.
      7. Wo brauchst du myPrintQueues?
      8. Ich konnte den Code nicht testen, weil ich keine Ahnung habe, was DruckerHardware ist oder sein soll und wo man es herbekommt. Vielleicht könntest du mal einen vollständig funktionierenden Code bereitstellen, den man nur C & P muss, damit er funktioniert.

      Hier mal ein bisschen optimierte Code:

      VB.NET-Quellcode

      1. ''' <summary>
      2. ''' Überprüft ob ungedruckte Druckaufträge in den Drucker-Spoolern existieren
      3. ''' Die Druckernamen befinden sich in einem globalen Array
      4. ''' </summary>
      5. ''' <remarks></remarks>
      6. Public Sub CheckPrintQueue()
      7. Using ps As New LocalPrintServer()
      8. For i As Integer = 0 To 256
      9. If Not String.IsNullOrEmpty(DruckerHardware(i).Druckername) Then
      10. Using jobs As PrintJobInfoCollection = ps.GetPrintQueue(DruckerHardware(i).Druckername).GetPrintJobInfoCollection()
      11. If jobs.Count() > 0 Then MessageBox.Show(String.Format("Es befinden sich ungedruckte Aufträge im Spooler von {0}.", DruckerHardware(i).Druckername), "Spooler-Alarm", MessageBoxButtons.OK, MessageBoxIcon.Information)
      12. End Using
      13. End If
      14. Next
      15. End Using
      16. End Sub
      Mfg
      Vincent

      Punkt 1-6 stimme ich natürlich zu.
      Punkt 7: hast recht, brauch ich nicht.
      Punkt 8:
      Zur Info: Ich übergebe der Routine keine Parameter. Die einzelnen Druckernamen befinden sich in einer Auflistung DruckerHardware(0-256).Druckername


      Für meine Bedürfnisse befinden sich in "Druckerhardware(0,256).Druckername natürlich noch andere Infos. Für das Beispiel könnte man auch Dim DruckerNamen(256) dimensionieren und übergeben.
      Liebe Grüße
      Roland Berghöfer

      Bei der Entwicklung meiner Anwendung(en) steht nicht "Code nach .NET Lehrbuch" im Vordergrund, sondern eine stabile und brauchbare Anwendung die der Anwender ordentlich verwenden kann. Usability für den Kunden und Supportbarkeit beim Kunden stehen an oberster Stelle. Das spiegelt sich auch in meinen Fragen und Antworten wider. Bitte verzeiht, dass meine VB.NET Quellcodes etwas VB6-lastig sind aber das ist für das funktionierende Endergebnis nicht wirklich relevant.
      Wieso deklarierst du die Methode denn nicht als Function und gibst dann die Informationen in der Rückgabe raus, anstatt diese direkt innerhalb der Sub zu verwerten.
      Würde natürlich Sinn machen, wenn ich diese Funktion öfter benötigen würde.
      Jedoch wird diese Funktion gerade einmal beim Start der Software aufgerufen und kann daher gleich "alles" übernehmen. Dann brauche ich an der Aufrufenden Stelle nur eine Zeile mit dem Funktionsaufruf zu schreiben - was die Hauptfunktionen übersichtlicher macht.

      Mein Datenkonstrukt DruckerHardware() ist global für alle Funktionen erreichbar, da diese nur ausgelesen werden muss. Ist einfacher zu handhaben. Dort befinden sich in einer Liste alle Drucker im System und auch diverse andere Informationen die für den Belegdruck relevant sind.

      VB.NET-Quellcode

      1. <Serializable()> _
      2. Public Structure DruckerHardwareStructure
      3. Dim Druckername As String
      4. Dim DruckertreiberName As String
      5. Dim Anschluss As String
      6. Dim aktiv As Boolean
      7. Dim XOffsetRechnungen As Double
      8. Dim XOffsetBerichte As Double
      9. Dim Kopien As Integer
      10. Dim Icon As Image
      11. Dim Ersatzdrucker As String
      12. Dim KlemmleisteOben As Double
      13. Dim KlemmleisteUnten As Double
      14. Dim EinzelbonsProArtikelnummer As Boolean
      15. Dim Speisenfolgen As Boolean
      16. Dim SchriftartKlein As Font
      17. Dim SchriftartGross As Font
      18. Dim TischErstbuchungsdatum As Boolean
      19. Dim Tischnummer As Boolean
      20. Dim TischnummerGross As Boolean
      21. Dim Bondatum As Boolean
      22. Dim Bedienername As Boolean
      23. Dim Kassenkennung As Boolean
      24. Dim Gastname As Boolean
      25. Dim GastnameGross As Boolean
      26. Dim Bonnummer As Boolean
      27. Dim Artikelgross As Boolean
      28. Dim Artikelpreise As Boolean
      29. Dim Gesamtsumme As Boolean
      30. Dim Barcode As Boolean
      31. Dim Artikelzusatztexte As Boolean
      32. Dim Vorhanden As Integer
      33. Dim Signalgeber As Boolean
      34. Dim Ausgabenummer As Boolean
      35. End Structure
      36. Public DruckerHardware(256) As DruckerHardwareStructure
      Liebe Grüße
      Roland Berghöfer

      Bei der Entwicklung meiner Anwendung(en) steht nicht "Code nach .NET Lehrbuch" im Vordergrund, sondern eine stabile und brauchbare Anwendung die der Anwender ordentlich verwenden kann. Usability für den Kunden und Supportbarkeit beim Kunden stehen an oberster Stelle. Das spiegelt sich auch in meinen Fragen und Antworten wider. Bitte verzeiht, dass meine VB.NET Quellcodes etwas VB6-lastig sind aber das ist für das funktionierende Endergebnis nicht wirklich relevant.