Controlsend in PuTTY für WOL

  • Hallo,

    ich habe mir einen Code geschrieben um meinen PC über WOL aufzuwecken, die Remotedesktopverbindung zu starten und bis zu der Passwortabfrage von Windows 10 zu verbinden. Funktioniert soweit.

    Jetzt möchte ich auf Controlsend () umstellen um Fehler bei der Eingabe zu minimieren und kein Blockinput verwenden zu müssen.

    Die Controlsend () Befehle sollen die Send () Befehle ablösen.

    Neu öffnet PuTTY, es wird ein (1) mal TAB gedrückt danach passiert nichts mehr.

    WinWaitActive habe ich, um es als Fehlerquelle auszuschliessen, deaktiviert.


    In der Hilfe (F1) zu Controlsend () steht:

    Sends a string of characters to a control.

    ControlSend ( "title", "text", controlID, "string" [, flag = 0] )

    ControlSend($hWnd, "", "Edit1", "This is some text")

    Was mache ich falsch? Wird die controlID zwingend gebraucht? Warum kommt dann ein TAB an?

    Window Info Summary

    >>>> Window <<<<

    Title: PuTTY Configuration

    Class: PuTTYConfigBox

    Position: 450, 159

    Size: 466, 449

    Style: 0x94C800C4

    ExStyle: 0x00010501

    Handle: 0x00020492

    >>>> Control <<<<

    Class:

    Instance:

    ClassnameNN:

    Name:

    Advanced (Class):

    ID:

    Text:

    Position:

    Size:

    ControlClick Coords:

    Style:

    ExStyle:

    Handle:

    >>>> Mouse <<<<

    Position: 632, 203

    Cursor ID: 0

    Color: 0xF0F0F0

    >>>> StatusBar <<<<

    >>>> ToolsBar <<<<

    >>>> Visible Text <<<<

    &Open

    &Cancel

    &About

    &Help

    Cate&gory:

    Host &Name (or IP address)

    &Port

    22

    Connection type:

    &SSH

    Se&rial

    O&ther:

    Telnet

    Specify the destination you want to connect to

    Sav&ed Sessions

    &Load

    Sa&ve

    &Delete

    Load, save or delete a stored session

    Close window on e&xit:

    Always

    Never

    Only on clean exit


    >>>> Hidden Text <<<<

    Bildlegende:

    (1) Swiffer auswählen/markieren

    (2) Open drücken

    Neues Fenster geht auf

    (3) "Swiffer" schreiben (immer ohne "")

    (4) {Enter} drücken

    Fenstername ändert sich

    (5) Schreiben

    (6) Drücken

    usw..

    Sauber bleiben.

    Einmal editiert, zuletzt von Swiffer (23. Dezember 2022 um 07:34) aus folgendem Grund: Screenshots hochgeladen

  • Hi Swiffer,

    kannst du bitte mal ein Screenshot von Putty deinem Post hinzufügen. Denn auf Grund deiner Send-Befehle und der Kommentare dazu kann ich persönlich nur sehr schwer helfen.
    Besser wäre, wenn du vielleicht bebildert zeigen könntest, was du wann drücken/schreiben/ausführen möchtest, dann können wir auch besser einschätzen ob ControlSend() überhaupt sinnvoll ist oder man es ganz anders lösen könnte/sollte.

    So eine Art Klick-Reihenfolge wäre super. Beispiel:



    Bitte beschreibe nochmal genau was du tun willst, Danke 🤝 .

    Viele Grüße
    Sven

  • Hi Swiffer,

    viel besser, Danke dir 🤝 . Okay, also zu deinem ersten Teil schlage ich vor, gar nicht erst über die putty Oberfläche zu gehen und zu versuchen mit ControlSend() putty zu steuern.
    Putty kann über die command line gesteuert werden, daher das folgende code snippet:

    Eigentlich sind es nur Zeile 9 bzw. Zeile 12, welche interessant sind. Das mit dem Debug Modus an/aus ist nur zur Flexibilität. Wenn du statt True auf False stellst, wird dir gar nicht erst das command line Fenster angezeigt.

    Voraussetzung hier ist, dass dein du eine Session mit dem Namen "Swiffer" gespeichert hast. Versuche dies doch mal bitte und dann kümmern wir uns ggf. um den restlichen Login im putty client. Oder du schaust dir schon mal die Doku an 😉 .

    Viele Grüße
    Sven

  • Ok hier sind ja einige Themen abzuarbeiten.
    Vorab: Automatisiertes Rumgeklicke und Send-Geschreibe ist nicht das Mittel der Wahl um Dinge wie Putty und die entsprechenden Remote-PCs zu steuern.

    Gehen wir mal bisschen durch:

    1. Man muss nicht die Oberfläche von Putty hochfahren und dort wild herumklicken lassen um eine bestimmte Putty-Session zu starten.
    Das geht auch direkter:

    AutoIt
    ; Einstellungen die du anpassen musst:
    Global Const $sPathPutty = "C:\Dein\Ordner\PUTTY.EXE"
    Global Const $sPuttyConfig = "Swiffer"
    
    ; Startet die Putty-Config:
    $iPID = Run('"' & $sPathPutty & '" -load "' & $sPuttyConfig & '"')

    2. Man muss nach einem Connect nicht immer einen Benutzernamen angeben.
    In der Putty-Konfiguration kann man auch einen Usernamen unter Connection --> Data --> Auto-login username eintragen und spart sich damit das Eintragen des Usernamens.

    3. Man muss nicht immer ein Passwort in Putty verwenden. Man kann stattdessen auch ein Key-File verwenden.

    Hierzu:

    1. Im Putty-Ordner gibt es das Tool PUTTYGEN.EXE. Mit diesem einen Key erstellen und den private-Key in eine Datei speichern (Das Programm weiter offen lassen).
    2. auf dem Server einloggen und (falls noch nicht vorhanden) den Ordner ~/.ssh und die Datei ~/.ssh/authorized_keys folgendermaßen erzeugen:
      mkdir -p -m 700 ~/.ssh && install -m 600 /dev/null ~/.ssh/authorized_keys
    3. In Puttgen den Key aus dem Textfenster so wie er ist kopieren.
    4. In der Datei ~/.ssh/authorized_keys den eben kopierten Key mit dem Editor der Wahl als neue Zeile einfügen.
    5. In der Putty-Konfiguration unter Connection --> SSH --> Auth --> Private key file for authentification den Pfad zur exportierten Private-Key-Datei eintragen.

    Nun sollte Putty sich einloggen ohne nach Nutzername und Passwort zu fragen.

    4. Man muss nicht über Maus- und Tastatursimulationen mit Putty kommunizieren. Es gibt im Putty-Ordner das Tool plink.exe. Mit diesem stellt man eine ssh-Connection auf der Konsole her (geht auch mit dem in Windows eingebauten Tool ssh). Heißt man kann nun direkt mit StdOut und StdIn kommunizieren.
    Grob könnt es so laufen:

    5. Und das ist der wichtigste Punkt! Warum musst du dich überhaupt per Putty in einen anderen Rechner einloggen und von dort aus das WoL-Signal an dein eigentliches Ziel schicken?
    Ist dein PC und das Ziel etwa nicht im selben Netz?
    Du kannst genauso direkt von Windows aus das magic packe verschicken.
    Da gibt es zig Tools für (wolcmd,wol2, WakeMeOnLan).
    Kurz: Ist diese Kaskade über 5 Ecken wirklich notwendig?

  • Ich wollte es eher in kleine Häppchen verpacken AspirinJunkie, doch so geht es natürlich auch 😅 .
    Nein ehrlich, Danke dir 🤝 . Spart mir Zeit selbst durch die Referenz zu gehen und ich habe gleich auch noch was dazu gelernt, Danke.

    Jetzt liegt es an dir Swiffer. Die Erläuterung, aber auch die letzte Frage von AspirinJunkie, ist super.

    Viele Grüße
    Sven

  • Moin,

    es gibt da eine uralte wake . exe unter Dos. Diese mit autoit ansteuern? Auf Wunsch kannst Du die *.exe haben = OS oder Freeware.

    LG

    Peter

    Hinweise auf Suchmaschinen finde ich überflüssig - wer fragt hat es nicht gefunden oder nicht verstanden. Die Antwort gibt sich oftmals schneller als der Hinweis auf Dr. Goggle & Co.

    Ab 19-10-22 ergänzt um:

    Die Welt wird nicht bedroht von den Menschen, die böse sind, sondern von denen, die das Böse zulassen. (Albert Einstein)

  • Erstmal vielen Dank für die vielen Antworten und Lösungsvorschläge!

    Trotzdem nochmal nachgefragt: Wird die controlID zwingend gebraucht für Controlsend ()? Geht es deshalb nicht? Java?

    SOLVE-SMART

    Versuche dies doch mal bitte und dann kümmern wir uns ggf. um den restlichen Login im putty client.

    Das funktioniert super, danke.

    Ich wollte es eher in kleine Häppchen verpacken

    Ich musste wirklich lachen! :D Bin schon ein wenig erschlagen.

    AspirinJunkie

    Das geht auch direkter:

    Auch Dein erster Code funktioniert bestens, danke.

    2. Man muss nach einem Connect nicht immer einen Benutzernamen angeben.

    Falls machbar würde ich das gerne so lassen mit dem Benutzernamen eingeben. Es ist nicht immer der gleiche Benutzer bzw. falls Putty mal manuell gestartet werden sollte müsste sich auch ein andere Nutzer anmelden können.

    Man muss nicht immer ein Passwort in Putty verwenden. Man kann stattdessen auch ein Key-File verwenden.

    Ich verwende den "public key" , ersichltich auf dem dritten Screenshot. Aber danke trotzdem. Sehr nett und gleich mit Anleitung wie erstellen. Top!

    Grob könnt es so laufen:

    Ich bin mir sicher das auch dein zweiter Code funktionieren würde. Durch den nicht automatisiert angemeldeten Benutzer scheitert es aber. Leider sehe ich gerade nicht wo das noch geändert werden müsste.

    5. Und das ist der wichtigste Punkt! Warum musst du dich überhaupt per Putty in einen anderen Rechner einloggen und von dort aus das WoL-Signal an dein eigentliches Ziel schicken?

    Es sind zwei getrennte Orte, zwei Fritzboxen, zwei Pi4 auf denen Wireguard VPN läuft.

    (Das VPN der 7490 war einfach zu langsam, deshalb die Pi)

    Ich weiss nicht mehr genau warum WOL über die Fritzboxen nicht zuverlässig funktionierte. Ich glaube es hat etwas mit der Namensauflösung zu tun. Die Fritzbox peilt nicht wohin mit dem Paket trotz MAC-Adresse. Ist schon ne Weile her. Aber es geht ziemlich sicher nicht ohne den Schritt über den Pi. Ich lasse mich gerne korrigieren. Das VPN steht jedoch so oder so.

    192.168.150.xxx / 192.168.160.xxx

    Peter S. Taler

    Ich befürchte die Pakete werden damit nicht ankommen. Der Befehl muss aus dem gleichen Netz kommen. Aber danke trotzdem für den Vorschlag.

    funkey

    Auch hier habe ich vermutlich das gleiche Problem mit dem Netzwerk. Also muss ich erst auf dem Pi. Danke auch Dir.

    Sauber bleiben.

  • Ich habe jetzt in Putty doch den Benutzer zur automatischen Anmeldung hinterlegt. Dachte erst ich muss es auf dem Pi selbst machen. So geht es ja wirklich gut auch mit anderen Benutzer.

    Leider wacht der PC nicht auf und ich weiss nicht warum. Es kommt keine Fehlermeldung. Ich habe versucht den Debug Modus von SOLVE-SMART in das Script von AspirinJunkie einzubauen um zu sehen wo es stockt aber ich stehe auf verlorenem Posten.

    Um Euch zu verdeutlichen dass es für mich nicht einfach ist schreibe ich mal rein was ich von dem Code zu verstehen glaube:

    Spoiler Ka.

    #include <AutoItConstants.au3>Inkludiere die Datei Constants

    ; ; Einstellungen die du anpassen musst:

    Global Const $sPathPLink = "C:\Dein\Ordner\plink.exe" Pfadangabe Plink

    Global Const $sPuttyConfig = "Swiffer" Gespeicherter Benutzer bzw. Einstellungen in Putty

    ; Startet die Putty-Config:

    $iPID Ka, wohl das Putty Fenster aber warum?.= RunAusführen('"' & $sPathPLink Pfad& '" -loadLaden "' & $sPuttyConfigBenutzer & '"', ""Ka., @SW_Hideverstecke, $STDIN_CHILD + $STDOUT_CHILDKa.)

    Local $sCmdOut = ""Schreibe in CMD

    DoMach

    Sleep(100)

    $sCmdOut &= StdoutRead($iPID)Schreibe in CMD + lese etwas im Putty Fenster.

    If @error Then ExitLoopFalls Fehler verlasse die Schleife

    If @extended = 0 Then ContinueLoopWenn ka. ist mache weiter in der Schleife

    ConsoleWrite($sCmdOut & @CRLF)Schreibe in die Console, Schreibe in CMD + Ka.

    ; einfache Prüfung ob schon Eingaben möglich sind

    If StringInStr($sCmdOut, ":") Then Wenn im Fenster : geschrieben werden kann dann

    StdinWrite($iPID, "sudo etherwake xx:xx:xx:xx:xx" & @CRLF) Schreibe im Fenster sudo... +@ka.

    Sleep(500)

    StdinWrite($iPID, "exit" & @CRLF)Schreibe im Fenster exit

    ExitLoopVerlasse die Schleife

    EndIf

    Until FalseBis falsch

    ProcessClose($iPID) Beende den Prozess Putty

    Falls jemand Lust hat mir dies ein wenig genauer zu erklären wäre das toll! :D

    Vielleicht lässt sich dann herausfinden warum es nicht funktioniert. Ausserdem wäre meine Neugierde befriedigt.

    Edit: Die MAC-Adresse habe ich vom funktionierenden script kopiert. An dem sollte es also nicht liegen.

    Edit1: Ich merk gerade das sich Putty zerschossen hat. Ich komme auch so nicht mehr auf den Pi. Ich fix das dann geht vermutlich das script auch.

    Edit2: Hust... Äh ja.. Wie soll ich das jetzt... Ich war Schuld! Kopf->Tisch!

    Die Daten in Putty neu gespeichert, keine Ahnung warum die fehlerhaft waren, und es läuft natürlich auch das script von AspirinJunkie fehlerfrei durch bzw. wacht der Rechner auf.

    Ich werde jetzt noch versuchen ein Popup-Fenster einzubauen um zu wissen dass der Rechner gerade aufstartet und danach die Remoteverbindung öffnen. Und hoffe dabei diesen schönen, kompakten code mit meinen stümperhaften Programmierkünsten nicht allzu sehr zu verschandeln ;)

    Vielen Dank nochmal an alle die geholfen haben! Wirklich sehr hohes Niveau hier!

    PS: Falls noch jemand Lust hat mir den Spoiler Ka. oben zu erklären bin ich immer noch interessiert.

    Sauber bleiben.

    4 Mal editiert, zuletzt von Swiffer (25. Dezember 2022 um 00:53) aus folgendem Grund: Edit:

  • Die Daten in Putty neu gespeichert, keine Ahnung warum die fehlerhaft waren, und es läuft natürlich auch das script von AspirinJunkie fehlerfrei durch bzw. wacht der Rechner auf.

    Ganz schön auf die Art arbeiten lässt sich noch nicht.
    Man könnte sich ein paar Hilfsfunktionen dazu schreiben um das bisschen sauberer und übersichtlicher hinzubekommen.

    Hier mal wirklich nur kurz hingeschludert ein paar Funktionen die das ganze etwas komfortabler machen könnten:

    Putty-SSH Hilfsfunktionen Rohfassung(!)

    Ist aber wie gesagt überhaupt keine ausgereifte UDF oder sowas. Nur ein grobes Grundgerüst.
    Vielleicht baue ich es mal zu einer ausgewachsenen UDF aus.

    Es sind zwei getrennte Orte, zwei Fritzboxen, zwei Pi4 auf denen Wireguard VPN läuft.

    Einen WoL-Proxy hast du schon probiert?

    Und verschiedene Lösungen für Wake-over-WAN gibt es ja auch.

    Einmal editiert, zuletzt von AspirinJunkie (25. Dezember 2022 um 13:31)

  • Vielen Dank! Hast Du das einfach kurz geschrieben? :O

    Irgendwas scheint da noch nicht ganz richtig.

    Error:

    (26,43) : error: undefined macro.

    Local $iPID = Run($sCmd, "", @HIDE,

    (31,43) : error: undefined macro.

    Local $iPID = Run($sCmd, "", @HIDE,

    Was ist denn der Vorteil eines WoL-Proxy? Das wäre ja noch zusätzliche Hardware oder verstehe ich das falsch?

    Mit Wake-over-WAN habe ich mich noch nicht beschäftigt. Ich finde die bisherige Lösung über die zwei Pi die eh als VPN fungieren eigentlich ganz ok.

    Sauber bleiben.

  • Irgendwas scheint da noch nicht ganz richtig.

    Jo - musste @SW_HIDE heißen - habs geändert.

    Was ist denn der Vorteil eines WoL-Proxy? Das wäre ja noch zusätzliche Hardware oder verstehe ich das falsch?

    Damit kann man Netzübergreifend WoL-Pakete senden.
    Ich steck da nicht tief im Thema da ich das noch nicht bräuchte aber im Grunde gäbe es zwei Optionen:
    1. Ein Router (also ein Rechner der an zwei Netze angeschlossen ist) sendet automatisch empfangene Magic packets auch in seinem anderen Netz weiter.
    2. Die Magic-Packets werden in andere Pakete (z.B. IP-Pakete auf Layer 3) gekapselt und werden bei der Ankunft an alle angeschlossenen Layer 2-Netze gesendet.


    Extra Hardware wäre nicht nötig. Das wäre eigentlich nur ein Dienst auf dem Pi.

    Aber konkreteres kann ich dir ad-hoc nicht anbieten - da bräuchte es wohl etwas Google-Arbeit.

    Aber im Grunde ist es durchaus möglich WoL-Pakete netzübergreifend zu senden und dann könntest du auch direkt ein Windows-Tool hierfür nehmen anstatt die SSH-Geschichte.

  • Vielen Dank nochmal für Deine / Eure Hilfe.

    Im Scite werden mir wenn ich das Script ausführe die Infos siehe folgend angezeigt: Kann ich das ignorieren?

    sudo etherwake xx:xx:xx:xx:xx:xx

    ESC]0;swiffer@raspberrypi: ~BELESC[01;32mswiffer@raspberrypiESC[00m:[01;34m~ $ESC[00m

    ESC]0;swiffer@raspberrypi: ~BELESC[01;32mswiffer@raspberrypiESC[00m:[01;34m~ $ESC[00m

    Ich habe jetzt aus einer Antwort von SOLVE-SMART in einem anderen Thema einen Countdowntimer eingebaut. Dieser sollte am Anfang vom Script starten (optische Bestätigung das script läuft) und in der Zeit vom Countdown können dann die Befehle an den Pi zum aufwachen gesendet werden.

    Logischerweise läuft das Script aber erst nach Ablauf des Timers weiter. Wie könnte ich das lösen um den Pi wärend der Timer läuft aufzuwecken?


     

    Gibt es eine Möglichkeit die Remotedesktopverbindung Software (die Software selbst nicht den Ziel PC) ebenfalls dirket anzusprechen? Ich habe es erstmal so gelöst:

    Run("mstsc.exe", "", @SW_SHOWDEFAULT)

    WinWaitActive ("Remotedesktopverbindung")

    ControlSend ("Remotedesktopverbindung", "", "Edit1", "192.168.160.20")

    Sleep (100)

    ControlSend ("Remotedesktopverbindung", "", "Edit1", "{Enter}")

    Meine Suche hat nichts ergeben. Das Meiste zu dem Thema dreht sich um Befehle auf dem Ziel PC ausführen. Ich müsste aber Befehle an RDP senden.

    Sauber bleiben.

  • Musst Du mal nach "mstsc commandline parameter" suchen...

    Man findet z.B. folgendes Vorgehen aus der Kommandozeile und damit sollte es auch unter AutoIt klappen:

    Code
    # Anmeldung generieren
    cmdkey /generic:"<servername>" /user:"<username>" /pass:"<password>"
    
    # Verbindung zum Server mit den vorherigen Anmeldung (user/pass geht mit mstsc nicht)
    mstsc /v:<servername>
    
    # Löschen der Anmeldung
    cmdkey /delete:TERMSRV/<servername>

    Zur Nutzung dieses Forum's, ist ein Übersetzer für folgende Begriffe unerlässlich:

    "On-Bort, weier, verscheiden, schädliges, Butten steyling, näckstet, Parr, Porblem, scripe, Kompletenz, harken, manuel zu extramieren, geckukt, würglich, excell, acces oder Compilevorgeng"

    Einmal editiert, zuletzt von Micha_he (29. Dezember 2022 um 07:30)

  • Danke Micha_he

    AutoIt
    Run("mstsc.exe /v:192.168.160.20", "", @SW_SHOWDEFAULT)

    funktioniert bestens.

    Bleiben noch die Fragen aus #14:

    1. Im Scite werden mir wenn ich das Script ausführe die Infos siehe folgend angezeigt: Kann/sollte ich das ignorieren?

    2. Countdowntimer laufen lassen wärend Putty öffnet usw.

    Ich bastel mal noch ein wenig, vielleicht gelingt es mir ja.

    Sauber bleiben.

  • Hi Swiffer,

    keine Ahnung wo du diesen "Countdowntimer" herausgekramt hast, kann mich nicht erinnern, ist aber auch egal. Wenn du eine visuelle Darstellung haben möchtest, dass das Skript läuft (wie du schreibst) und während dessen etwas anderes passieren soll, dann ist AdlibRegister dein Stichwort 😀 .

    Hier mal ein Beispiel ohne GUI, einfach nur mit einem Tooltip:

    Die Funktion _DoSomethingDuringTheCountdownIsShown() dient nur der Anschauung. Also es wird einfach der Tooltip aktualisiert angezeigt und während dessen kann dein Skript alles andere tun. Sobald der Countdown zu Ende ist (wenn er 0 ist), wird diese Funktion nicht mehr aufgerufen.

    Viele Grüße
    Sven

  • Hallo SOLVE-SMART . Gute Sache, Danke Dir.

    Sobald Func _DoSomethingDuringTheCountdownIsShown() durch ist schliesst sich der Tooltip (und das script) auch wenn dieser zum Beispiel erst bei 7 Sekunden ist. Gut wäre wenn er bis zum Ende sichtbar bleiben und weiterzählen würde auch wenn die andere "Aufgabe" abgeschlossen ist.

    Wie verhindere ich dass der Tooltip schliesst wenn Func _DoSomethingDuringTheCountdownIsShown() durch ist?

    Ich habe es jetzt provisorisch mit Sleep (13000) gelöst so passt es etwa mit dem 18000 Countdown. Aber schön ist das nicht unbedingt.

    Mit Sleep ($iCountdown) ist die Zeit komischerweise viel zu kurz.

    Edit:

    Ich habe gerade gemerkt dass ich den Sleep von Func _DoSomethingDuringTheCountdownIsShown() viel zu lang machen kann und es über ein Exit bei If $iCountdown == 0 Then schliessen kann.

    Ist also erledigt :) Eine gute Nacht wünsche ich.

    Sauber bleiben.

    Einmal editiert, zuletzt von Swiffer (29. Dezember 2022 um 22:14)

  • Hi Swiffer ,

    eigentlich war die Funktion nur zu Anschauung. Also du solltest gar kein Sleep() einbauen müssen oder sollen. Denn die eigentliche Funktion _ShowRefreshedToolTip() läuft parallel zu deinen anderen Schritten in deinem Skript. Ich hatte verstanden, du willst nur den "Countdown" angezeigt bekommen und während dessen soll putty aktiv werden. Genau dies macht die "Countdown"-Funktion. Mehr nicht. Immer wenn du Sleep() nutzt, wird die Ausführung des Skripts kurz pausiert - daher stattdessen der Ansatz mit AdlibRegister().

    Wenn du deinen bisherigen Code nochmal senden möchtest und an Hand dessen deinen Stand nochmal erläuterst, dann wird sicher klarer ob noch was offen ist oder nicht.
    Ansonsten, ja, ebenfalls eine gute Nacht 😀 .

    Viele Grüße
    Sven