CefSharp / WinForms - automatisierte Mausklicks - ein Klick fehlt



  • Hallo,
    das Chromium Dingen wird an das WinForm Dingen angedockt.

     public void InitializeChromium()
            {
                CefSettings settings = new CefSettings();
                // Initialize cef with the provided settings
                Cef.Initialize(settings);
                // Create a browser component
                chromeBrowser = new ChromiumWebBrowser("http://google.de");
                // Add it to the form and fill it to the form window.
                chromeBrowser.LoadingStateChanged += OnLoadingStateChanged;
                this.Controls.Add(chromeBrowser);
                chromeBrowser.Dock = DockStyle.Fill;
            }
    

    Wenn die Google-Webseite geladen ist, sollen zwei Klicks mit der rechten Maustaste automatisiert ausgelöst werden. Es wird nur einmal geklickt, warum?
    (Ach ja und der Mauscursor bewegt sich auch keinen Millimeter, f**k.)

            private void OnLoadingStateChanged(object sender, LoadingStateChangedEventArgs args)
            {
                if (!args.IsLoading)
                {
                    // Page has finished loading, do whatever you want here
                    
                    int x = 300, y = 300;
    
                    chromeBrowser.GetBrowser().GetHost().SendMouseMoveEvent(x, y, false, CefEventFlags.None);
                    chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, false, 1, CefEventFlags.RightMouseButton);
                    Thread.Sleep(100);
                    chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, true, 1, CefEventFlags.RightMouseButton);
    
    
                    x -= 100; y -= 100;
                    Thread.Sleep(2000);
    
                    chromeBrowser.GetBrowser().GetHost().SendMouseMoveEvent(x, y, false, CefEventFlags.None);
                    chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, false, 1, CefEventFlags.RightMouseButton);
                    Thread.Sleep(100);
                    chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, true, 1, CefEventFlags.RightMouseButton);
    
                    return;
    }
    

  • Administrator

    @bruder Meine Vermutung würde hier sein, dass die Events sich überlappen. Wenn du Thread.Sleep aufrufst, legst du den Main-Thread schlafen, wodurch das ganze Programm einfriert und keine Events verarbeitet werden.

    Ich würde mal das Thread.Sleep(2000) durch ein await Task.Delay(2000) ersetzen und schauen, ob das reicht. Dazu muss dann die Funktion natürlich mit async markiert werden. Falls du dich mit async und await noch nicht auskennst, dann gibt es in der MSDN eine gute Dokumentation dazu.



  • Es wird leider nur ein Klick ausgelöst.

    private async void OnLoadingStateChanged(object sender, LoadingStateChangedEventArgs args)
            {
                if (!args.IsLoading)
                {
                    int x = 300, y = 300;
                    await Task.Run(() =>
                    {
                        chromeBrowser.GetBrowser().GetHost().SendMouseMoveEvent(x, y, true, CefEventFlags.None);
                        chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, false, 1, CefEventFlags.RightMouseButton);
                        Task.Delay(100);
                        chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, true, 1, CefEventFlags.RightMouseButton);
    
    
                        x -= 30; y -= 30;
    
                        Task.Delay(2000);
                        chromeBrowser.GetBrowser().GetHost().SendMouseMoveEvent(x, y, true, CefEventFlags.None);
                        chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, false, 1, CefEventFlags.RightMouseButton);
                        Task.Delay(100);
                        chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, true, 1, CefEventFlags.RightMouseButton);
    
                        x -= 30; y -= 30;
    
                        Task.Delay(2000);
                        chromeBrowser.GetBrowser().GetHost().SendMouseMoveEvent(x, y, true, CefEventFlags.None);
                        chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, false, 1, CefEventFlags.RightMouseButton);
                        Task.Delay(100);
                        chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, true, 1, CefEventFlags.RightMouseButton);
                    });
                }
            }
    


  • Du mußt ja auch await Task.Delay(100); benutzen (sonst ist es sinnfrei, s.a. C# Async Antipatterns).



  • @Th69 sagte in CefSharp / WinForms - automatisierte Mausklicks - ein Klick fehlt:

    Du mußt ja auch await Task.Delay(100); benutzen (sonst ist es sinnfrei, s.a. C# Async Antipatterns).

    Dann bekomme ich eine Fehlermeldung:

    Der await-Operator kann nur mit Async-Lambdaausdruck verwendet werden. Markieren Sie ggf. Lambdaausdruck mit dem async -Modifizierer.
    

    Edit: Klar habe ich gegoogelt wie man das mit dem async-Modifizierer markieren könnte aber das gibt dann noch mehr Fehler.



  • Neuster Stand, dasselbe Ergebnis, nur ein Rechtsklick ist zu sehen:

    private async void OnLoadingStateChanged(object sender, LoadingStateChangedEventArgs args)
            {
                if (!args.IsLoading)
                {
    
                    int x = 300, y = 300;
                    await Task.Run(async () =>
                    {
                        chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, false, 1, CefEventFlags.RightMouseButton);
                        await Task.Delay(200);
                        chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, true, 1, CefEventFlags.RightMouseButton);
                        await Task.Delay(1000);
    
                        x -= 50; y -= 50;
                        chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, false, 1, CefEventFlags.RightMouseButton);
                        await Task.Delay(200);
                        chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, true, 1, CefEventFlags.RightMouseButton);
                        await Task.Delay(1000);
    
                        x -= 50; y -= 50;
                        chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, false, 1, CefEventFlags.RightMouseButton);
                        await Task.Delay(200);
                        chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, true, 1, CefEventFlags.RightMouseButton);
                        await Task.Delay(1000);
                    });
    
                }
            }
    


  • push?



  • hast du es mal ohne mouseUp probiert? evtl. falsche koordinaten?



  • @Wade1234 Dann gibt's nicht einmal den einen Rechtsklick. Die Koordinaten sind okay.



  • also auf https://stackoverflow.com/questions/31135070/cef-simulate-mousedown-and-keysend (übrigens das 3. ergebnis bei google -> sendmouseclickevent) gibt es ein beispiel mit CefEventFlags.None als letzten parameter. angeblich funktioniert das. probiers halt mal, wenns nicht funktioniert, kann ich dir auch nicht weiter helfen.



  • @Wade1234 Danke, kenn ich schon, funzt net.



  • @Wade1234 Okay, danke trotzdem 🙂



  • @bruder sagte in CefSharp / WinForms - automatisierte Mausklicks - ein Klick fehlt:

    int x = 300, y = 300;

    Verschieb' das mal in dein Lambda rein. Das ist ja völlig sinnfrei das ausserhalb zu haben. Plus du solltest sicherstellen dass du das ganze nur 1x startest - nicht dass OnLoadingStateChanged mehrfach mit args.IsLoading == false aufgerufen wird und das irgend ein unerwartetes Verhalten erzeugt.



  • @hustbaer Aye aye Sir!

    private async Task<int> Klick()
            {
                    await Task.Run(async () =>
                    {
                        int x = 300, y = 300;
                        
                        chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, false, 1, CefEventFlags.RightMouseButton);
                        await Task.Delay(100);
                        chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, true, 1, CefEventFlags.RightMouseButton);
                        await Task.Delay(1000);
    
                        x -= 50; y -= 50;
    
                        chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, false, 1, CefEventFlags.RightMouseButton);
                        await Task.Delay(100);
                        chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, true, 1, CefEventFlags.RightMouseButton);
                        await Task.Delay(1000);
    
                        x -= 50; y -= 50;
    
                        chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, false, 1, CefEventFlags.RightMouseButton);
                        await Task.Delay(100);
                        chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, true, 1, CefEventFlags.RightMouseButton);
                        await Task.Delay(1000);
                    });
                return 1;
            }
    
            private async void button1_Click(object sender, EventArgs e)
            {
                await Klick();
            }
    

    Funzt net. Nach wie vor wird nur einmal geklickt.


  • Administrator

    @bruder Nimm bitte das Task.Run da raus. Dadurch läuft die Sache in einem anderen Thread. Ich weiss nicht mal, ob die API Thread-Safe ist.

    private async Task Klick()
    {
        int x = 300, y = 300;
        
        chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, false, 1, CefEventFlags.RightMouseButton);
        await Task.Delay(100);
        chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, true, 1, CefEventFlags.RightMouseButton);
        await Task.Delay(1000);
    
        x -= 50; y -= 50;
    
        chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, false, 1, CefEventFlags.RightMouseButton);
        await Task.Delay(100);
        chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, true, 1, CefEventFlags.RightMouseButton);
        await Task.Delay(1000);
    
        x -= 50; y -= 50;
    
        chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, false, 1, CefEventFlags.RightMouseButton);
        await Task.Delay(100);
        chromeBrowser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, true, 1, CefEventFlags.RightMouseButton);
        await Task.Delay(1000);
    }
    

    Aber ich vermute, dass es auch so nicht funktionieren wird. Meine Hilfe beruhte nur auf der Erfahrung mit WinForms. Ich kenne mich ansonsten mit CefSharp leider nicht aus.



  • @Dravere sagte in CefSharp / WinForms - automatisierte Mausklicks - ein Klick fehlt:

    Aber ich vermute, dass es auch so nicht funktionieren wird.

    Da hast du leider Recht.


Log in to reply