Der Martin: Windows-Tool gesucht

Hallo alle zusammen,

ich frage mich, ob es irgendein Tool für Windows gibt, das einen bestimmten Bildschirmausschnitt (oder mehrere) "beobachtet" und Alarm schlägt (oder sonst irgendeine Aktion ausführt), sobald sich in diesem Bereich etwas ändert. Im Idealfall natürlich Open-Source und kostenlos.

Der Sinn dahinter: Bei uns im Betrieb gibt es mehrere ähnliche Diagnoseprogramme für ältere Baugruppen, die aber jetzt wieder aktiell werden, weil die betreffenden Baugruppen in aktuellen Projekten wieder eingesetzt werden. Diese Diagnoseprogramme können aber immer nur den aktuellen Status der Baugruppen in quasi-Echtzeit anzeigen. Es gibt leider keine Protokollierung oder einen Soll-Ist-Vergleich.
Jetzt werden diese Programme wieder bei Typprüfungen verwendet, um festzustellen, dass die Baugruppen einwandfrei funktionieren. Problem: Manche Tests ziehen sich über mehrere Stunden. Dabei ständig auf den Bildschirm starren und aufpassen, ob irgendwo was zuckt? Bitte nicht!

Genau dieses Starren und Aufpassen hätte ich nun gern automatisiert.

Leider sind mir auch noch nicht die richtigen Suchbegriffe eingefallen, um erfolgreich selbst nach so einer Software zu forschen. Google hat mir nur jede Menge Luxus-Screenshot-Tools angeboten und solche, mit denen ich Videos vom Windows-Desktop aufnehmen kann. Das nützt mir aber nix.

Irgendwelche Hinweise?

Bis später beim Stammtisch
 Martin

--
Zucker ist das Zeug, das den Kaffee bitter macht, wenn man es weglässt.
  1. Hallo Martin,

    https://stackoverflow.com/questions/362986/capture-the-screen-into-a-bitmap

    Ich wüsste, wie man sowas selbst schreibt… Man muss die zu beobachtende Region festlegen und dann die Snaps vergleichen.

    Ist natürlich mühsam. Aber ein fertiges Tool finde ich im Getöse des Suchmülls nicht, die mir Reports verkaufen wollen, Monitore, Überwachungskameras - da scheint noch keiner ein Freeware-Tool für gebaut zu haben oder es steckt auf Google Seite siebenunddrölfzig.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Ich wüsste, wie man sowas selbst schreibt… Man muss die zu beobachtende Region festlegen und dann die Snaps vergleichen.

      … ein fertiges Tool …

      Kann man sich zu leicht selbst „hinscripten“.

      1. Bild kommt. Bild speichern, md5-Summe der Datei als Vergleichsgrundlage erstellen
      2. Bild kommt. Bild speichern, md5-Summe erstellen, mit erster Vergleichsgrundlage vergleichen:
      • wenn gleich: Bild wieder löschen.
      • wenn nicht: md5-Summe des neuen Bildes wird neue Vergleichsgrundlage; meckern, loggen und verpetzen.

      Freilich kann man auch Python hernehmen, die Datei(en) zu RAW expandieren und Pixel für Pixel vergleichen…

      1. Hallo Raketenwilli,

        Man muss den Bildschirmbereich passend festlegen können. Geht natürlich auch per Daumen.

        Der Irfanview kann meines Wissens von der Befehlszeile aus alle Funktionen ausführen, also vielleicht auch einen partiellen Screenshot. Ich hatte das vorhin nicht verfolgt, weil ich dachte, dass Grafikdateien wegen Timestamps in Metadaten nicht deterministisch erzeugbar sind. Aber da gibt's vielleicht ein passendes Format.

        Wenn ich das Tool selbst schreiben würde, dann würde ich einen Controller bauen der N Bildausschnitte monitort und bei Änderungen Radau macht. Vielleicht mit einstellbarem Radau je Ausschnitt, damit man gleich hört wo was abgeht.

        Rolf

        --
        sumpsi - posui - obstruxi
        1. Hallo Rolf,

          Man muss den Bildschirmbereich passend festlegen können.

          genua.

          Der Irfanview kann meines Wissens von der Befehlszeile aus alle Funktionen ausführen, also vielleicht auch einen partiellen Screenshot. Ich hatte das vorhin nicht verfolgt, weil ich dachte, dass Grafikdateien wegen Timestamps in Metadaten nicht deterministisch erzeugbar sind. Aber da gibt's vielleicht ein passendes Format.

          Aber wenn ich sowieso irgendeinen Rahmen drumherum schreiben muss, würde ich auch den Screenshot selber bestellen. Ich habe da inzwischen auch was Brauchbares gefunden (im Titel ist von C++ die Rede, das Code-Beispiel ist aber Plain Vanilla C)

          Wenn ich das Tool selbst schreiben würde, dann würde ich einen Controller bauen der N Bildausschnitte monitort und bei Änderungen Radau macht. Vielleicht mit einstellbarem Radau je Ausschnitt, damit man gleich hört wo was abgeht.

          Fun Fact: Es gab im Ruhrgebiet bis vor einigen Jahren ein Fachgeschäft für Amateurfunkzubehör, dessen Inhaber großen Wert darauf legte, dass der Name Radaufunk auf der ersten Silbe betont würde. 😀

          Einen schönen Tag noch
           Martin

          --
          Zucker ist das Zeug, das den Kaffee bitter macht, wenn man es weglässt.
      2. Moin,

        Kann man sich zu leicht selbst „hinscripten“.

        1. Bild kommt. Bild speichern, md5-Summe der Datei als Vergleichsgrundlage erstellen
        2. Bild kommt. Bild speichern, md5-Summe erstellen, mit erster Vergleichsgrundlage vergleichen:

        Zur Berechnung einer Prüfsumme musst du die ganzen Bilddaten einmal verarbeiten. Dann kannst du auch gleich die Bilddaten gegeneinander vergleichen.

        Wenn man (grob) die Bildschirmbereiche weiß, in denen die Änderungen passieren, kann man die Vergleiche auch darauf beschränken – mit etwas „Nachdenken“ lässt sich der Vergleich auf Ungleichheit sogar noch „zufällig“ etwas optimieren.

        Apropos Bildschirmbereiche: Es bietet sich an

        • nur das relevante Fenster aufzunehmen
        • den Bereich der Taskbar (wegen der Uhr) nicht aufzunehmen.

        Freilich kann man auch Python hernehmen, die Datei(en) zu RAW expandieren und Pixel für Pixel vergleichen…

        Wenn die Screenshots schon mit C aufgezeichnet werden, kann man auch direkt in C roh vergleichen und braucht kein unpack.

        Viele Grüße
        Robert

    2. n*Abend Rolf,

      https://stackoverflow.com/questions/362986/capture-the-screen-into-a-bitmap

      das ist ein interessanter Startpunkt.

      Ich wüsste, wie man sowas selbst schreibt… Man muss die zu beobachtende Region festlegen und dann die Snaps vergleichen.

      Genau. Und mittlerweile habe ich auch ein paar Code-Snippets gefunden, die sowas ohne C# und ohne .NET hinkriegen wollen. Das käme meiner Philosophie entgegen: Im Idealfall in reinem Standard-C und ausschließlich per Windows-API ohne zusätzliche Frameworks oder Bibliotheken.

      Ist natürlich mühsam.

      Ja. Aber bis zum nächsten potentiellen Einsatzfall habe ich ein Zeitfenster von 1..2 Monaten. Vielleicht gehe ich also wirklich in diese Richtung. Mal sehen, was der Projektleiter und mein Teamchef dazu sagen.

      Aber ein fertiges Tool finde ich im Getöse des Suchmülls nicht

      So ging es mir auch. Schade. Aber danke immerhin für die Bestätigung.

      da scheint noch keiner ein Freeware-Tool für gebaut zu haben

      Vielleicht ist das ja eine Marktlücke. On verra ...

      Einen schönen Tag noch
       Martin

      --
      Zucker ist das Zeug, das den Kaffee bitter macht, wenn man es weglässt.
      1. Moin Martin,

        Genau. Und mittlerweile habe ich auch ein paar Code-Snippets gefunden, die sowas ohne C# und ohne .NET hinkriegen wollen. Das käme meiner Philosophie entgegen: Im Idealfall in reinem Standard-C und ausschließlich per Windows-API ohne zusätzliche Frameworks oder Bibliotheken.

        soweit ich mich erinnere ist das auch nicht so schwierig:

        Screenshot erzeugen

        1. Jeweils die Rückgabewerte der Funktionen prüfen.
        2. Device Context des Screens holen
          HDC dcScreen = GetDC(nullptr);
          // Freigabe mit ReleaseDC
          
        3. kompatiblen Device Context erzeugen
          HDC dcc = CreateCompatibleDC(dcScreen);
          // Freigabe mit DeleteDC
          
        4. Bitmap (HBITMAP-Typ) erzeugen
          HBITMAP bmp = CreateCompatibleBitmap(dcScreen, width, height);
          // Freigabe mit DeleteObject
          
        5. Bitmap in den kompatiblen Device Context selektieren
          SelectObject(dcc, bmp);
          
        6. „Bit-Level Transfer“ des Bildschirminhalts in die Bitmap
          BitBlt(dcc, x0, y0, width, height, dcScreen, wndLeft, wndTop, SRCCOPY);
          

        Bitmap-Daten extrahieren

        1. BITMAPINFO der Bitmap initialisieren (Achtung: Der Speicher einer BITMAPINFO muss sizeof(BITMAPINFO) + 2 * sizeof(RGBQUAD) sein).
          const std::size_t BIS(sizeof(BITMAPINFO) + 2 * sizeof(RGBQUAD));
          char infoMem[BIS] = { 0 };
          BITMAPINFO *info = reinterpret_cast<BITMAPINFO*>(&infoMem);
          info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
          
          GetDIBits(dcScreen, bmp, 0, 0, NULL, info, DIB_RGB_COLORS);
          
        2. Die Bildhöhe in info muss für den nächsten Schritt negativ sein:
          const long height = info->bmiHeader.biHeight;
          info->bmiHeader.biHeight *= -1;
          
        3. Rohe Bitmap-Daten extrahieren
          char *data = new char[info->bmiHeader.biSizeImage];
          GetDIBits(dcScreen, bmp, 0, height, info, DIB_RGB_COLORS);
             // sollte einen Wert gleich height zurückgeben
          

        Das müsste grob auch das sein, was du im Internet/der Microsoft-Dokumentation findest.

        Viele Grüße
        Robert

  2. Diese Diagnoseprogramme können aber immer nur den aktuellen Status der Baugruppen in quasi-Echtzeit anzeigen.

    Ganz andere Baustelle: Wie kommunizieren denn diese Diagnoseprogramme mit den Baugruppen?

    Womöglich macht es deutlich mehr Sinn da anzusetzen...

    1. Hallo Raketenwilli,

      eigentlich ja, aber es gibt bei Martin interne Gründe, weshalb das problematisch ist.

      Rolf

      --
      sumpsi - posui - obstruxi
      1. Moin,

        Ganz andere Baustelle: Wie kommunizieren denn diese Diagnoseprogramme mit den Baugruppen?

        Womöglich macht es deutlich mehr Sinn da anzusetzen...

        eigentlich ja, aber es gibt bei Martin interne Gründe, weshalb das problematisch ist.

        genau, diese Diagnosetools wurden vor vielen Jahren von einer Fremdfirma entwickelt, die in der Zwischenzeit nicht mehr existiert. Und über die reine Anwenderdoku hinaus haben die uns nicht viel Information hinterlassen. 🤬

        Trotzdem ist der Ansatz natürlich gut und eigentlich richtig. Wenn irgendwo noch Informationen über das Kommunikationsprotokoll aufzutreiben sind, werde ich tatsächlich versuchen, das selbst nochmal zu implementieren. Die physische Schnittstelle zum PC ist USB, und das Anschaltgerät simuliert einfach einen COM-Port.
        Eine universelle Datenlogger-Software mit integriertem Soll-Ist-Vergleich habe ich ja schon, fehlt also "nur" ein Compatibility Layer dazwischen.

        Einen schönen Tag noch
         Martin

        --
        Zucker ist das Zeug, das den Kaffee bitter macht, wenn man es weglässt.
        1. Wenn irgendwo noch Informationen über das Kommunikationsprotokoll aufzutreiben sind, werde ich tatsächlich versuchen, das selbst nochmal zu implementieren. Die physische Schnittstelle zum PC ist USB, und das Anschaltgerät simuliert einfach einen COM-Port.

          In der Regel sendet das Zeug einfach zeilenweise CSV-Daten, die vielleicht ein wenig umgerechnet werden müssen. Da willst Du nicht mit Bildschirmfotos agieren. Ich glaube auch weniger, dass die alten Geräte die Daten verschlüsselt haben.

        2. Ich habe hier eine „GPS-Maus“, die via USB und einen darüber simulierten seriellen Anschluss kommuniziert. Anschluss und Kontrolle im syslog:

          • usb 1-1.3: new full-speed USB device number 10 using xhci_hcd
          • usb 1-1.3: New USB device found, idVendor=1546, idProduct=01a6, bcdDevice= 7.03
          • usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
          • usb 1-1.3: Product: u-blox 6 - GPS Receiver
          • usb 1-1.3: Manufacturer: u-blox AG - www.u-blox.com
          • cdc_acm 1-1.3:1.0: ttyACM0: USB ACM device

          Soso: /dev/ttyACM0 ist also das Gerät.

          <?php
          
          $devise = '/dev/ttyACM0';
          
          $FH = fopen( $device 'r' );
          if ( $FH ) {
              while ( ( $line = fgets( $FH ) ) !== false) {
                  echo $line;
              }
          
              fclose( $FH );
          } else {
          	trigger_error( 'Fehler beim Verbindungsaufbau zum Gerät ' . $devise, E_USER_ERROR );
          }
          

          da kommt:

          $GPRMC,115418.000,V,0000.0000,N,00000.0000,E,0.00,0.00,280722,,,N*73
          
          $GPVTG,0.00,T,,M,0.00,N,0.0,K,N*02
          
          $GPGGA,115418.000,0000.0000,N,00000.0000,E,0,00,99.9,-17.0,M,17.0,M,,0000*71
          
          $GPGSA,A,1,,,,,,,,,,,,,99.9,99.9,99.9*09
          
          $GPGSV,1,1,04,12,,,21,20,,,19,22,,,10,31,,,21*77
          
          $GPGLL,0000.0000,N,00000.0000,E,115418.000,V,N*49
          

          Ich die kann also Daten lesen: Es ist in meinem Fall CSV. Willst Du das Vorgehen nicht erstmal nach Windows portieren und wenigstens mal antesten?

          1. Moin,

            Ich habe hier eine „GPS-Maus“, die via USB und einen darüber simulierten seriellen Anschluss kommuniziert. Anschluss und Kontrolle im syslog:

            • usb 1-1.3: new full-speed USB device number 10 using xhci_hcd
            • usb 1-1.3: New USB device found, idVendor=1546, idProduct=01a6, bcdDevice= 7.03
            • usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
            • usb 1-1.3: Product: u-blox 6 - GPS Receiver
            • usb 1-1.3: Manufacturer: u-blox AG - www.u-blox.com
            • cdc_acm 1-1.3:1.0: ttyACM0: USB ACM device

            Soso: /dev/ttyACM0 ist also das Gerät.

            wenn du von der virtuellen Gerätedatei direkt passend lesen kannst, ist das wunderbar. Bei einer „richtigen“ seriellen Schnittstelle musst du doch die Verbindungsparameter (Start- und Stop-Bits, Datenbits, Parität, …) passend setzen.

            Viele Grüße
            Robert

            1. Moin,

              Ich habe hier eine „GPS-Maus“, die via USB und einen darüber simulierten seriellen Anschluss kommuniziert. Anschluss und Kontrolle im syslog:

              • usb 1-1.3: new full-speed USB device number 10 using xhci_hcd
              • usb 1-1.3: New USB device found, idVendor=1546, idProduct=01a6, bcdDevice= 7.03
              • usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
              • usb 1-1.3: Product: u-blox 6 - GPS Receiver
              • usb 1-1.3: Manufacturer: u-blox AG - www.u-blox.com
              • cdc_acm 1-1.3:1.0: ttyACM0: USB ACM device

              Soso: /dev/ttyACM0 ist also das Gerät.

              wenn du von der virtuellen Gerätedatei direkt passend lesen kannst, ist das wunderbar.

              Probieren ging schon immer über Studieren. Ist ja keine Zündschnur an einer Kiste.

              Bei einer „richtigen“ seriellen Schnittstelle musst du doch die Verbindungsparameter (Start- und Stop-Bits, Datenbits, Parität, …) passend setzen.

              Niemand ist daran gehindert, es mit einem der Programme aus dieser Liste zu probieren: https://www.mikrocontroller.net/topic/66694

              Für Windows: gibt es dort einen Link um sowas selbst kompilieren:

              https://sourceforge.net/projects/serial-io/

          2. Hallo,

            Soso: /dev/ttyACM0 ist also das Gerät.

            <?php
            
            $devise = '/dev/ttyACM0';
            
            $FH = fopen( $device 'r' );
            if ( $FH ) {
                while ( ( $line = fgets( $FH ) ) !== false) {
                    echo $line;
                }
            
                fclose( $FH );
            } else {
            	trigger_error( 'Fehler beim Verbindungsaufbau zum Gerät ' . $devise, E_USER_ERROR );
            }
            

            so umständlich? Ich werfe mal grinsend ein cat /dev/ttyACM0 in die Runde. 🤓

            Willst Du das Vorgehen nicht erstmal nach Windows portieren und wenigstens mal antesten?

            Das hieße rein praktisch betrachtet: Ein Terminal aufmachen und damit an der virtuellen Schnittstelle lauschen. Wäre einen Versuch wert, sobald ich das Gerät wieder zur Verfügung habe.

            Meines Wissens will das Gerät aber erstmal angesprochen werden und ein Kommando hören, bevor es irgendwas sagt.

            Einen schönen Tag noch
             Martin

            --
            Zucker ist das Zeug, das den Kaffee bitter macht, wenn man es weglässt.
            1. Ich werfe mal grinsend ein cat /dev/ttyACM0 in die Runde

              Ja? Das sendet "ewig". Und wie kommst Du an die Daten?

              #/bin/bash
              while read line < /dev/ttyACM0; do
                  echo $line;
              done
              

              Ich wollte schon etwas zeigen, was es erlaubt, mit den gelesenen Daten „was zu machen“.

              Meines Wissens will das Gerät aber erstmal angesprochen werden und ein Kommando hören, bevor es irgendwas sagt.

              Senden geht genau so: Einfach reinschreiben. Das haben wir schon im vorigen Jahrtausend mit Modems so gemacht:

              echo "ATD0800" > /dev/modem
              
              1. Hallo,

                Ich werfe mal grinsend ein cat /dev/ttyACM0 in die Runde

                Ja? Das sendet "ewig". Und wie kommst Du an die Daten?

                die sehe ich doch dann auf der Konsole.

                #/bin/bash
                while read line < /dev/ttyACM0; do
                    echo $line;
                done
                

                Ich wollte schon etwas zeigen, was es erlaubt, mit den gelesenen Daten „was zu machen“.

                Ah. Ich hatte deinen Ansatz nur als Vorschlag verstanden, erstmal einen Eindruck zu bekommen, wie die gelieferten Daten aussehen.

                Meines Wissens will das Gerät aber erstmal angesprochen werden und ein Kommando hören, bevor es irgendwas sagt.

                Senden geht genau so: Einfach reinschreiben. Das haben wir schon im vorigen Jahrtausend mit Modems so gemacht:

                echo "ATD0800" > /dev/modem
                

                Schon klar, aber dazu muss ich erstmal wissen, was ich in die Schnittstelle stopfen muss, damit mir das Gerät nicht einfach ein Häufchen Binärmüll vor die Füße kotzt. Ich gehe nämlich nicht davon aus, dass es sich um ein menschenlesbares Protokoll handelt.

                Einen schönen Tag noch
                 Martin

                --
                Zucker ist das Zeug, das den Kaffee bitter macht, wenn man es weglässt.
                1. Binärmüll

                  Das ist bei seriellen Schnittstellen aber „eher selten“. Weitaus öfter musst Du Zahlen oder Werte umrechnen.

                  Schon klar, aber dazu muss ich erstmal wissen, was ich in die Schnittstelle stopfen muss,

                  Google mal nach Gerät, Hersteller und, wenn Du hast, Chipsatz. Ggf. das, was Dir das syslog ausspuckt, wenn Du das Gerät anschließt. Es gibt bekanntlich „Nichts Neues im Westen“. Besonders weil das Zeug ja älter ist…

                  1. Hallo,

                    Binärmüll

                    Das ist bei seriellen Schnittstellen aber „eher selten“.

                    im Bereich der Bahn-Elektronik und Bahn-IT ist das recht gängig.

                    Schon klar, aber dazu muss ich erstmal wissen, was ich in die Schnittstelle stopfen muss,

                    Google mal nach Gerät, Hersteller und, wenn Du hast, Chipsatz.

                    Zwecklos. Das Ding ist ja "nur zum internen Gebrauch" oder für die Servicetechniker der Bahngesellschaften, die unsere Systeme auf ihren Fahrzeugen einsetzen. Veröffentlicht (also im Web frei zugänglich) ist darüber nichts. Eine Chance sehe ich höchstens noch bei den altgedienten Kollegen in der Entwicklung, die die Entstehung des Geräts noch miterlebt haben.

                    Beschreibung in Stichworten (PDF; Seite 3, "ACSys Interface")

                    Ggf. das, was Dir das syslog ausspuckt, wenn Du das Gerät anschließt.

                    Dazu müsste ich das Teil verbotenerweise mal mit nach Hause nehmen. In der Firma gibt's ja keine Rechner mit Betriebssystem. Und ich ahne schon, was mir das syslog dann verrät: Wahrscheinlich einen FTDI USB-zu-Seriell-Chip. Was dahinter für ein µC werkelt und welche Sprache der spricht, weiß ich davon noch lange nicht.

                    Einen schönen Tag noch
                     Martin

                    --
                    Zucker ist das Zeug, das den Kaffee bitter macht, wenn man es weglässt.
  3. Hallo Martin,

    musst du denn sofort reagieren, wenn der Test nicht planmäßig verläuft? Sonst könntest du (oder der Tester) den Bildschirm abfilmen und das Video dann im Zeitraffer ansehen.

    Gruß
    Jürgen

    1. Hallo Jürgen,

      musst du denn sofort reagieren, wenn der Test nicht planmäßig verläuft?

      nicht zwangsläufig, aber ...

      Sonst könntest du (oder der Tester) den Bildschirm abfilmen und das Video dann im Zeitraffer ansehen.

      Wäre denkbar. Ist nur schade, wenn man erst hinterher auswertet und dann feststellt, dass drei Stunden Prüfzeit für die Tonne waren. Bei Laborkosten von teils über 200EU$/h tut das schon weh.

      Einen schönen Tag noch
       Martin

      --
      Zucker ist das Zeug, das den Kaffee bitter macht, wenn man es weglässt.