Click here to Skip to main content
15,891,431 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
im quite the newbie when it comes to htmlelement class!

What i am trying to do right now is to fill a very very boring external web page with loads of data that already exists on the computer (the program is executed locally on said computer). one of those annoying and time consuming things to do manually is to select picture of an equipment installation from your computer and then submit it to that form, doing so, is possible by using the HTMLElement class and webBrowser control, but i hate the unsafe coding required to do so, i call it unsafe because it has race condition issues, here take a look:

The following code was not created by me
C#
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);
        }
    }
}

Ok, now image your computer has the HDD sleeping, or its in a very stressfull antivirus scanning + updating windows at the same time, naturally the modal window to appear can take even up to 10 seconds. what then that means is youre typing the path of the file and pressing enter way before the shown dialog appears which will cause the program to get stuck never leaving that failed to execute line of code, nor presenting the user or the coder with any error (which is expected).

What im trying to do is exactly that but at the same time avoiding that very obvious race condition, i was considering checking each 500ms in a loop to see if window is open and only then execute the sendkeys, something like this:

C#
AutoUploadPicture(string path)
{
    fileUploadDialogElement.Focus();//HTMLElement Taken from webBrowser1.Document

    Task.Run(()=>PerformAsyncCheckup());
    fileUploadDialogElement.InvokeMember("click");
    CancelTask = true;

    //successfully continue coding as it avoided that ugly race condition
}
bool CancelTask = false;
PerformAsyncCheckup()
{
     while (webBrowser1.AnyDialogFormShowing==false && CancelTask == false)
     {
         Thread.Sleep(200);
     }
     if (CancelTask ==false)
         SendKeys.Send("C:\\Images\\CCPhotoID.jpg" + "{ENTER}");

Is what i want possible? ive searched google and stackoverflow and all solutions were based on some random timer which always risks race condition errors.

Best Regards!

What I have tried:

C#
PerformAsyncCheckup()
{
     while (webBrowser1.AnyDialogFormShowing==false && CancelTask == false)
     {
         Thread.Sleep(200);
     }
     if (CancelTask ==false)
         SendKeys.Send("C:\\Images\\CCPhotoID.jpg" + "{ENTER}");
Posted
Updated 18-Oct-16 4:22am
v2

1 solution

I have fixed the problem by ignoring the sendkeys method and using a combination of threading and windows internal messaging system to detect and configure modal windows on top of my application, which fixes the reliability issues with this current coding.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900