none
Simulation eines Maus-Clicks RRS feed

  • Frage

  • Ein JavaScript-Fenster im Browser erfordert einen Mausklick (linke Maustaste) auf eine OK-Schaltfäche. Weiß jemand wie sich Derartiges bewerkstelligen ließe ?

    Dienstag, 23. August 2016 06:15

Antworten

  • @Stefan: Ja das WASP-Projekt ist schon etwas älter. Ich hatte dir allerdings schon eine von mir geschriebene Lösung geschickt.

    Schreib mal folgendes in dein Script:

    Add-Type -AssemblyName System.Windows.Forms
    
    function Click-MouseButton{
    param(
    [string]$Button)
    
        $signature=@' 
          [DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
          public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);
    '@ 
    
        $SendMouseClick = Add-Type -memberDefinition $signature -name "Win32MouseEventNew" -namespace Win32Functions -passThru 
        if($Button -eq "left")
        {
            $SendMouseClick::mouse_event(0x00000002, 0, 0, 0, 0);
            $SendMouseClick::mouse_event(0x00000004, 0, 0, 0, 0);
        }
        if($Button -eq "right")
        {
            $SendMouseClick::mouse_event(0x00000008, 0, 0, 0, 0);
            $SendMouseClick::mouse_event(0x00000010, 0, 0, 0, 0);
        }
        if($Button -eq "middle")
        {
            $SendMouseClick::mouse_event(0x00000020, 0, 0, 0, 0);
            $SendMouseClick::mouse_event(0x00000040, 0, 0, 0, 0);
        }
    
    }

    "Add-Type -AssemblyName System.Windows.Forms" musst du einmal in deiner PS ausführen.

    Nun kannst du noch "[Windows.Forms.Cursor]::Position" in die PS eingeben und du erhälst die Koordinaten des Mauszeigers - aufjedenfall besser und einfacher als Paint zu nutzen.

    Jetzt führst du folgendes aus: [Windows.Forms.Cursor]::Position = "X-Koordinate,Y-Koordinate"

    Die Maus bewegt sich dann automatisch auf die Position. Und dann führst du noch meine Funktion aus:

    Click-MouseButton left

    Der Linksklick wird ausgeführt.


    Mittwoch, 24. August 2016 09:04

Alle Antworten

  • http://wasp.codeplex.com/

    Da findest du sowas schönes wie Send-Click oder Send-Key.

    Dienstag, 23. August 2016 07:18
  • Hi Stefan,

    ich habe mir dazu damals eine Funktion erstellt.

    Als erstes benötigst du folgende Assembly:

    Add-Type -AssemblyName System.Windows.Forms

    Dann habe ich folgende Funktion erstellt:

    function Click-MouseButton{
    param(
    [string]$Button)
    
        $signature=@' 
          [DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
          public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);
    '@ 
    
        $SendMouseClick = Add-Type -memberDefinition $signature -name "Win32MouseEventNew" -namespace Win32Functions -passThru 
        if($Button -eq "left")
        {
            $SendMouseClick::mouse_event(0x00000002, 0, 0, 0, 0);
            $SendMouseClick::mouse_event(0x00000004, 0, 0, 0, 0);
        }
        if($Button -eq "right")
        {
            $SendMouseClick::mouse_event(0x00000008, 0, 0, 0, 0);
            $SendMouseClick::mouse_event(0x00000010, 0, 0, 0, 0);
        }
        if($Button -eq "middle")
        {
            $SendMouseClick::mouse_event(0x00000020, 0, 0, 0, 0);
            $SendMouseClick::mouse_event(0x00000040, 0, 0, 0, 0);
        }
    
    }

    Nun gehst du mit dem Mauszeiger über den "OK-Button" und gibst den Befehl "[Windows.Forms.Cursor]::Position". Damit erhälst du die Koordinaten von deinem Mauszeiger. Sind die Koordinaten z.b. X=707    Y=1129, dann gibst du folgendes ein:

    #Mauszeiger über den OK-Button bringen

    [Windows.Forms.Cursor]::Position = "707,1129"

    #Linksklick ausführen

    Click-MouseButton left

    Falls du noch weitere Fragen hast, stell Sie einfach :)

    Liebe Grüße, Lars

    /e: Falls du den IE benutzt, kannst du auch auf alle Objekte drauf zugreifen - z.B. Formulare füllen, Buttons klicken usw.. Wobei ich hier allerdings nicht genau weiß, ob das auch bei einem PopUp v. JavaScript funktioniert.

    Dienstag, 23. August 2016 08:15
  • Lars, bitte keine eigenen Antworten "als Antwort" vorschlagen.

    Das ist ein schönes kurzes Script zur Maussteuerung, aber ich denke für Webseiten nicht geeignet.
    Allein schon da sich auf den allermeisten Webseiten die Position und Größe der Elemente je nach Bildschirmauflösung, Fensterposition, Fenstergröße, Browser-Typ und Browserskalierung verändert. Du kannst also nie wirklich sicher sein, schon gar nicht auf den Pixel genau, an welcher Position sich dein Button befindet.
     
    Stefan, du hast leider nicht genauer erwähnt was du machen willst. Warum soll der Button gedrückt werden? Was soll danach passieren? Je nachdem gibt es noch diverse Möglichkeiten:
    Z.b. die Seite direkt in einem IE-Objekt aufzurufen und dann den Button zu drücken: LINK 
    Bei Spezialfällen kannst du das Modul Autobrowse probieren.

    Und wenn es bei der ganzen Aktion am Ende darum geht etwas runterzuladen oder ähnliches, kannst du den Click vielleicht komplett umgehen, indem du die Seite mit invoke-webrequest auswertest...

     
    Grüße, Denniver




    Blog: http://bytecookie.wordpress.com

    Neu: Powershell Code Manager v5 ! Link
    (Schneller, besser + komfortabler scripten.)

    Hilf mit und markiere hilfreiche Beiträge mit dem "Abstimmen"-Button (links) und Beiträge die eine Frage von dir beantwortet haben, als "Antwort" (unten).
    Warum das Ganze? Hier gibts die Antwort.



    Dienstag, 23. August 2016 12:56
    Moderator
  • @psott: Danke für die Info - der Einfachheit halber versuchte ich zunächst im Taschenrechner einen Klick auf die 7 zu simulieren:

    calc
    Select-Window calc | Send-Click 40 190

    - funktioniert leider nicht. Werde aus der Syntax auf Anhieb nicht schlau ....

    SYNTAX
    Send-Click [[-Left] <Int32>] [[-Top] <Int32>] [[-Button] <MouseButton>] [-Window] <Win
    dowHandle[]> [-AltButton] [-ShiftButton] [-ControlButton] [-WinButton] [-DoubleClick]
    [-ForceClient] [-Passthru] [-Verbose] [-Debug] [-ErrorAction <ActionPreference>] [-War
    ningAction <ActionPreference>] [-ErrorVariable <String>] [-WarningVariable <String>] [
    -OutVariable <String>] [-OutBuffer <Int32>] [-WhatIf] [-Confirm]


    • Bearbeitet Stefan Karg Dienstag, 23. August 2016 19:12
    Dienstag, 23. August 2016 18:57
  • Hi Denniver,

    das tut mir leid, das wusste ich leider nicht.

    @Stefan: Probier es mal damit:

    Send-Click -Left 40 -Top 190 -Window calc -Button left

    Ich gebe allerdings Denniver vollkommen Recht, je nach "Bildschirmauflösung, Fensterposition, Fenstergröße, Browser-Typ und Browserskalierung" wird die Position der Koordinate immer anders sein. Also wird dein Script auch dann nur auf deinem Rechner laufen.

    Das du auf die Objekte im IE drauf zugreifen kannst habe ich ja auch vorgeschlagen, allerdings ist es natürlich fraglich wie es da mit JavaScript Buttons aussieht, da das ganze ja nicht als HTML hinterlegt ist - <form><button type=button id="berechnen"></form>    ist dann nicht gegeben.                            Vielleicht hat Denniver ja da noch eine Idee?

    Eine Alternative aber auch immer noch keine optimale Lösung wäre, das du das Browserfenster in den Vordergrund holst und ein Tastaturanschlag losschickst. Z.B. Enter oder Space. Meist werden die Buttons auf einer Webseite dadurch ausgelöst.

    #Assemblys laden
    $sig = '[DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);'
    Add-Type -MemberDefinition $sig -name NativeMethods -namespace Win32
    Add-Type -AssemblyName System.Windows.Forms
    
    #ID des Prozesses in eine Variable schreiben
    $ProcessID = @(Get-Process Notepad++)[0].MainWindowHandle
    
    #Notepad++ anhand der ProcessID maximieren - ist dann das aktive Fenster
    [Win32.NativeMethods]::ShowWindowAsync($ProcessID, 3)
    
    #Tastaturanschlag Enter - lässt sich auch in {Space} oder Text ändern
    [System.Windows.Forms.SendKeys]::SendWait("{Enter}")
    
    
    <#
            "Hide"               {$WinStateInt =  0}
            "Normal"             {$WinStateInt =  1}
            "ShowMinimized"      {$WinStateInt =  2}
            "Maximize"           {$WinStateInt =  3}    Im Beispiel verwendet.
            "ShowNoActivate"     {$WinStateInt =  4}
            "Show"               {$WinStateInt =  5}
            "Minimize"           {$WinStateInt =  6}
            "ShowMinNoActive"    {$WinStateInt =  7}
            "ShowNA"             {$WinStateInt =  8}
            "Restore"            {$WinStateInt =  9}
            "ShowDefault"        {$WinStateInt = 10}
            "ForceMinimize"      {$WinStateInt = 11}
    #>

    => Ich maximiere hier das Fenster Notepad++, welches dann mein aktives Fenster ist und sende dann den Tastaturanschlag Enter raus.

    Vielleicht hilft es dir ja weiter. Es ist zwar nicht die beste Lösung, aber immerhin hättest du dann nicht die Probleme mit den festen Koordinaten.

    LG, Lars


    • Bearbeitet Lars1335 Mittwoch, 24. August 2016 06:44 Korrektur
    Mittwoch, 24. August 2016 06:42
  • Außerhalb der PowerShell könntest du es mit SIKULI lösen. Das ist ein Projekt, bei dem man mit Bildern programmieren kann. Man legt in den Code ein Bild von dem Objekt, auf das geklickt werden soll, und das System sucht nach diesem Bild auf dem Bildschirm. Ich habe damit schon einige Web-Anwendungen automatisiert.
    Mittwoch, 24. August 2016 06:43
  • @Lars:
    Send-Click -Left 40 -Top 190 -Window calc -Button left
    führt zur Fehlermeldung:

    Send-Click : Der Parameter "Window" kann nicht gebunden werden. Der Wert "calc" vom Typ "System.String" kann nicht in den Typ "Huddled.Wasp.WindowHandle" konvertiert werden.

    Select-Window calc | Send-Click -Left 40 -Top 190 -Button left

    läuft ohne Fehler durch, ein Klick auf die 7 erfolgt allerdings nicht. Die Koordinaten habe ich mit einem ScreenShot und Paint ermittelt:

    7

    @Denniver:

    Stefan, du hast leider nicht genauer erwähnt was du machen willst. Warum
     soll der Button gedrückt werden? Was soll danach passieren? 

    Nach Ausfüllen eines HTML-Formulars (funktioniert ausgezeichnet mit Send-Keys von WASP) öffnet sich ein JavaScript-Fenster. Ein Mausklick auf eine OK-Schaltfläche ist nötig, Send-Keys versagt hier. Die Koordinaten der Schaltfläche könnte ich möglicherweise mit der Screenshot/Paint - Methode ermitteln. Die Anpassung an die Bildschirmauflösung des Zielrechners wäre unproblemtisch, da es sich um eine Stand-Alone-Anwendung handelt.

    Das WASP-Projekt scheint inzwischen eingeschlafen zu sein. Unter Some Usage Examples   finden sich Beispiele:

    ## NOTE: 0, 0 is the resize corner, so you need to specify X,Y coordinates for the click:
    Select-Window devenv | Select-ChildWindow | Send-Click 10 10 -Double 

    Wie genau Send-Click funktioniert hat sich mir noch nicht erschlossen ...



    Mittwoch, 24. August 2016 08:02
  • Falls der OK-Button den Fokus hat, kannst du auch einfach über die SendKeys Methode des WScript.Shell COM-Objektes die ENTER-Taste drücken. Dann musst du dir keine Gedanken mehr über die Position machen. Falls sie nicht den Fokus hat, könntest du auch Pfeiltasten drücken. Letztendlich sollte sich doch eigentlich jeder Button auch nur mit Tastatur-Befehlen drücken lassen.

    https://msdn.microsoft.com/en-us/library/8c6yea83(v=vs.84).aspx

    Mittwoch, 24. August 2016 08:53
  • @Stefan: Ja das WASP-Projekt ist schon etwas älter. Ich hatte dir allerdings schon eine von mir geschriebene Lösung geschickt.

    Schreib mal folgendes in dein Script:

    Add-Type -AssemblyName System.Windows.Forms
    
    function Click-MouseButton{
    param(
    [string]$Button)
    
        $signature=@' 
          [DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
          public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);
    '@ 
    
        $SendMouseClick = Add-Type -memberDefinition $signature -name "Win32MouseEventNew" -namespace Win32Functions -passThru 
        if($Button -eq "left")
        {
            $SendMouseClick::mouse_event(0x00000002, 0, 0, 0, 0);
            $SendMouseClick::mouse_event(0x00000004, 0, 0, 0, 0);
        }
        if($Button -eq "right")
        {
            $SendMouseClick::mouse_event(0x00000008, 0, 0, 0, 0);
            $SendMouseClick::mouse_event(0x00000010, 0, 0, 0, 0);
        }
        if($Button -eq "middle")
        {
            $SendMouseClick::mouse_event(0x00000020, 0, 0, 0, 0);
            $SendMouseClick::mouse_event(0x00000040, 0, 0, 0, 0);
        }
    
    }

    "Add-Type -AssemblyName System.Windows.Forms" musst du einmal in deiner PS ausführen.

    Nun kannst du noch "[Windows.Forms.Cursor]::Position" in die PS eingeben und du erhälst die Koordinaten des Mauszeigers - aufjedenfall besser und einfacher als Paint zu nutzen.

    Jetzt führst du folgendes aus: [Windows.Forms.Cursor]::Position = "X-Koordinate,Y-Koordinate"

    Die Maus bewegt sich dann automatisch auf die Position. Und dann führst du noch meine Funktion aus:

    Click-MouseButton left

    Der Linksklick wird ausgeführt.


    Mittwoch, 24. August 2016 09:04
  • Um eine konkrete Lösung vorzuschlagen müsstest du die Adresse des Formulars das du ausfüllen willst posten.

    Grüße, Denniver


    Blog: http://bytecookie.wordpress.com

    Neu: Powershell Code Manager v5 ! Link
    (Schneller, besser + komfortabler scripten.)

    Hilf mit und markiere hilfreiche Beiträge mit dem "Abstimmen"-Button (links) und Beiträge die eine Frage von dir beantwortet haben, als "Antwort" (unten).
    Warum das Ganze? Hier gibts die Antwort.



    Mittwoch, 24. August 2016 12:20
    Moderator
  • @Denniver:
    das Formular liegt im Kundenbereich von wikifolio.com  - die Zugangsdaten würde ich nicht gern im Forum posten. Personal Message gibt es in diesem Forum scheinbar nicht - oder ?

    @Lars: Dein Skript funktioniert ausgezeichnet - Besten Dank !!!

    Beste Grüße
    Stefan

    Freitag, 26. August 2016 06:52
  • Nein, kein PM hier.
    Wenn du mit der Lösung zufrieden bist, markiere bitte noch die Posts als Antwort die für spätere Leser die möglichen Lösungen aufzeigen.

     Grüße, D


    Blog: http://bytecookie.wordpress.com

    Neu: Powershell Code Manager v5 ! Link
    (Schneller, besser + komfortabler scripten.)

    Hilf mit und markiere hilfreiche Beiträge mit dem "Abstimmen"-Button (links) und Beiträge die eine Frage von dir beantwortet haben, als "Antwort" (unten).
    Warum das Ganze? Hier gibts die Antwort.



    Samstag, 27. August 2016 11:10
    Moderator
  • Falls du noch weitere Fragen hast, stell Sie einfach :)

    Mein Powershell-Skript sendet diverse Tastatureingaben und Mausklicks an das Web-Formular.
    Folgende Fragen drängen sich auf:

    1. Gibt es eine Funktion, die den aktuellen Fokus des Controls des Web-Formulars zurückgibt (vielleicht ähnlich wie [Windows.Forms.Cursor]::Position ) ?
    2. Analog gibt es vielleicht eine Funktion mit der sich der Fokus auf das erste Control setzen läßt ?

    Beste Grüße
    Stefan

    Donnerstag, 15. September 2016 07:11
  • Lars,

    wenn es um die Simulation von Mausklicks oder Tastatureingaben geht, wäre nach meiner unmassgeblichen Meinung Autoit oder Autohotkey besser geeignet als Powershell. Diese beiden Scriptsprachen sind direkt für solche Einsatzzwecke gemacht. Damit ist es auch möglich, einigermaßen flexibel auf unterschiedliche Position von anzusteuernden Elementen zu reagieren z.B. wegen einer anderen Bildschirmauflösung.

    In deren Foren findet man dann meistens schon tonnenweise ähnliche Anfragen und auch entsprechende Lösungsvorschläge oder -ansätze.


    Grüße - Best regards

    PS:> (79,108,97,102|%{[char]$_})-join''


    • Bearbeitet BOfH-666 Donnerstag, 15. September 2016 10:30
    Donnerstag, 15. September 2016 10:29