Wie kann ich einen Tastendruck senden mit pywinauto in inaktivem Fenster?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
MyPy17
User
Beiträge: 18
Registriert: Mittwoch 19. April 2023, 12:40

ich möchte das python mitniterm (Terminal) benutzen und dann per pywinauto einen Tastendruck schicken. Ich benutze für den Start des Terminals folgenden Code:

Code: Alles auswählen

import pywinauto
from pywinauto import application

app = application.Application().start(r"python -m serial.tools.miniterm COM76 19200 --rts 1 --dtr 1", wait_for_idle=False)
Danach startet das Programm und wartet auf eine Tasteneingabe, die ich mit folgendem Code mache:

Code: Alles auswählen

import pywinauto
from pywinauto import application
from pywinauto.application import Application

# add your exe name here; you can get via Task Manager
yourExeName = "conhost.exe" 
 
# get PID of your running process
pid = application.process_from_module(module = yourExeName)
print(pid)


# use Pid to connect
app = Application(backend='uia').connect(process = pid)
print(app)

pywinauto.keyboard.send_keys('^N') 
Für das starten benutze ich <F5> wodurch sich die IDLE öffnet und dann auch im IDLE ein neues File öffnet. Dies ist das Problem, dass der Tastendruck im IDLE ausgeführt wird und nicht im miniterm. Ich habe die PID des miniterm geprüft und stimmt überein.

Sieht jemand was hier nicht passt?
Benutzeravatar
grubenfox
User
Beiträge: 601
Registriert: Freitag 2. Dezember 2022, 15:49

Was ist mit ? Ist das Kunst oder kann das weg? Genutzt wird es jedenfalls nicht. (den "print"-Aufruf zähle ich jetzt mal nicht als Nutzung.)
Sirius3
User
Beiträge: 18250
Registriert: Sonntag 21. Oktober 2012, 17:20

Um in einem Python-Programm etwas zu automatisieren braucht man kein pywinauto.

Was ist Dein eigentliches Problem? Was möchtest Du erreichen?
Benutzeravatar
__blackjack__
User
Beiträge: 13997
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@MyPy17: conhost.exe ist auch in der Regel mehrdeutig, denn so einen Prozess starten ja alle Programme die entweder direkt eine Konsole verwenden oder zumindest ein „Pseudoterminal“ um mit einem anderen Prozess zu kommunizieren. Es wäre also deutlich robuster nicht in einem eigenen Programm ein externes Programm zu starten und dann in einem anderen eigenen Code nicht gezielt auf diesen Prozess zuzugreifen, sondern einfach allgemein irgendeinen conhost.exe-Prozess ansprechen zu wollen. Zumal conhost.exe auch nicht direkt die GUI-Anwendung sein dürfte — da muss kein Fenster zugeordnet sein.

Und dann ist das externe Programm auch noch ein Python-Programm. Da würde ich erst mal versuchen ob man da nicht direkt von Python aus mit dem Python-Modul beziehungsweise mit der `Miniterm`-Klasse arbeiten kann.
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
MyPy17
User
Beiträge: 18
Registriert: Mittwoch 19. April 2023, 12:40

grubenfox hat geschrieben: Dienstag 25. April 2023, 10:30 Was ist mit ? Ist das Kunst oder kann das weg? Genutzt wird es jedenfalls nicht. (den "print"-Aufruf zähle ich jetzt mal nicht als Nutzung.)
Die Referenz ist sicher gut, dein Kommentar zur Problemlösung ist jedoch so was von überflüssig...
MyPy17
User
Beiträge: 18
Registriert: Mittwoch 19. April 2023, 12:40

Sirius3 hat geschrieben: Dienstag 25. April 2023, 10:45 Um in einem Python-Programm etwas zu automatisieren braucht man kein pywinauto.

Was ist Dein eigentliches Problem? Was möchtest Du erreichen?
Nun, ich möchte das miniterm starten (erstes Pythonscript) und dann von einer anderen Applikation einen Tastendruck an das miniterm senden mit dem Aufruf des zweiten Pythonscripts. Ich meine dass dies mit pywinauto am einfachsten zu lösen ist, da das miniterm nur Tasteninputs verwendet.
Sirius3
User
Beiträge: 18250
Registriert: Sonntag 21. Oktober 2012, 17:20

Aber warum brauchst Du zwei Pythonscripts?
Was möchtest Du eigentlich erreichen? Ich frage nicht nach Deinem Lösungsweg. Sondern nach Deinem eigentlichen Problem, das Du hast.
MyPy17
User
Beiträge: 18
Registriert: Mittwoch 19. April 2023, 12:40

__blackjack__ hat geschrieben: Dienstag 25. April 2023, 10:57 @MyPy17: conhost.exe ist auch in der Regel mehrdeutig, denn so einen Prozess starten ja alle Programme die entweder direkt eine Konsole verwenden oder zumindest ein „Pseudoterminal“ um mit einem anderen Prozess zu kommunizieren. Es wäre also deutlich robuster nicht in einem eigenen Programm ein externes Programm zu starten und dann in einem anderen eigenen Code nicht gezielt auf diesen Prozess zuzugreifen, sondern einfach allgemein irgendeinen conhost.exe-Prozess ansprechen zu wollen. Zumal conhost.exe auch nicht direkt die GUI-Anwendung sein dürfte — da muss kein Fenster zugeordnet sein.

Und dann ist das externe Programm auch noch ein Python-Programm. Da würde ich erst mal versuchen ob man da nicht direkt von Python aus mit dem Python-Modul beziehungsweise mit der `Miniterm`-Klasse arbeiten kann.
Nun es ist so, dass das Terminal (miniterm) gestartet ist und erst danach angesprochen wird von einem anderen pythonscript. Das heisst, man öffnet zuerst den Port x im miniterm und toggelt dann zu irgendeinem Zeitpunkt von einem anderen pythonskript die RTS-Leitung zum Beispiel. Im miniterm kann man dies erreichen wenn man eben eine Tastenkombination schickt.
Auch wenn ich die Klasse vom miniterm hätte wäre der Ablauf der gleiche, dass der Aufruf später von einer anderen Stelle aus kommt.
Benutzeravatar
__blackjack__
User
Beiträge: 13997
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@MyPy17: Du hättest nicht die Klasse von Miniterm, sondern Du hast die, denn Du hast ja das `serial`-Package. Da ist die drin. Es wäre sinnvoller und robuster von `Miniterm` auszugehen und das zu erweitern als so eine nicht wirklich robuste Frickellösung umzusetzen.

Was heisst der Aufruf kommt von einer anderen Stelle aus? Warum ist das nicht das gleiche Programm? Und warum muss das so umständlich über simulierte Tastendrücke gehen? Die RTS-Leitung kann man ja auch direkt auf dem Serial-Objekt toggeln, und falls das tatsächlich aus einem anderen Prozess passieren muss, auch über eine RPC-Schnittstelle die man genau dafür anbietet.
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
MyPy17
User
Beiträge: 18
Registriert: Mittwoch 19. April 2023, 12:40

Sirius3 hat geschrieben: Dienstag 25. April 2023, 14:46 Aber warum brauchst Du zwei Pythonscripts?
Was möchtest Du eigentlich erreichen? Ich frage nicht nach Deinem Lösungsweg. Sondern nach Deinem eigentlichen Problem, das Du hast.
Mit dem ersten wird ja nur das miniterm gestartet, sodass ich eigentlich nur das zweite script benötige um den Tastendruck zu senden. Angenommen das miniterm läuft schon, dann benötige ich nur noch das zweite Skript, das stimmt. Mein Problem ist wie gesagt: "Wie kann ich den Tastendruck an das miniterm senden, wenn das miniterm schon läuft u.U. im Hintergrund"?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das ist immer noch nicht die Antwort auf die Frage. Du hast dir einen kruden Lösungsweg ausgedacht, der übermäßig kompliziert und daher schwer zu handhaben ist. Beschreibe das ursprüngliche Problem. NICHT was du dir schon als vermeintliche Lösung ausgedacht hast.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wir waren doch schon hier viewtopic.php?t=56767 auf einen simplen Service gekommen? Ist das immer noch das gleiche Problem? Wieso kommt da plötzlich ein miniterm ins Spiel, und Tastendrücke statt simpler HTTP-Aufrufe?
MyPy17
User
Beiträge: 18
Registriert: Mittwoch 19. April 2023, 12:40

__blackjack__ hat geschrieben: Dienstag 25. April 2023, 15:13 @MyPy17: Du hättest nicht die Klasse von Miniterm, sondern Du hast die, denn Du hast ja das `serial`-Package. Da ist die drin. Es wäre sinnvoller und robuster von `Miniterm` auszugehen und das zu erweitern als so eine nicht wirklich robuste Frickellösung umzusetzen.

Was heisst der Aufruf kommt von einer anderen Stelle aus? Warum ist das nicht das gleiche Programm? Und warum muss das so umständlich über simulierte Tastendrücke gehen? Die RTS-Leitung kann man ja auch direkt auf dem Serial-Objekt toggeln, und falls das tatsächlich aus einem anderen Prozess passieren muss, auch über eine RPC-Schnittstelle die man genau dafür anbietet.

Nun, der Aufruf kommt von einem anderen Prozess (kein Python). Das heisst es kann nicht das gleiche Programm sein bzw. das miniterm läuft schon im Hintergrund. Dann erfolgt zu irgendeinem Zeitpunkt der Aufruf mit welchem ich dann das miniterm ansprechen möchte. Da das miniterm nur Tastendrücke empfängt um die RTS-Leitung zu toggeln wollte ich es eben so realisieren, dass einfach per pywinauto dieser Tastendruck gesendet wird von einem anderen Prozess aus.

Du sagst man kann dies via RPC-Schnittstelle lösen was ein guter Ansatz ist. Würdest du dann darüber die Tastendrücke absetzten? Wie weiss ich dann welches Programm (miniterm) diese empfangen muss?
Benutzeravatar
__blackjack__
User
Beiträge: 13997
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@MyPy17: Warum läuft das denn in einem anderen Prozess und warum ist das kein Python? Wenn das kein Python ist, dann nützt doch auch keine Python-Lösung um Tastendrücke zu senden.

Du willst anscheinend nicht sagen welches konkrete Gesamtproblem da eigentlich gelöst werden soll. Dann kann man halt auch schlecht Lösungen vorschlagen.
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
MyPy17
User
Beiträge: 18
Registriert: Mittwoch 19. April 2023, 12:40

__blackjack__ hat geschrieben: Mittwoch 26. April 2023, 15:12
Problemstellung:
Wie kann ich das RTS-Signal einer seriellen Schnittstelle ein- oder ausschalten wenn dies von einem externen Prozess aus gesteuert werden soll? Vom externen Prozess gibt es folgende Möglichkeiten:
- benutzen eines Batch-Files (Win)
- starten eines Pythonskriptes



Lösung:
?
Benutzeravatar
__blackjack__
User
Beiträge: 13997
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@MyPy17: Dafür würde man einfach einen Dienst schreiben der die RTS-Leitung schalten kann und zum Beispiel per Socket eine Schnittstelle zur Verfügung stellt. Da ist kein Miniterm für nötig und auch keine Fernsteuerung von anderen GUI-Programmen. Für die Socket-Kommunikation kann man sich natürlich ein eigenes Protokoll ausdenken und implementieren, aber ich würde da irgend etwas bestehendes verwenden. Eine HTTP-REST-API oder JSON-RPC oder etwas in der Richtung.
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ist ja nicht so, als ob das nicht schonmal erläutert wurde.

viewtopic.php?t=56767
MyPy17
User
Beiträge: 18
Registriert: Mittwoch 19. April 2023, 12:40

__blackjack__ hat geschrieben: Donnerstag 27. April 2023, 09:13 @MyPy17: Dafür würde man einfach einen Dienst schreiben der die RTS-Leitung schalten kann und zum Beispiel per Socket eine Schnittstelle zur Verfügung stellt. Da ist kein Miniterm für nötig und auch keine Fernsteuerung von anderen GUI-Programmen. Für die Socket-Kommunikation kann man sich natürlich ein eigenes Protokoll ausdenken und implementieren, aber ich würde da irgend etwas bestehendes verwenden. Eine HTTP-REST-API oder JSON-RPC oder etwas in der Richtung.
Das heisst man würde zum Beispiel einen Server socket laufen lassen und dann via dem Client zuerst eine serielle Schnittstelle öffnen und danach die RTS toggeln?
Antworten