Question

I am using a WebBrowser control for some automated testing. The problem is that occasionally - not all the time - when I am testing uploading images, the file upload dialog box does not close and the the program just "hangs" and waits for manual input, which defeats the purpose of the whole automated process. What I want to do is to "force" a close of the dialog box, but have been unable to figure this out. Any help or direction would be much appreciated.

The thing to realize is that this code works some of the time, but NOT all of the time. I need help figuring out how to make this code work ALL of the time.

Here is the code:

    async Task PopulateInputFile(System.Windows.Forms.HtmlElement file, string fname)
    {
        file.Focus();

        // delay the execution of SendKey 500ms to let the Choose File dialog show up
        var sendKeyTask = Task.Delay(5000).ContinueWith((_) =>
        {
            // this gets executed when the dialog is visible
            //SendKeys.Send(fname + "{ENTER}");
            //PressKey(Keys.Space, false);
            SendKeys.SendWait(fname);
            PressKey(Keys.Enter, false);
        }, TaskScheduler.FromCurrentSynchronizationContext());

        file.InvokeMember("Click"); // this shows up the dialog

        await sendKeyTask;

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

    async Task Populate(string fname)
    {
        var elements = webBrowser.Document.GetElementsByTagName("input");
        foreach (System.Windows.Forms.HtmlElement file in elements)
        {
            if (file.GetAttribute("name") == "file")
            {
                this.Activate();
                this.BringToFront();
                file.Focus();
                await PopulateInputFile(file, fname);
                file.RemoveFocus();
            }
        }
    }
Était-ce utile?

La solution 2

Not really an answer, but it may turn into an answer later. Are use sure the focus is inside the IE "Choose File to Upload" dialog, when you do SendKeys? Use the following to verify that, put the code from below Task.Delay(4000) into your ContinueWith and check the output from Debug.Print.

static class Win32
{
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern int GetWindowText(IntPtr hWnd, System.Text.StringBuilder lpString, int nMaxCount);

    [DllImport("user32.dll")]
    public static extern IntPtr GetForegroundWindow();
}

private async void Form1_Load(object sender, EventArgs ev)
{
    await Task.Delay(4000);

    var currentWindow = new System.Text.StringBuilder(1024);
    Win32.GetWindowText(Win32.GetForegroundWindow(), currentWindow, currentWindow.Capacity);
    Debug.Print("Currently focused window: \"{0}\"", currentWindow);
}

Autres conseils

Ok, so here is the solution. You have to use the WIN API to close the window. I found the class name of the "Choose File to Upload" dialog by using SPY++, which turns out to be: #32770.

    [DllImport("user32.dll")]
    public static extern int FindWindow(string lpClassName,string lpWindowName);
    [DllImport("user32.dll")]
    public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);

    public const int WM_SYSCOMMAND = 0x0112;
    public const int SC_CLOSE = 0xF060;

    int iHandle = FindWindow("#32770", "Choose File to Upload");
    if (iHandle > 0)
    {
          // close the window using API        
          SendMessage(iHandle, WM_SYSCOMMAND, SC_CLOSE, 0);
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top