Загрузка файлов не работает - нужна помощь
Я пытаюсь загрузить файл (изображение) с помощью элемента управления 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}");
}
}
Обратите внимание, что кнопка загрузки файла появляется, но не может ввести любое имя файла в область имени файла.
2 ответа
IMO, то, что вы пытаетесь сделать, это действительно законный сценарий для автоматизации тестирования пользовательского интерфейса. IIRC, в ранних версиях IE можно было заполнить <input type="file"/>
поле с именем файла, без отображения Choose File
Диалог. По соображениям безопасности это больше невозможно, поэтому вам нужно отправить ключи в диалог.
Проблема здесь в том, что file.InvokeMember("Click")
показывает модальное диалоговое окно, и вы хотите, чтобы ключи были отправлены в этот диалог, но SendKeys.Send
исполняется после закрытия диалога (в конце концов, это модально). Вам нужно сначала открыть диалоговое окно, затем отправить ключи и закрыть его.
Эта проблема может быть решена с помощью 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);
}
}
}
ИМО, этот подход очень удобен для сценариев автоматизации пользовательского интерфейса. Ты можешь позвонить Populate
вот так, например:
void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
this.webBrowser.DocumentCompleted -= webBrowser_DocumentCompleted;
Populate().ContinueWith((_) =>
{
MessageBox.Show("Form populated!");
}, TaskScheduler.FromCurrentSynchronizationContext());
}
Просто так
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}");
}
и нет ошибки символа обрезки, как я столкнулся Посмотрите на это мне был отправлен этот вопрос