Drucker online / Drucker offline / Papierstatus / eingeschaltet oder ausgeschaltet (oder nicht angesteckt)

    • VB.NET

    Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von petaod.

      Drucker online / Drucker offline / Papierstatus / eingeschaltet oder ausgeschaltet (oder nicht angesteckt)

      Hallo Leute,

      ich bekomme so viel Hilfe von Euch, da ist es nur fair wenn ich auch einmal etwas produktives beisteuere.

      Ich stand vor der Aufgabe eine Druckausgabe auf einen Reservedrucker umzuleiten, sobald der Hauptdrucker offline ist, das Papier aus ist oder nicht angesteckt oder ausgeschaltet. Ich habe sehr viele Lösungsansätze im Netz gefunden um den Druckerstatus herauszufinden, nur einer funktionierte wirklich zuverlässig und diesen habe ich für meine Bedürfnisse adaptiert:

      VB.NET-Quellcode

      1. ''' <summary>
      2. ''' Übergibt False, wenn der Drucker aus welchem Grund auch immer nicht druckbereit ist
      3. ''' In dieser Funktion wird "ErrorLog" verwendet - diese Funktion schreibt ein Error-Logfile im Falle von offline, paper out oder disconnect
      4. ''' </summary>
      5. ''' <param name="Drucker"></param>
      6. ''' <returns></returns>
      7. ''' <remarks></remarks>
      8. Public Function isPrinterOnline(Drucker As String) As Boolean
      9. Dim Online As Boolean = False
      10. Dim scope As ManagementScope = New ManagementScope("\root\cimv2")
      11. scope.Connect()
      12. Dim searcher As ManagementObjectSearcher = New ManagementObjectSearcher("SELECT * FROM Win32_Printer")
      13. Dim collection As ManagementObjectCollection = searcher.Get
      14. For Each printer As ManagementObject In collection
      15. If printer("Name").ToString() = Drucker Then
      16. If printer("WorkOffline").ToString().ToLower().Equals("true") Then
      17. ErrorLog(Drucker + " offline (user)") 'Error-Logfile Eintrag
      18. Online = False
      19. Else
      20. Online = True
      21. End If
      22. If printer("PrinterStatus") <> 3 Then Online = False
      23. If printer("ExtendedDetectedErrorState") <> 0 Then Online = False
      24. If printer("PrinterState") <> 0 Then Online = False
      25. If printer("PrinterState") = 144 Then ErrorLog(Drucker + " no Paper") 'Error-Logfile Eintrag
      26. If printer("PrinterState") = 4096 Then ErrorLog(Drucker + " not on") 'Error-Logfile Eintrag
      27. End If
      28. Next
      29. Return Online
      30. End Function


      Liebe Grüße
      Roland
      Liebe Grüße
      Roland Berghöfer

      Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at
      @dive26:: Feine Lösung. :thumbup:
      Zur direkten Umsetzung noch ein paar wichtige Hinweise:
      1. muss ein Verweis auf die System.Management.dll hinzugefügt werden.
      2. muss der System.Management-Namespace importiert werden,
      3. müssen für Option Strict On ein paar Object-Variablen korrekt gecastet werden:

      Insgesamt sieht das nun so aus:
      PrinterStatus

      VB.NET-Quellcode

      1. Option Strict On
      2. Imports System.Management
      3. Public Class Form1
      4. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
      5. isPrinterOnline("FreePDF")
      6. End Sub
      7. ''' <summary>
      8. ''' Übergibt False, wenn der Drucker aus welchem Grund auch immer nicht druckbereit ist
      9. ''' In dieser Funktion wird "ErrorLog" verwendet - diese Funktion schreibt ein Error-Logfile im Falle von offline, paper out oder disconnect
      10. ''' </summary>
      11. ''' <param name="Drucker"></param>
      12. ''' <returns></returns>
      13. ''' <remarks></remarks>
      14. Public Function isPrinterOnline(Drucker As String) As Boolean
      15. Dim scope As ManagementScope = New ManagementScope("\root\cimv2")
      16. scope.Connect()
      17. Dim searcher As ManagementObjectSearcher = New ManagementObjectSearcher("SELECT * FROM Win32_Printer")
      18. Dim collection As ManagementObjectCollection = searcher.Get
      19. For Each printer As ManagementObject In collection
      20. Dim Online As Boolean = False
      21. If printer("Name").ToString() = Drucker Then
      22. If printer("WorkOffline").ToString().ToLower().Equals("true") Then
      23. ErrorLog(Drucker + " offline (user)") ' Error-Logfile Eintrag
      24. Online = False
      25. Else
      26. Online = True
      27. End If
      28. Dim x1 As UShort = CUShort(printer("PrinterStatus"))
      29. Dim x2 As UShort = CUShort(printer("ExtendedDetectedErrorState"))
      30. Dim x3 As UInteger = CUInt(printer("PrinterState"))
      31. If x1 <> 3 Then Online = False
      32. If x2 <> 0 Then Online = False
      33. If x3 <> 0 Then Online = False
      34. If x3 = 144 Then ErrorLog(Drucker + " no Paper") ' Error-Logfile Eintrag
      35. If x3 = 4096 Then ErrorLog(Drucker + " not on") ' Error-Logfile Eintrag
      36. Return Online
      37. End If
      38. Next
      39. Return False
      40. End Function
      41. Private Sub ErrorLog(message As String)
      42. ' Logging
      43. End Sub
      44. End Class
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!
      Danke für die Ergänzung des Codes.
      Den Verweis zur System.Management.dll habe ich natürlich gesetzt und auch den entsprechenden Namespace importiert. Aber Du hast recht, die hätte ich hier der Vollständigkeit halber auch posten sollen. Ist mir selbst auch schon öfter passiert, dass diverse Codeteile nicht funktionierten, weil eben diese wichtigen Informationen fehlten. Danke nochmals.

      Ich habe Option Strict On nun gesetzt und den Code so wie Du vorgeschlagen hast abgeändert.

      Meine Frage zu Option Stict On:
      Wäre es ein großer Fehler den Code auf "If printer("PrinterStatus") <> 3 Then" zu belassen ohne Option Strict on?
      In MSDN steht folgendes dazu:
      Liebe Grüße
      Roland Berghöfer

      Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at

      dive26 schrieb:

      ohne Option Strict on
      ist der Code einfach unsauber.
      Wenn Du in einer einzelnen Datei Strict ausschaltest und dann den Code erweiterst, verzichtest Du dort auf die explizite Typprüfung und kommst ganz fix in die Berdängnis, hier wegen nix einen Thread aufzumachen. ;)
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!
      Ich habe versucht, das bei mir zu machen.(VB2010, Win7-64, Win8.1)
      Mein Ergebnis:
      PrinterStatus = 1
      ExtendedDetectedErrorState = 5
      Printerstate = 131072
      Manchmal kriege ich auch 3,0,0 wie erwartet, allerdings ca. 10 min. nachdem ich etwas gedruckt habe (mit Notepad).
      Ausserdem ändert sich die Anzeige nicht, wenn ich den Drucker offline schalte oder ihn völlig abschalte.
      Mein Drucker ist über's Netzwerk angeschlossen - kann das daran liegen?
      Update: Microsoft sagt:
      Only a specific device driver can obtain
      real-time, accurate printer status information. This code obtains the
      same status that the Windows Spooler reports.
      The exact status that is reported may vary with different printers and drivers.

      Also kein Glück übers Netzwerk. Die Informationen kriegt man nur vom "Spooler" und die Status-Codes sind auch unterschiedlich.
      Alles was man direkt herausfinden kann, ist welcher Drucker Standard ist und ob der Drucker auf "Drucker offline verwenden" geschaltet ist.
      Letzteres ist allerdings zeitverzögert, z.B. wenn der Drucker abgeschaltet wird - abhängig wohl vom allgemeinen Netzwerk.


      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „jocutus“ ()

      Hallo Jocutus,

      der Thread ist schon etwas älter und ich bin heute zufällig wieder darauf gestoßen.
      Du hast es schon richtig herausgefunden. Das geht nicht mit jedem Druckertreiber. Netzwerkdrucker haben mitunter eine Zeitverzögerung in der online/offline Meldung.
      Wir verwenden USB Thermobondrucker und Ethernet Thermobondrucker welche den Status einwandfrei übermitteln. Es gibt aber auch Geräte wo das überhaupt nicht funktioniert. Ist generell treiberabhängig.
      Liebe Grüße
      Roland Berghöfer

      Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at
      Hallo Leute,

      entschuldigt, dass ich den alten Beitrag wieder ausgrabe. Aber auf diesen aufbauend wollte ich jetzt noch weitere Funktionen einbauen.

      Oft wird ein Drucker von Windows in den Modus "offline verwenden" geschaltet. Das passiert meist, wenn der Drucker beim Drucken nicht eingeschaltet ist. Auch ein späteres Einschalten des Druckers schaltet nicht wieder auf "online". Dies müsste man in der Systemsteuerung manuell machen.

      Nun meine Frage dazu: Kann man den Drucker auch über VB.NET softwaremäßig wieder auf "online" schalten?
      Ich habe dazu leider nichts im Netz gefunden.

      LG Roland
      Liebe Grüße
      Roland Berghöfer

      Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at
      Vielen Dank. Aber ich werde aus dem C++ Code nicht ganz schlau. Werde es in stiller Stunde mal versuchen. Aber zumindest gibts schon mal Setprinter.
      Liebe Grüße
      Roland Berghöfer

      Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at