Загрузка файлов не работает - нужна помощь

Я пытаюсь загрузить файл (изображение) с помощью элемента управления 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}");
        }

и нет ошибки символа обрезки, как я столкнулся Посмотрите на это мне был отправлен этот вопрос

Другие вопросы по тегам