0

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();
            }
        }
    }
PiE
  • 335
  • 1
  • 7
  • 24
  • When the dialog "hangs", do you see any of the keystrokes in the dialog's file name input field, or just none? Also, why the 5 seconds delay? – noseratio Oct 07 '13 at 14:22
  • @Noseratio - Most of the time, I do not see any keystrokes in the dialog input field, but sometimes I do. So, I used the `Keys.Enter` system command hoping that would help, and I'm not sure if it did. During a given file upload, whether or not it uploads the file is not as important that the File Dialog closes at the end. I increased the delay time to try to experiment as a result of this issue - I.e., maybe there was not enough time to both download a file (that's what my program does), and then upload it? – PiE Oct 07 '13 at 16:10

2 Answers2

1

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);
    }
PiE
  • 335
  • 1
  • 7
  • 24
  • Hmm, you just close the dialog here. What about the file name? I was under impression you do not get *any* keystrokes, including the file name. I don't understand how closing the dialog with `SC_CLOSE` would get the file name propagated into the web page's ` field. Otherwise, no problem - glad it if I helped. – noseratio Oct 08 '13 at 08:08
  • 1
    @Noseratio - You are right - When the `SENDKEYS` does not work, nothing gets populated and the dialog just closes without entering the file name. I still don't know why _sometimes_ the file name does not get populated in the dialog using the code you provided in an earlier post (i.e., the `asynch` Populate filename method), however, most of the time it does. That problem is still unsolved. But now, if the file name **does not** get populated (for whatever reasons), the dialog closes and my program can continue without human intervention. – PiE Oct 08 '13 at 08:25
  • No problem. [This](http://stackoverflow.com/q/17069123/1768303) may further help you with the `SendKey` issue. – noseratio Oct 08 '13 at 08:28
0

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);
}
noseratio
  • 59,932
  • 34
  • 208
  • 486
  • 1
    So I put the code in exactly per your specifications. The program says the "Currently focused window is "Choose File to Upload". (By the way, thanks for your help - this is awesome - thanks - Pierre) – PiE Oct 08 '13 at 07:17
  • I tried using this code to close the window (It did not work)`[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("C2CTest", "Choose File to Upload"); if (iHandle > 0) { // close the window using API SendMessage(iHandle, WM_SYSCOMMAND, SC_CLOSE, 0); }` – PiE Oct 08 '13 at 07:28
  • Interesting, so the focused window is indeed "Choose File to Upload" (the correct one), but `SendKeys` doesn't feed in any keystrokes into it. Is the text cursor really inside "File name" field? – noseratio Oct 08 '13 at 07:49
  • 1
    I found the solution - Pls see below - Again, thanks for your direction - your suggestion led me to find the WIN API commands. Thanks - PMF – PiE Oct 08 '13 at 08:03