Uploading Files Not Working - Need Assistance

后端 未结 2 983
旧巷少年郎
旧巷少年郎 2020-11-27 23:12

I am trying to upload a file (an image) using the WebBrowser control. Can\'t seem to do it and need some help.

Here is the Html:

相关标签:
2条回答
  • 2020-11-27 23:33

    Just simple like that

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

    Make this function and call it before click it will work perfectly

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

    and no triming character error as I faced Take a look on this I was posted this Question

    0 讨论(0)
  • 2020-11-27 23:40

    IMO, what you're trying to do is indeed a legit scenario for UI testing automation. IIRC, in early versions of IE it was possible to populate the <input type="file"/> field with a file name, without showing up the Choose File dialog. For security reason, this is no longer possible, so you have to send keys to the dialog.

    The problem here is that file.InvokeMember("Click") shows a modal dialog, and you want the keys to be sent to that dialog, but SendKeys.Send gets executed after the dialog has been closed (it's modal, after-all). You need to let the dialog open first, then send the keys and let it close.

    This problem can be solved using WinForms Timer, but I'd prefer using async/await and Task.Delay for this (working code):

    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, this approach is very convenient for UI automation scripts. You can call Populate like this, for example:

    void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        this.webBrowser.DocumentCompleted -= webBrowser_DocumentCompleted;
        Populate().ContinueWith((_) =>
        {
            MessageBox.Show("Form populated!");
        }, TaskScheduler.FromCurrentSynchronizationContext());
    }
    
    0 讨论(0)
提交回复
热议问题