Externes Programm GUI auslesen

  • VB.NET

Es gibt 40 Antworten in diesem Thema. Der letzte Beitrag () ist von Gonger96.

    Nein, der Wertemember ist für andere Zwecke gedacht. Bei einer ListBox kannst Du da eine Eigenschaft von Current einstellen, die dann zur Auswahl hergenommen wird, wenn Du noch zusätzlich was bei [Ausgewählter Wert] einstellst. Dann kannst Du quasi 2 Datenquellen miteinander koppeln. Das willst Du hier erstmal nicht. Von daher lass ValueMember leer bzw. auf (keine) eingestellt.
    Aber sag doch mal, was Du Dir davon versprochen hast, HandleID bei ValueMember einzustellen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    VaporiZed schrieb:

    Aber sag doch mal, was Du Dir davon versprochen hast, HandleID bei ValueMember einzustellen.

    Ich wünsche allen ein Frohes neues Jahr!

    Wenn ich die Programme in der Listbox habe ( Die ich ja wie gewünscht, dank Dir jetzt habe ), sollen die durch klicken ausgewählt werden ( z.B ListBox1.SelectedItem.Value), dazu benötige ich doch eine Zuordnung ... die Handle ID wäre eine solche, oder nicht? oder wäre es die AutomationsID ?, ProzessID? Da weis ich noch nicht weiter ....

    Was es auch immer ist, ich muss durch klicken in der ListBox sagen, du bist ausgewählt und gibt jetzt alle Inhalte preis, die ich nun wissen möchte.
    Aktuell habe ich nun erreicht, durch klicken in der ListBox, die Programm-ProzessID zu erhalten.
    Nun würde ich gerne, wenn das der richtige weg wäre, eine Abfrage für ProzessID, mittels Automation schreiben. Gibt es das so bei Automation?

    VaporiZed schrieb:

    Sobald Du die richtige App am Haken hast, machst Du damit weiter. Denn diese App ist dann vom Typ AutomationElement. Und damit geht's dann auch weiter.

    Könntest Du mir den abschnit etwas erleutern, wie gehts nun weiter? App ist geklickt in listbox ...



    Was ich wissen muss:
    - Wie ordne ich das Programm beim Klick zu? ProzessID?, AuomationsID?, HandleID?
    - Wenn zugeordnet (z.B. Wie in alten guten Zeiten Listbox.Value), wie lese ich alle vorhandenen Texte einer Klasse des Programms aus.

    Quellcode

    1. >>> Window <<<<
    2. Title: [Zeppix] Programm Titel
    3. - Hauptklasse der APP:-> Class: wxWindowClassNR


    Auszulesender Bereich der App:

    Quellcode

    1. Class: wxWindowClassNR
    2. Instance: 2
    3. ClassnameNN: wxWindowClassNR2
    4. Name:
    5. Advanced (Class): [CLASS:wxWindowClassNR; INSTANCE:2]
    6. ID: 241
    7. Text: ID_PANEL3
    8. Text den ich haben möchte


    Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von „intrepidklasse“ ()

    Wenn die Daten, die AutomationElementInformation beinhaltet, für Dich relevant sind, dann ist alles gut. Dann kommst Du mit folgendem Vorgehen an die Infos als Auflistung:
    Pack Dir eine weitere BindingSource (BS2) auf Dein Form und setze als Datenquelle diesmal nicht als Objekt AutomationElementInformation, sondern AutomationElement. Danach nimmst Du Deine erste BindingSource (BS1) und änderst die Datenquelle auf BS2, bei DataMember schreibst Du rein: Current. Zusätzlich änderst Du den Code zu:

    VB.NET-Quellcode

    1. BS2.DataSource = AutomationElement.RootElement.FindAll(TreeScope.Children, Condition.TrueCondition).Cast(Of AutomationElement).Select(Function(x) x.Current)

    Im Fenster Datenquellen (Menü Ansicht -> weitere Fenster -> Datenquellen) sollte nun das hier stehen:

    Da kannst Du auf AutomationElementInformation klicken und rechts daneben auf den DropDownButton, wo Du dann von DataGridView auf Details umstellen kannst:

    Jetzt kannst Du diese Zeile per DragAndDrop auf Dein Form ziehen und es tauchen sehr viele neue CEs auf, die Deine Details anzeigen werden:

    Wenn Du jetzt das Programm startest und den o.g. Code ausführst, sollten in der ListBox wie gewohnt die Programmnamen aufgelistet werden und die Details werden in den CEs angezeigt und automatisch aktualisiert.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Hi VaporiZed,
    funktioniert alles, jetzt erhalte ich sämtliche Fehlereigenschaften über die CEs, aber beinhaltete Informationen lassen sich hiermit noch nicht finden.


    hierbei gibt er nichts aus:

    VB.NET-Quellcode

    1. Dim AllFittingApps = AutomationElement.RootElement.FindAll(TreeScope.Children, Condition.TrueCondition).Cast(Of AutomationElement).Where(Function(x) x.Current.ClassName = "ID_PANEL3")
    2. ListBox2.Items.Add(AllFittingApps)


    Ich habe ja jezt das Hauptfenster selektiert, lese ich mit der oben genannten Vorgehensweise den Inhalt von ID_PANEL3 aus? Was soll ich dafür nehmen? den ClassName?

    intrepidklasse schrieb:

    Fehlereigenschaften
    :?:
    Ich verstehe nicht. Versuchst Du eine Fehlermeldung auszulesen?

    intrepidklasse schrieb:

    aber beinhaltete Informationen lassen sich hiermit noch nicht finden
    versteh ich noch weniger.
    Setz mal bitte einen Haltepunkt bei ListBox2.Items.Add(AllFittingApps), warte, bis der Debugger in der Laufzeit des Programms dort vorbeikommt und anhält. Dann gehe mit der Maus über AllFittingApps und versichere Dich, dass da was drinsteht, was Du brauchst. Und dann kannst Du gleich beantworten, was Du mit ListBox2.Items.Add(AllFittingApps) erreichen willst.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    also, ich glaube wir reden ein wenig an einander vorbei

    ListBox1 soll alle Anwendungen enthalten (passt)
    ListBox2 soll alle ausgewählten Texte von Klasse ID_PANEL3 enthalten

    Quellcode

    1. # Zeige mir alle Anwendungen #
    2. Anwendung -> Class: wxWindowClassNR (Hauptfenster)
    3. # Durch Klick ListBox1 Anwendung ausgewählt, anhand Binding #
    4. Unterklasse der Anwendung ID_PANEL3 -> alle texte/Inhalte in ListBox2 << Hier harpert es noch, da ich die Vorgehensweise noch nicht kenne :)

    Da alle Anwendungen die CLass wxWindowClassNR haben und ebenfalls die Unterklasse ID_Panel3, war das selektieren zuvor notwending.

    Jetzt ist die frage, mit was teile ich dem Klick auf ListBox1 mit das er alles (Sichtbare Texte/Inhalte) aus Anwendung xy mit unterklasse ID_PANEL3 anzeigen soll?

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „intrepidklasse“ ()

    Ich kom mit den gegebenen Infos wohl nicht klar. Ich fasse zusammen, was ich verstanden habe:
    • Du hast 16 Programminstanzen oder -fenster laufen, die alle (wahrscheinlich) mehr oder weniger den gleichen Inhalt haben, aber auf jeden Fall mal den selben Aufbau.
    • Aus einem dieser Fenster willst Du Info rausziehen.
    • Du hast jetzt das Fenster selektiert und willst ... von dem Unterbereich (?) ID_PANEL3 jetzt die Inhalte haben.
    Von welchem Typ ist ID_Panel3 (Klassentyp)?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    ja alles richtig,

    den Klassentyp kann ich nicht nennen, da ich nicht weis was damit gemeint ist, es handelt sich hier bei ID_PANEL3 inhalt erstmal nur um Caption texte

    So ist das Programm Aufgebaut:

    Quellcode

    1. >>> Window <<<<
    2. Title: [Zari] Programm Titel
    3. Class: wxWindowClassNR
    4. >>>> Control <<<<
    5. >>>> Mouse <<<<
    6. >>>> ToolsBar <<<<
    7. ID_PANEL1
    8. ID_PANEL3
    9. Text1 << will ich auslesen gefiltert auslesen
    10. ID_TOP_MPBAR
    11. ID_TOP_XPBAR

    Ausserdem habe ich noch folgende Informationen zu ID_PANEL3

    Quellcode

    1. >>>> Control <<<<Class:
    2. wxWindowClassNRInstance: 2ClassnameNN:
    3. wxWindowClassNR2Name: Advanced (Class): [CLASS:wxWindowClassNR;
    4. INSTANCE:2]
    5. ID: 241Text:
    6. ID_PANEL3
    7. Position: 5,5
    8. Size: 804,
    9. 56ControlClick Coords: 791, 32
    10. Style: 0x52000000ExStyle: 0x00010000
    11. Handle: 0x00000000000EAA68


    Ich benutze vom AutoIT das Window Information Tool, gibts eins das den Klasentyp auslesen kann?

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

    Ich gehe mal davon aus, dass es sich dabei nicht um ein kostenloses Programm handelt, welches ich mir runterladen kann, damit ich es selbst ausprobieren kann, oder?
    Mit den jetzt genannten Informationen komm ich insofern nicht klar, weil ich mir einfach nichts darunter vorstellen kann, was sie bedeuten.

    Quellcode

    1. >>>> Control <<<<
    2. >>>> Mouse <<<<
    3. >>>> ToolsBar <<<<
    Häh?
    Na egal. Probier doch erstmal den schon längst genannten Klassiker:

    VB.NET-Quellcode

    1. Dim AllCEs = DeineZielApp.FindAll(TreeScope.Descendants, Condition.TrueCondition).Cast(Of AutomationElement).Select(Function(x) x.Current)
    2. MessageBox.Show(AllCEs.Count)
    3. Stop


    Bei dem Stop hält ja der Debugger an. Dann kannst Du auch in AllCEs reinschauen. Ist da Dein ID_Panel3 dabei? Wenn Du nicht genau weißt, was ich mit dieser Anweisung meine, sag bescheid, dann schick ich n Screenshot oder sowas.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    frei ist es in der tat nicht, aber du kannst es trozdem downloaden und siehst genau das was ich brauche, auch ohne bezahlen.

    Bei dem Bild ist es erstmal der Bereich von dem ich hier rede, PANEL3
    Bilder
    • programm.jpg

      11,66 kB, 291×57, 41 mal angesehen

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

    intrepidklasse schrieb:

    frei ist es in der tat nicht

    intrepidklasse schrieb:

    auch ohne bezahlen
    Moment mal. Wie bekommt man es? Ist es kostenlos frei herunterladbar oder braucht es da n Freischaltcode oder muss man sich vorher irgendwo registrieren, um es zu bekommen. Denn wenn da Download-Hürden sind, ist ein Anbieten durch Dich illegal. Meines Erachtens ist das Anbieten von Fremdsoftware hier illegal. Ich bin daher so frei und lösch den Anhang, bevor jemand das Forum dafür haftbar macht. Das Posten von legalen Downloadlinks auf anderen Seiten wäre wahrscheinlich noch ok, aber mehr nicht.
    Welchen Teil Deines Screenshots brauchst Du als auslesbare Daten in Deinem Programm?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Na das Programm ist frei verfügbar, man muss dafür bezahlen, downloaden kann man es auf der Hersteller Seite auch ohne bezahlen ...
    ich will hier keine Software illegal anbieten sondern Dir mein mein Problem schildern, ich habe selbstverständlich dafür bezahlt und ohne bezahlen funktioniert das Programm auch nicht, aber darum ging es ja nicht sondern um den klassentyp!

    Wenn Du das Programm startest, siehst du oben rechts direkt welchen Bereich ich meine, vgl. mit meinem Bild.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „intrepidklasse“ ()

    :cursing:
    Es ist alles wie schon mehrfach geschrieben.

    VB.NET-Quellcode

    1. Dim DeineZielApp = AutomationElement.RootElement.FindFirst(TreeScope.Children, New PropertyCondition(AutomationElement.ClassNameProperty, "wxWindowClassNR"))
    2. Dim Panel3 = DeineZielApp.FindFirst(TreeScope.Descendants, New PropertyCondition(AutomationElement.NameProperty, "ID_PANEL3"))
    3. Dim BotServerStatusBar = Panel3.FindFirst(TreeScope.Children, New PropertyCondition(AutomationElement.AutomationIdProperty, "235"))
    4. Dim BotServerStatus = BotServerStatusBar.Current.Name

    Die AutomationID für die BotServerStatusBar hättest Du mit den beschriebenen Verfahren aus Post#25 und #29 selber herausfinden können. Für die restlichen Statusbars bitte ich um Eigeninitiative.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Also ich freue mich sehr das es jetzt hinhaut. Das fehlende Wissen mit welcher ID (Handle, AutomationID ... ) ich nun auslesen kann war ja das eigentliche Problem.

    VB.NET-Quellcode

    1. AutomationIdProperty, "235"


    Ich danke dir vielmals für Deine Investierte Zeit und freue mich sehr, jetzt weiter machen zu können.
    Dank VaporiZed, kann ich nun alle benötigten Inhalte auslesen. Jetzt habe ich das Problem, dass das auslesen länger als 8 Sekunden dauert und das Programm sich bis es fertig ist mit auslesen kein Zentimeter bewegt und hängt.

    Hat jemand einen Tipp, wie ich das Auslesen beschleunigen könnte?

    VB.NET-Quellcode

    1. Function readBotsToArr()
    2. Dim TargetApps = AutomationElement.RootElement.FindAll(TreeScope.Children, New PropertyCondition(AutomationElement.ClassNameProperty, "wxWindowClassNR")).Cast(Of AutomationElement)
    3. For Each TargetApp In TargetApps
    4. Dim Name = TargetApp.FindFirst(TreeScope.Descendants, New PropertyCondition(AutomationElement.AutomationIdProperty, "1255"))
    5. Name = Name.Current.Name
    6. Next
    7. End Function

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

    Bevor der Vorschlag kommt, mit Parallel.For und Multithreading (also Erstellung von einzelnen Threads) geht es auch nicht viel schneller.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Laut stackoverflow ist diese Art der UIAutomation langsam. Die Alternative IUIAutomation COM soll schnell sein. Ist aber WinAPI-C++ <X Es gibt über nuget einen Wrapper, aber da muss ich mich selber erstmal reinfitzeln und testen, wieviel schneller und besser das ist.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    intrepidklasse schrieb:

    Jetzt habe ich das Problem, dass das auslesen länger als 8 Sekunden dauert und das Programm sich bis es fertig ist mit auslesen kein Zentimeter bewegt und hängt
    Wenn die Automatisierung das Hauptprogramm blockiert, kannst du sie schon in einen gesonderten Thread auslagern.
    Das ändert zwar nichts an den 8 Sekunden, aber das Programm hängt dann nicht mehr.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    petaod schrieb:

    Wenn die Automatisierung das Hauptprogramm blockiert, kannst du sie schon in einen gesonderten Thread auslagern.


    das habe ich schon getan, das System.Windows.Automation deprecated ist ... ich dachte FindWindow wäre veraltet :D
    Dann wirds jetzt wohl IUIAutomation werden