繁体   English   中英

c#HtmlElement 如何从没有竞争条件的计算机中以编程方式选择文件(从 WebBrowser 访问的 HtmlElement)

[英]c# HtmlElement How to programmaticaly select a file (from a HtmlElement accessed by a webBrowser) from a computer without race condition

我是 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,所有解决方案都基于一些随机计时器,这总是有竞争条件错误的风险。

此致!

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM