c#HtmlElement如何从没有竞争条件的计算机中选择一个文件(来自webBrowser访问的HtmlElement)

时间:2016-10-17 15:59:04

标签: c# webbrowser-control htmlelements

对于htmlelement类来说,我是个新手!

我现在要做的是填充一个非常无聊的外部网页,其中包含计算机上已存在的大量数据(该程序在所述计算机上本地执行)。手动做的烦人和耗时的事情之一是从你的计算机中选择设备安装的图片,然后将其提交到那个表格,这样做,可以通过使用HTMLElement类和webBrowser控件,但我讨厌不安全的编码要求这样做,我称之为不安全,因为它有竞争条件问题,请看一下:

以下代码不是由我创建的

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);
        }
    }
}

好的,现在你的计算机硬盘处于睡眠状态,或者它处于非常紧张的防病毒扫描+同时更新窗口,自然出现的模态窗口甚至可能需要长达10秒。那意味着你输入文件的路径并在显示的对话框出现之前按下输入方式,这将导致程序卡住,永远不会离开执行代码行,也不会向用户或编码器显示任何错误(这是预期的。)

我试图做的正是这一点,但同时避免了非常明显的竞争条件,我正在考虑在循环中检查每个500毫秒,看看窗口是否打开,然后才执行sendkeys,如下所示:< / p>

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}");

我想要的是什么?香港专业教育学院搜索谷歌和stackoverflow,所有的解决方案都是基于一些随机计时器,它总是存在竞争条件错误。

最诚挚的问候!

1 个答案:

答案 0 :(得分:0)

我通过忽略sendkeys方法并使用线程和Windows内部消息传递系统的组合来检测和配置应用程序之上的模态窗口来解决问题,这解决了当前编码的可靠性问题。

即FindWindowEx(),SendMessage(),GetParent()和Task.Run()