如何在没有竞争条件的情况下从计算机上编程地选择一个文件(从webBrowser访问的HtmlElement中)
本文关键字:一个 HtmlElement 访问 webBrowser 文件 选择 编程 竞争 条件 计算机 情况下 | 更新日期: 2023-09-27 18:13:21
我对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秒。这意味着你在显示的对话框出现之前输入文件的路径并按enter键,这将导致程序卡住,永远不会离开未能执行的代码行,也不会向用户或编码器呈现任何错误(这是预期的)。
我想做的就是这样,但同时避免非常明显的竞争条件,我正在考虑在循环中检查每500ms,看看窗口是否打开,然后才执行sendkeys,像这样:
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()