Hallo,
Hmm, also bei mir funktioniert der import nur, wenn die dark.theme.properties im Programmverzeichnis liegt und ich die SciTEGlobal.properties anpasse (statt der SciTEUser.properties.)
Aber auch dabei bleiben Fensterrahmen, Scroolleiste, Menü usw. weiß bzw. hellgrau. Auf den Bildern ist das leider abgeschnitten, so dass ich nicht sehen kann, ob das "normal" so ist.
Beiträge von f705185@rppkn.com
-
-
Also du willst in der Schleife immer und immer wieder AnyDesk in den Vordergrund bringen und dann "Annehmen" klicken, egal ob das bereits passiert ist.
Das wird so nicht funktionieren.Kannst du bitte mal diese Version an Code ausprobieren:
AutoIt
Alles anzeigen#AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #AutoIt3Wrapper_AU3Check_Stop_OnWarning=y #AutoIt3Wrapper_Run_Au3Stripper=y #AutoIt3Wrapper_UseUpx=n #Au3Stripper_Parameters=/sf /sv /mo /rm /rsln ; ESC = Raus aus der Schleife. Setze die Taste oder Tastenkombination deiner Wahl. HotKeySet('{ESC}', '_Exit') Global $bScriptShouldEnd = False _Actions() Exit Func _Exit() $bScriptShouldEnd = True EndFunc Func _Actions() Local $mAnyDesk[] $mAnyDesk.ProcessName = 'AnyDesk.exe' $mAnyDesk.FilePath = 'C:\Program Files (x86)\AnyDesk\AnyDesk.exe' $mAnyDesk.WindowTitle = 'AnyDesk' $mAnyDesk.AcceptButton = '[CLASS:basic_button#9; INSTANCE:1]' While Not $bScriptShouldEnd If Not ProcessExists($mAnyDesk.ProcessName) Then Run($mAnyDesk.FilePath) EndIf If Not _IsWindowInForegroundWithinThreeSeconds($mAnyDesk.WindowTitle) Then ContinueLoop EndIf ControlClick($mAnyDesk.WindowTitle, '', $mAnyDesk.AcceptButton) Sleep(500) WEnd EndFunc Func _IsWindowInForegroundWithinThreeSeconds($sWindowTitle) Local Const $iTimeout = 3 If Not WinWaitActive($sWindowTitle, '', $iTimeout) Then Return False EndIf Return True EndFunc
Ich gehe hier davon aus, dass ein Fenster mit Titel "AnyDesk" aufpoppt und erst wenn dieses aufpoppt/aktiv/im Vordergrund ist, dann wird der Button "Annehmen" gewählt.
Viele Grüße
SvenJa, richtig. Man muss dieses neue Fenster sogar nicht mal aktiv in den Vordergrund bringen, es erscheint autom. "ganz nach vorne".
Streng genommen muss man es sogar nicht irgendwohin verschieben, da es immer gleich groß und an der gleichen Stelle ist, wenn es erscheint.
Obiger Code klappt leider auch nicht. Ich gebe es aber auf, das wird so nicht klappen. Wahrscheinlich irritiert den das, dass beide Fenster den gleichen Titel oder so haben.
Ich bedanke mich nochmals sehr bei dir für deine Zeit & Mühen!
-
Falls das folgende nicht den Klick durchführt, dann wechsle im Au3Info Tool mal auf den Reiter Control und nutze ggf. die Advanced Mode (dort doppel-klicken und einfügen).
ControlClick('AnyDesk', '', '[CLASS:basic_button#9]')Allerdings muss ich sagen, dass ich dir bereits im Beitrag #2 gesagt hatte, dass du die Hilfe mal bemühen solltest, denn aus dem Beispiel dort wäre genau dies auch hervorgegangen 🧐 .
Viele Grüße
SvenIch versuche es schon, so ist das nicht!
Folgendes habe ich probiert, vielleicht kannst du ja direkt den Fehler erkennen:
AutoIt
Alles anzeigenWhile 1 If Not ProcessExists('AnyDesk.exe') Then Run('C:\Program Files (x86)\AnyDesk\AnyDesk.exe') EndIf Sleep(250) If WinExists("AnyDesk", "[CLASS:basic_button#9; INSTANCE:1]") Then WinActivate("AnyDesk", "[CLASS:basic_button#9; INSTANCE:1]") WinWaitActive("AnyDesk", "[CLASS:basic_button#9; INSTANCE:1]") sleep(1500) ControlClick('AnyDesk', '', '[CLASS:basic_button#9; INSTANCE:1]') EndIf WEnd
Ich habe jetzt bei allen die Klasse zu der vom Advaned gemacht.
-
Wenn du nun also mit dem Au3Info Tool über den grünen "Annehmen" button hoverst, wird dieser wahrscheinlich nicht als einzelnes Control angezeigt oder doch?
Daher nochmal die Bitte: Screenshot des Tools während du über die Bereiche des AnyDesk Fensters hoverst bzw. über den Button.
Danach sehen wir, ob die die CLASS verwenden kannst oder nicht.
1. Alternative wenn nicht: Relative Koordinaten zum Klick benutzen (siehe mein Code-Beispiel weiter oben).
2. Alternative wenn nicht: Mit PixelSearch() in einem gewissen Bereich des Fensters (auch wieder relativ zum Fensterinhalt, nicht zum Screen) nach dem grün des Buttons suchen und dort dann per Maus klicken lassen.
Viele Grüße
SvenNatürlich. So sieht das dann aus, bin gespannt, wie das gelöst wird.
-
Achso! => Darum sagt ein Bild manchmal mehr als 1000 Worte 😅 .
Basic Window Info zeigt den Titel des Fensters (siehe Titelleiste) und die CLASS des Parent-Elements des Fensters.
Basic Control Info zeigt hingegen die Informationen des Controls, über das du mit dem "Finder Tool" hoverst. Allerdings auch nur, wenn Au3Info dies überhaupt erkennen kann.
Viele Grüße
SvenJa, ok, dann wäre ja alles klar. Tut mir leid für die Verwirrung!
-
Nein, woher auch? Wie wäre es wenn du beschreibst wo du diese Angaben her hast oder siehst? Geht es um das Au3Info Tool, welches dir diese Klassen anzeigt, wenn du über das aufpoppende AnyDesk Fenster hoverst? Vielleicht ich es dir nicht bekannt, doch ein Fenster kann auf Grund seines Aufbaus (bspw. der darunter liegenden Programmiersprache oder des verwendeten Frameworks (wie Swing, Qt etc.)) völlig unterschiedliche Controls/Elemente bzw. Klassen aufweisen. Also daher ist mir kein Basic Window Info oder Basic Control Info bekannt.
Auch hierzu bitte Screenshots, damit man zumindest Versuche starten kann. Es ist nicht so, als würde ich mir extra AnyDesk installieren um dein Szenario durchzuspielen, ein wenig mehr Zuarbeit braucht es schon - schließlich bist du hier der Fragende, meinst du nicht?Bitte nicht falsch verstehen, doch Forderungen finde ich unangebracht.
Viele Grüße
SvenAch nein, ich meinte das nicht bezogen auf meine Anwendung sondern i.A. also generell.
Das Tool heiß Autoit Window Info. Dort gibt es eben diese 2 Kategorien
-
Kannst du daher mal ein paar Screenshots machen in denen du deutlich machst, was du manuell genau tun würdest? Dann sind die Vorschläge sicherlich auch besser.
Sehr gerne.
Also, das normale Anydesk Fenster läuft ja, und wenn es nicht läuft, dann wird es gestartet. Das klappt alles, da muss auch am Code nichts verändert werden.
So, nun ist es so, dass, wenn sich ein anderes Gerät verbinden möchte, dann ein neues Fenster erscheint. Dafür soll es in der gleichen while Schleife auch eine Bedingung geben, dass diese Anfrage jederzeit angenommen wird (sei es um 3 oder um 19 Uhr).
Im Anhang ist ein Bild, wie diese Anfrage aussieht.
Kurz: es soll einfach nur auf annehmen drücken, sobald eine Verbindungsanfrage erscheint.
Und könntest du mir bitte endlich mal den Unterschied zwischen der Klasse von "Basic Window Info" und "Basic Control Info" sagen? Danke.
-
Hier mal die einfachere Variante mit den Maus-Klicks. Nicht elegant und je nachdem was du alles machen willst auch nicht ausreichend, aber vielleicht reicht dir das bereits.
AutoIt
Alles anzeigen#AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #AutoIt3Wrapper_AU3Check_Stop_OnWarning=y #AutoIt3Wrapper_Run_Au3Stripper=y #AutoIt3Wrapper_UseUpx=n #Au3Stripper_Parameters=/sf /sv /mo /rm /rsln ; Ggf. musst du die Admin-Rechte Direktive aktivieren. ; Dazu die nächste Zeile ein- oder auskommentieren. ; #RequireAdmin Opt('MouseCoordMode', 0) ; 0 = relative Koordinaten zum aktiven Fenster HotKeySet('{ESC}', '_Exit') ; ESC = Raus aus der Schleife. Setze die Taste oder Tastenkombination deiner Wahl. Global $bScriptShouldEnd = False _Actions() Exit Func _Exit() $bScriptShouldEnd = True EndFunc Func _Actions() Local $mAnyDesk[] $mAnyDesk.ProcessName = 'AnyDesk.exe' $mAnyDesk.FilePath = 'C:\Program Files (x86)\AnyDesk\AnyDesk.exe' $mAnyDesk.WindowTitle = 'AnyDesk' While Not $bScriptShouldEnd If Not ProcessExists($mAnyDesk.ProcessName) Then Run($mAnyDesk.FilePath) If Not _IsWindowActiveWithinTenSeconds($mAnyDesk.WindowTitle) Then ExitLoop EndIf _MoveWindowToTopLeftCorner($mAnyDesk.WindowTitle) ; Dies dient nur der Robustheit (du könntest daher auch "MouseCoordMode" auf Standard lassen) MouseClick('left', 15, 15) ; Klicke im Fenster per relative Koordinaten EndIf Sleep(500) WEnd EndFunc Func _IsWindowActiveWithinTenSeconds($sWindowTitle) Local Const $iTimeout = 10 If Not WinWait($sWindowTitle, '', $iTimeout) Then Return False EndIf WinActivate($sWindowTitle) If Not WinWaitActive($sWindowTitle, '', $iTimeout) Then Return False EndIf Return True EndFunc Func _MoveWindowToTopLeftCorner($sWindowTitle) WinMove($sWindowTitle, '', 0, 0) EndFunc
💡 Wichtig hierbei:
Es wird nur reagiert, wenn der Prozess nicht existiert. Also bspw. der Rechner startet neu, dann wird AnyDesk gestartet und auf X oder Y geklickt (dies musst du vorgeben wo).
Oder: Jemand beendet AnyDesk komplett (der Prozess existiert nicht mehr), dann wird dieser erneut gestartet, die Klicks werden gemacht etc.
💡 Aber:
Wenn der Prozess bereits vorhanden ist oder noch läuft und dann erst das Skript gestartet wird, wird auch nichts geklickt. Also wenn ein Nutzer einfach die Verbindung beendet, anstatt den AnyDesk wirklich komplett zu schließen, dann merkt dies das Skript nicht (es reagiert nicht), da nur darauf gelauscht wird, ob der Prozess läuft oder nicht.
Wenn dies so nicht reicht, dann müsstest du einen anderen Indikator dafür finden, ob eine Verbindung bereits besteht oder nicht. Falls nicht, Fenster in den Vordergrund bringen und Klick-Aktionen machen (dieser Teil ist ja bereits vorhanden).
Bin gespannt, was du meinst 😅 .
Viele Grüße
SvenVielen lieben Dank für deine sehr ausführliche Antwort!!
Aber ich denke, du hast mich da leider falsch verstanden.
Und zwar soll Anydesk immer im Hintergrund laufen, und wenn es nicht läuft bzw. geschlossen wird, dann soll es laufen.
Das geschieht ja soweit gut mit folgendem Code:
AutoItIf Not ProcessExists('AnyDesk.exe') Then Run('C:\Program Files (x86)\AnyDesk\AnyDesk.exe') EndIf Sleep(250)
Dann ist es ja so, dass ein zusätzliches Fenster erscheint, wenn eine Verbindungsanfrage von einem Gerät kommt.
Da möchte ich es so haben, dass im zusätzlichen Pop-up auf annehmen gedrückt wird.
Und genau da ist mein Problem:
Ich weiß 1) nicht, ob ich die Klasse von "Basic Window Info" oder von "Basic Control Info" nehmen muss.
2) Wie ich das am besten per ControlClick implentieren soll.
Ich glaube, dein Code ist da wirklich sehr ausführlich, ich glaube sogar fast schon zu sehr ausführlich.
Das geht bestimmt kürzer, mir fehlt da sogar (mit dem ersten Code im Anfangspost verglichen) glaube ich nur eine Zeile, die korrigiert werden muss.
-
Hi @f705185@rppkn.com,
zu aller erst möchte ich dir den Hinweis geben, dass du unter "Benutzerkonto verwalten" deinen Benutzernamen ändern kannst.
Nur für den Fall das er dir zu lang erscheint 😅 .
Dann zu deiner Fragestellung:
- Du möchtest wenn der Prozess AnyDesk noch nicht läuft, dass dieser geöffnet wird und im aufpoppenden Fenster etwas geklickt wird. Soweit erstmal korrekt, richtig?
- Wenn der Prozess AnyDesk bereits existiert, zum Zeitpunkt des ersten Ausführens, dann soll dies auch geschehen oder nicht?
- Was soll passieren wenn die Klicks ausgeführt wurden? Dies ist u. a. entscheidend für die Logik in der Schleife.
💡 Bestenfalls kannst du mit ControlClick() und/oder ControlCommand() arbeiten. Denn dann musst du nicht über Koordinaten gehen. Schaue dir die Hilfe zu diesen Funktionen einfach mal an. Falls das Fenster jedoch nicht mit diesen Funktionen erreichbar sein sollte, hast du mindestens zwei Optionen.
A: Du setzt dich mit UIAutomation auseinander (was eine gewisse Einarbeitungsphase und ggf. fortgeschrittene Kenntnisse voraussetzt).
B: Du nutzt doch Koordination, die jedoch relativ zum aktiven Fenster sind, nicht zum Screen. D. h. Wenn du das Fenster schiebst auf deinem Monitor bspw., sind die relativen Koordination im Fenster noch immer die Gleichen. Falls das Fenster nicht irgendwie größer oder kleiner gezogen wurde. Dies kannst du allerdings mit der Funktion WinMove() ganz gut handhaben. Denn du setzt einfach das aktive (bei dir AnyDesk) Fenster auf eine von dir definierte Größe und machst danach deine Klicks.
Viele Grüße
SvenAbend Sven,
genau, wenn Anydesk noch nicht läuft, dann soll es laufen.
Und wenn da eine Verbindungsfrage kommt, soll er es annehmen.
Das alles in einer unendlichen While Schleife, damit das auch immer klappt.
Den Rest schaue ich mir morgen früh mal genauer an. Danke schonmal!
-
Anlehnend an meinen anderen Thread: Programm schreiben, das überprüfen soll ob .exe im Hintergrund läuft (vielen Dank an dieser Stelle für die zahlreichen Antworten!) möchte ich auf eine bestimmte Stelle klicken, wenn ein bestimmtes Fenster erscheint.
Allerdings soll das in einer while-Schleife passieren. Meine will nicht so ganz klappen:
AutoIt
Alles anzeigenWhile 1 If Not ProcessExists('AnyDesk.exe') Then Run('C:\Program Files (x86)\AnyDesk\AnyDesk.exe') EndIf Sleep(250) If WinWait("[class:ad_win#3]") Then Sleep(1000) MouseClick("left", 695, 728, 1) EndIf WEnd
Also, das erste Problem hierbei ist, dass das erste if-Statement nur einmal ausgeführt wird. Kann mir vorstellen, dass es daran liegt, dass er beim zweiten hängenbleibt.
Das zweite Problem ist, dass ich beim MousClick nicht per Koordinaten klicken möchte, da diese sich immer wieder verändern können.
Ich glaube, die Lösung ist es, per Klassen zu arbeiten. Allerdings weiß ich nicht, ob ich die Klasse von "Basic Window Info" oder von "Basic Control Info" nehmen muss.
Wenn ich bestimmte klickbare Teile innerhalb des Fensters auswähle, dann ändert sich eine Klasse, die andere bleibt gleich. Heißt, es müsste die änderbare, also Basic Control Info sein, denke ich mal: basic_button#9
Was habe ich also falsch gemacht?
-
Schau dir mal die Hilfe zu ProcessExists an.
Auszug : Die Prozessnamen sind die ausführbaren Dateien ohne den kompletten Pfad, also z.B. "notepad.exe" oder "winword.exe".
ja ok, das habe ich ja so bereits probiert. Und die .exe in win32 zu packen, damit ich direkt anydesk.exe schreiben kann, macht ja keinen Sinn. Was ist hier also die Lösung?
-
Hallo,
ich möchte ein kurzes Programm schreiben, das überprüft, ob ein Programm im Hintergrund läuft und falls nicht, das es dann einmal startet (also in ner Schleife).
Folgendes klappt mit dem Text-Editor wunderbar:
Es startet den Text Editor genau einmal, wenn es nicht geöffnet wird.
Mache ich allerdings in die "" nicht notepad.exe rein, sondern "C:\Program Files (x86)\AnyDesk\AnyDesk.exe" dann startet es das Programm unendlich oft, auch wenn es bereits läuft.
Ich kann mir vorstellen, dass es i-was mit dem Pfad zu tun hat, weil oben bei Notepad habe ich nur die .exe angegeben.
Anydesk in win32 zu verschieben, würde glaube ich keinen Sinn ergeben. Wie sähe das also richtig aus? -
-
Danke für die Erklärungen. Das mit \Z vs \z ist mir klar geworden aus der Hilfe, aber ein guter und wichtiger Hinweis. Mich wundert btw, dass es sich mit \A und \a nicht analog verhält.
Durch die Perspektive search vs. match wird es wesentlich verständlicher, warum das so gebaut ist. -
Das ist für mich extrem unintuitiv. Warum muss ich das angeben, was ich nicht matchen will ("alles, was kein Wort trennt")?
Nach meinem Verständnis von RegEx sollte man explizit angeben, was man matcht und nicht, was man nicht matcht. Will sagen: Was ich in meinem Pattern nicht angebe, soll auch nicht da sein. \b vor und nach jedes Zeichen (bzw. in meinem Fall zu machtende Wort) zu setzen macht den Code extrem unleserlich und ich kann beim besten Willen nicht verstehen, was sich ein Sprachdesigner dabei gedacht hat. Schließlich ist es StringRegEx und nicht SubStringRegEx.
Immerhin geht "\A(a|b|c)\Z". Ist zwar hässlich und wird mich irgendwann zwingen \A und \Z nachzuschlagen, wenn ich den Code überarbeite, aber scheinbar muss das in Autoit dann so. Danke. -
Wie gesagt, ich matche a, nicht .*a.* - offenbar ergänzt Autoit .* auf beiden Seiten Seite automatisch bzw. interpretiert die RegEx als Substring, weil auf "dabc" ebenso die Regex "a" matcht
Was ich erwarte und warum habe ich doch schon beschrieben - mir ist nicht klar, wie ich es anders formulieren soll. Ich versuche es dennoch nochmal
sollte False/0 sein
sollte True/1 sein
-
-
Es war viel einfacher als ich dachte. Ich muss einfach jedesmal ein neues Objekt erstellen. Hier der Code:
[autoit]Dim $var1=ObjCreate("Scripting.Dictionary")
[/autoit][autoit][/autoit][autoit]
Dim $var2=ObjCreate("Scripting.Dictionary")$var1.add("farbe","grün")
[/autoit][autoit][/autoit][autoit]
$var1.add("eigenschaft","fest")
$var2.add(1,$var1);$var1.RemoveAll alter Code
[/autoit][autoit][/autoit][autoit]$var1=ObjCreate("Scripting.Dictionary") ;neu
[/autoit][autoit][/autoit][autoit]
$var1.add("farbe","gelb")
$var1.add("eigenschaft","flüssig")
$var2.add(2,$var1)Dim $var3=ObjCreate("Scripting.Dictionary")
[/autoit]
Dim $var3 = $var2.Item(1)
msgbox(48,"Eigenschaft",$var3.Item("eigenschaft")); -
Danke schonmal für die prompte und ausführliche Antwort. Call by Value und Call by Reference sind mir von C geläufig. Ich hatte vermutet, dass es damit zusammenhängt.
ZitatDas heißt du musst also immer ein neues Dictionary erstellen anstatt immer wieder auf das selbe zu verweisen.
Ich schildere mal mein Problem etwas abstrakt. Ich habe mehrere Autos. Die Eigenschaften eines Autos lege ich in ein Dictionary. Meine gesamten Autos möchte ich nun in einem weiteren Dictionary als Fuhrpark zusammenfassen. Diesen Fuhrpark möchte ich nun an eine Funktion übergeben, die z.B. den Fuhrpark einfach nur ausgibt. Die einzelnen Autos zu übergeben macht da also wenig Sinn.
Wie löse ich diese Aufgabe am besten? -
Hier mein Skript
Code
Alles anzeigenDim $var1=ObjCreate("Scripting.Dictionary") Dim $var2=ObjCreate("Scripting.Dictionary") $var1.add("farbe","grün") $var1.add("eigenschaft","fest") $var2.add(1,$var1) $var1.RemoveAll $var1.add("farbe","gelb") $var1.add("eigenschaft","flüssig") $var2.add(2,$var1) Dim $var3=ObjCreate("Scripting.Dictionary") Dim $var3 = $var2.Item(1) msgbox(48,"Eigenschaft",$var3.Item("eigenschaft"));
Erwartet wird, dass in der Messagebox "fest" steht, stattdessen erscheint "flüssig". Was mache ich falsch? Wie kann ich es besser lösen? Danke für die Hilfe im Voraus.