4

我正在尝试使用 WebBrowser 控件上传文件(图像)。似乎做不到,需要一些帮助。

这是HTML:

<form action="https://post.testsite.com/k/IOkurrwY4xGI_EJMbjF5pg/zMNsR" method="post" enctype="multipart/form-data">
    <input type="hidden" name="cryptedStepCheck" value="U2FsdGVkX18yNzEwMjcxMJdrv2IidjtpGSCPzHNblWk02eJAJ6DFXFXic-Am1lTPMYL7k7XDoH0">
    <input type="hidden" name="a" value="add">
    <input class="file" type="file" name="file" multiple="multiple">
    <button class="add" type="submit" name="go"  value="add image">add image</button>
</form>

这是C#代码...

        elements = webBrowser.Document.GetElementsByTagName("input");
        foreach (HtmlElement file in elements)
        {
            if (file.GetAttribute("name") == "file")
            {
                file.Focus();
                file.InvokeMember("Click");
                SendKeys.Send("C:\\Images\\CCPhotoID.jpg" + "{ENTER}");
            }
        }

请注意,文件上传按钮出现,但不能在文件名区域输入任何文件名。

4

2 回答 2

7

IMO,您正在尝试做的确实是 UI 测试自动化的合法场景。IIRC,在 IE 的早期版本中,可以<input type="file"/>使用文件名填充字段,而不显示Choose File对话框。出于安全原因,这不再可能,因此您必须将密钥发送到对话框。

这里的问题是file.InvokeMember("Click")显示一个模态对话框,并且您希望将键发送到对话框,但在对话框关闭后SendKeys.Send执行(毕竟它是模态的)。您需要先让对话框打开,然后发送密钥并让它关闭。

这个问题可以使用 WinForms 解决Timer,但我更喜欢使用async/awaitand Task.Delay(工作代码):

async Task PopulateInputFile(HtmlElement file)
{
    file.Focus();

    // delay the execution of SendKey to let the Choose File dialog show up
    var sendKeyTask = Task.Delay(500).ContinueWith((_) =>
    {
        // this gets executed when the dialog is visible
        SendKeys.Send("C:\\Images\\CCPhotoID.jpg" + "{ENTER}");
    }, TaskScheduler.FromCurrentSynchronizationContext());

    file.InvokeMember("Click"); // this shows up the dialog

    await sendKeyTask;

    // delay continuation to let the Choose File dialog hide
    await Task.Delay(500); 
}

async Task Populate()
{
    var elements = webBrowser.Document.GetElementsByTagName("input");
    foreach (HtmlElement file in elements)
    {
        if (file.GetAttribute("name") == "file")
        {
            file.Focus();
            await PopulateInputFile(file);
        }
    }
}

IMO,这种方法对于 UI 自动化脚本非常方便。你可以Populate这样调用,例如:

void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    this.webBrowser.DocumentCompleted -= webBrowser_DocumentCompleted;
    Populate().ContinueWith((_) =>
    {
        MessageBox.Show("Form populated!");
    }, TaskScheduler.FromCurrentSynchronizationContext());
}
于 2013-09-09T03:45:03.930 回答
2

就这么简单

 elements = webBrowser.Document.GetElementsByTagName("input");
        foreach (HtmlElement file in elements)
        {
            if (file.GetAttribute("name") == "file")
            {
                SelectFile();
                file.InvokeMember("Click");
            }
        }

制作此功能并在单击之前调用它会完美运行

 public async void SelectFile()
        {
            await Task.Delay(2000);
            SendKeys.Send("C:\\Images\\CCPhotoID.jpg" + "{ENTER}");
        }

并且我面临的没有修剪字符错误看看这个我发布了这个问题

于 2016-09-14T10:54:07.330 回答