我正在尝试使用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}");
}
}
请注意,文件上传按钮出现,但无法在文件名区域输入任何文件名。
答案 0 :(得分:6)
IMO,您正在尝试做的事情确实是UI测试自动化的合法场景。 IIRC,在早期版本的IE中,可以使用文件名填充<input type="file"/>
字段,而不显示Choose File
对话框。出于安全原因,这不再可能,因此您必须将密钥发送到对话框。
这里的问题是file.InvokeMember("Click")
显示模式对话框,并且您希望将密钥发送到那个对话框,但是SendKeys.Send
在之后执行 / em>对话框已关闭(它是模态,后跟)。您需要先打开对话框,然后发送密钥并将其关闭。
使用WinForms Timer
可以解决此问题,但我更倾向于使用async/await
和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());
}
答案 1 :(得分:1)
就像那样简单
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}");
}
时没有尝试字符错误