You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中替代Java Robot类实现Selenium鼠标可视化移动的方案问询

在C#中替代Java Robot类实现鼠标可视化移动的方案(适配Selenium测试场景)

嘿,我懂你要的是什么——不是Selenium Actions那种后台静默模拟,而是能看到真实鼠标指针跟着测试步骤同步移动的效果,对吧?在C#里确实没有和Java Robot完全对应的内置类,但有几个非常靠谱的方案,刚好能满足你在Rediffmail测试里的需求:依次移动到地址栏、用户名输入框、密码输入框和登录按钮,全程可视化。

方案1:直接调用Windows API(user32.dll)

这是最底层、最灵活的方式,直接通过Win32接口控制系统鼠标,完全能实现你要的可视化移动。你需要先导入user32.dll的相关方法,然后结合Selenium获取页面元素的屏幕坐标,再驱动鼠标移动过去。

代码示例:

首先,定义Win32 API调用:

using System.Runtime.InteropServices;

public class MouseController
{
    [DllImport("user32.dll")]
    private static extern bool SetCursorPos(int x, int y);

    [DllImport("user32.dll")]
    private static extern bool GetCursorPos(out POINT lpPoint);

    public struct POINT
    {
        public int X;
        public int Y;
    }

    // 移动鼠标到指定屏幕坐标
    public static void MoveMouseTo(int x, int y)
    {
        SetCursorPos(x, y);
    }

    // 获取当前鼠标位置
    public static POINT GetCurrentMousePosition()
    {
        GetCursorPos(out POINT point);
        return point;
    }
}

然后结合Selenium实现你的Rediffmail测试流程:

using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Threading;

class Program
{
    static void Main(string[] args)
    {
        using (var driver = new ChromeDriver())
        {
            driver.Manage().Window.Maximize();
            driver.Navigate().GoToUrl("https://www.rediffmail.com/");

            // 1. 移动到地址栏
            var addressBar = driver.FindElement(By.TagName("input")); // 可根据实际浏览器调整定位器
            var addressBarLocation = addressBar.Location;
            var addressBarSize = addressBar.Size;
            // 计算元素中心的屏幕坐标(窗口最大化时直接用元素Location即可)
            int targetX = addressBarLocation.X + addressBarSize.Width / 2;
            int targetY = addressBarLocation.Y + addressBarSize.Height / 2;
            MouseController.MoveMouseTo(targetX, targetY);
            Thread.Sleep(1000); // 停留1秒让移动效果可见

            // 2. 移动到用户名输入框
            var usernameField = driver.FindElement(By.Id("login1"));
            int usernameX = usernameField.Location.X + usernameField.Size.Width / 2;
            int usernameY = usernameField.Location.Y + usernameField.Size.Height / 2;
            MouseController.MoveMouseTo(usernameX, usernameY);
            Thread.Sleep(1000);

            // 3. 移动到密码输入框
            var passwordField = driver.FindElement(By.Id("password"));
            int passwordX = passwordField.Location.X + passwordField.Size.Width / 2;
            int passwordY = passwordField.Location.Y + passwordField.Size.Height / 2;
            MouseController.MoveMouseTo(passwordX, passwordY);
            Thread.Sleep(1000);

            // 4. 移动到登录按钮
            var loginButton = driver.FindElement(By.Name("proceed"));
            int loginX = loginButton.Location.X + loginButton.Size.Width / 2;
            int loginY = loginButton.Location.Y + loginButton.Size.Height / 2;
            MouseController.MoveMouseTo(loginX, loginY);
            Thread.Sleep(1000);
        }
    }
}

方案2:使用InputSimulator库(封装好的便捷方案)

如果你不想自己写Win32 API的调用,可以用InputSimulator这个NuGet包,它已经封装了所有输入设备的模拟操作,使用起来更简洁。

步骤:

  1. 在NuGet包管理器中安装InputSimulator(或者用命令:Install-Package InputSimulator)
  2. 编写测试代码:
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using WindowsInput;
using System.Threading;
using System.Drawing;

class Program
{
    static void Main(string[] args)
    {
        var inputSimulator = new InputSimulator();
        using (var driver = new ChromeDriver())
        {
            driver.Manage().Window.Maximize();
            driver.Navigate().GoToUrl("https://www.rediffmail.com/");

            // 移动到地址栏
            var addressBar = driver.FindElement(By.TagName("input"));
            var addressBarCenter = new Point(
                addressBar.Location.X + addressBar.Size.Width / 2,
                addressBar.Location.Y + addressBar.Size.Height / 2);
            inputSimulator.Mouse.MoveMouseTo(addressBarCenter.X, addressBarCenter.Y);
            Thread.Sleep(1000);

            // 移动到用户名输入框
            var usernameField = driver.FindElement(By.Id("login1"));
            var usernameCenter = new Point(
                usernameField.Location.X + usernameField.Size.Width / 2,
                usernameField.Location.Y + usernameField.Size.Height / 2);
            inputSimulator.Mouse.MoveMouseTo(usernameCenter.X, usernameCenter.Y);
            Thread.Sleep(1000);

            // 移动到密码输入框
            var passwordField = driver.FindElement(By.Id("password"));
            var passwordCenter = new Point(
                passwordField.Location.X + passwordField.Size.Width / 2,
                passwordField.Location.Y + passwordField.Size.Height / 2);
            inputSimulator.Mouse.MoveMouseTo(passwordCenter.X, passwordCenter.Y);
            Thread.Sleep(1000);

            // 移动到登录按钮
            var loginButton = driver.FindElement(By.Name("proceed"));
            var loginCenter = new Point(
                loginButton.Location.X + loginButton.Size.Width / 2,
                loginButton.Location.Y + loginButton.Size.Height / 2);
            inputSimulator.Mouse.MoveMouseTo(loginCenter.X, loginCenter.Y);
            Thread.Sleep(1000);
        }
    }
}

关键注意事项

  • 窗口前置:确保浏览器窗口处于前台,否则鼠标移动的坐标可能会偏移(可额外用Win32 API的SetForegroundWindow方法强制前置窗口)
  • 坐标计算:如果浏览器没有最大化,需要把浏览器窗口的屏幕位置加到元素的Location上,才能得到正确的全局屏幕坐标
  • 延迟设置:用Thread.Sleep或者Task.Delay添加间隔,让鼠标移动的过程清晰可见,否则会瞬间跳转到目标位置

内容的提问来源于stack exchange,提问作者Jessica David

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:25:21