@fanat_96

Как в webview2 Заполнить поле типа file?

Здравствуйте.
Много лет назад был найден способ заполнения полей type="file" еще для webbrowser.

async Task PopulateInputFile_poster(string file_poster)
        {
            ExecuteScript("document.getElementById(\"fln1\").focus();");

            // delay the execution of SendKey to let the Choose File dialog show up
            var sendKeyTask = Task.Delay(1000).ContinueWith((_) =>
            {
                // this gets executed when the dialog is visible
                SendKeys.Send(disk + "" + "poster.webp" + "{ENTER}");
            }, TaskScheduler.FromCurrentSynchronizationContext());

            ExecuteScript("document.getElementById(\"fln1\").click();"); // this shows up the dialog

            await sendKeyTask;

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


        async Task Populate()
        {
            ExecuteScript("document.getElementById(\"fln1\").focus();");
            await PopulateInputFile_poster("fln1");
        }


И потом все это вызывается при нажатии нужной кнопки:
Populate().ContinueWith((_) =>
            {

            }, TaskScheduler.FromCurrentSynchronizationContext());

Этот способ работает и для webview2. Но меня интересует есть ли какая-нибудь альтернатива? Т.к. в приведенном мною примере заполняется лишь одно поле, но у меня есть парочка проектов, где таких полей больше 10. И это занимает некоторое время, и его хотелось бы сократить, если это возможно)
  • Вопрос задан
  • 34 просмотра
Решения вопроса 1
@Uncleruc1
В WebView2 есть несколько способов автоматизировать заполнение полей типа file, но основное ограничение связано с безопасностью браузера, так как доступ к файловым полям строго ограничен и браузеры не позволяют напрямую задавать значения для этих полей через JavaScript. Ваш текущий подход с использованием SendKeys имитирует пользовательский ввод, что позволяет обходить это ограничение, но действительно может быть медленным при большом количестве полей.

Вот несколько возможных альтернатив для ускорения процесса:

Пакетная обработка файлов: Вместо того, чтобы обрабатывать каждое поле по одному, можно попытаться сгенерировать команды для всех полей и запустить их параллельно. Например, можно использовать параллельные задачи для вызова метода PopulateInputFile_poster сразу для нескольких полей:
async Task PopulateMultipleFiles(Dictionary<string, string> fileMappings)
{
    var tasks = fileMappings.Select(async kvp =>
    {
        var fileId = kvp.Key;
        var filePath = kvp.Value;
        ExecuteScript($"document.getElementById(\"{fileId}\").focus();");

        var sendKeyTask = Task.Delay(1000).ContinueWith((_) =>
        {
            SendKeys.Send(filePath + "{ENTER}");
        }, TaskScheduler.FromCurrentSynchronizationContext());

        ExecuteScript($"document.getElementById(\"{fileId}\").click();");

        await sendKeyTask;
        await Task.Delay(1000);
    });

    await Task.WhenAll(tasks);
}

var fileMappings = new Dictionary<string, string>
{
    { "fln1", "poster.webp" },
    { "fln2", "image2.jpg" },
    // Добавьте остальные файлы
};

await PopulateMultipleFiles(fileMappings);

WebDriver / Selenium: Хотя WebView2 более легкий и быстрый, использование Selenium с WebDriver может предоставить более гибкие возможности автоматизации, в том числе возможность работы с множеством полей через драйвер:
IWebDriver driver = new EdgeDriver();
IWebElement fileInput = driver.FindElement(By.Id("fln1"));
fileInput.SendKeys("C:\\path\\to\\poster.webp");

Это может быть быстрее для массового заполнения полей.

Использование JavaScript и локальных API: Если у вас есть контроль над страницей, можно разработать API для загрузки файлов через JavaScript, но это требует модификации самой страницы, что не всегда возможно.

Оптимизация задержек: Поиграйте с настройками задержек в вашем коде. Возможно, в некоторых случаях не нужно ждать целую секунду между шагами.

Если у вас есть возможность контролировать или изменять целевые страницы, другие подходы могут включать в себя создание вспомогательных API для загрузки файлов напрямую.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы