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

Windows弹窗中Selenium+C#上传文件:RDC锁定后SendKeys失效求替代方案

Windows环境下Selenium文件上传的替代方案(解决RDC锁定后SendKeys失效问题)

1. 直接操作页面文件输入元素(最优方案)

很多文件上传功能背后都对应一个隐藏的<input type="file">元素,无需触发Windows弹窗,直接给这个元素发送文件路径即可,完全绕开系统弹窗的限制,RDC锁定后也不受影响——因为这是浏览器层面的交互,不依赖系统模拟输入。

C#代码示例:

// 用CSS选择器定位文件输入元素(无需ID/Xpath)
IWebElement fileInput = driver.FindElement(By.CssSelector("input[type='file']"));
// 直接传入文件完整路径
fileInput.SendKeys(@"C:\Documents\example.pdf");

如果元素是隐藏的,可以先通过JS显示它再操作:

IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
js.ExecuteScript("arguments[0].style.display = 'block';", fileInput);
fileInput.SendKeys(@"C:\Documents\example.pdf");

2. 通过Windows API直接操作上传弹窗

如果必须处理Windows原生弹窗,可以调用user32.dll的API查找弹窗句柄,直接和控件交互,不依赖键盘模拟,RDC锁定后依然有效。

C#代码示例:

首先引入必要的DllImport:

using System.Runtime.InteropServices;

public static class FileUploadHandler
{
    [DllImport("user32.dll", SetLastError = true)]
    private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll", SetLastError = true)]
    private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern bool SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, string lParam);

    private const uint WM_SETTEXT = 0x000C;
    private const uint BM_CLICK = 0x00F5;

    public static void UploadFile(string filePath)
    {
        // 等待弹窗加载(可根据实际情况调整延迟)
        System.Threading.Thread.Sleep(1500);

        // 查找上传弹窗句柄(标题为"打开",根据系统语言调整)
        IntPtr dialogHandle = FindWindow("#32770", "打开");
        if (dialogHandle == IntPtr.Zero)
            throw new InvalidOperationException("未找到文件上传弹窗");

        // 定位输入框控件(类名为Edit)
        IntPtr inputBoxHandle = FindWindowEx(dialogHandle, IntPtr.Zero, "Edit", null);
        if (inputBoxHandle != IntPtr.Zero)
        {
            SendMessage(inputBoxHandle, WM_SETTEXT, IntPtr.Zero, filePath);
            System.Threading.Thread.Sleep(500);
        }

        // 定位"打开"按钮并点击
        IntPtr openBtnHandle = FindWindowEx(dialogHandle, IntPtr.Zero, "Button", "打开");
        if (openBtnHandle != IntPtr.Zero)
            SendMessage(openBtnHandle, BM_CLICK, IntPtr.Zero, null);
    }
}

使用时:

// 点击页面上的上传按钮触发弹窗
driver.FindElement(By.CssSelector("button.upload-trigger")).Click();
// 调用API上传文件
FileUploadHandler.UploadFile(@"C:\Documents\example.pdf");

3. 使用AutoIt进行Windows GUI自动化

AutoIt是专门用于Windows界面自动化的工具,可通过COM接口在C#中调用,定位控件更灵活,适合复杂弹窗场景。

C#代码示例:

  1. 先安装AutoIt并引用AutoItX3Lib组件
  2. 编写上传逻辑:
using AutoItX3Lib;

public void AutoItUploadFile(string filePath)
{
    AutoItX3 autoIt = new AutoItX3();
    // 等待弹窗出现,超时10秒
    autoIt.WinWait("打开", "", 10);
    // 激活弹窗
    autoIt.WinActivate("打开");
    // 给输入框设置文件路径(用控件类名定位)
    autoIt.ControlSetText("打开", "", "[CLASS:Edit; INSTANCE:1]", filePath);
    // 点击"打开"按钮
    autoIt.ControlClick("打开", "", "[CLASS:Button; TEXT:打开]");
}

注意事项

  • 优先使用方法1,避免依赖系统弹窗,稳定性最高
  • 方法2和3需要确保程序有足够权限操作系统窗口
  • 若RDC会话锁定后仍有问题,可尝试在RDC连接时勾选**"当我断开连接时保持会话处于活动状态"**,或修改组策略禁用自动锁定

内容的提问来源于stack exchange,提问作者Vivek Ghevariya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 12:50:22