-1

我是 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 毫秒以查看窗口是否打开,然后才执行发送键,如下所示:

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

我想要的可能吗?我搜索了 google 和 stackoverflow,所有解决方案都基于一些随机计时器,这总是存在竞争条件错误的风险。

此致!

4

1 回答 1

0

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

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

于 2016-10-18T14:23:22.627 回答