c# HtmlElement 如何以编程方式 select 来自计算机的文件(来自 Web 浏览器访问的 HtmlElement)而没有竞争条件
c# HtmlElement How to programmaticaly select a file (from a HtmlElement accessed by a webBrowser) from a computer without race condition
我是 htmlelement 的新手 class!
我现在想做的是用计算机上已经存在的大量数据填充一个非常非常无聊的外部网页(该程序在所述计算机上本地执行)。手动执行的烦人且耗时的事情之一是从您的计算机 select 设备安装的图片,然后将其提交到该表单,这样做可以通过使用 HTMLElement class 和 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);
}
}
}
好吧,现在想象一下你的电脑有硬盘休眠,或者它在一个非常紧张的杀毒扫描+同时更新windows,自然出现的模式window可以占用更多时间到 10 秒。那么这意味着您在显示的对话框出现之前键入文件的路径并按回车键,这将导致程序卡住,永远不会离开未能执行的代码行,也不会向用户或编码器显示任何错误(这是预期的)。
我正在尝试做的正是那样,但同时避免了非常明显的竞争条件,我正在考虑在循环中每 500 毫秒检查一次以查看 window 是否打开,然后才执行 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 和 Whosebug,所有解决方案都基于一些随机计时器,这总是有竞争条件错误的风险。
此致!
我已经通过忽略 sendkeys 方法并使用线程和 windows 内部消息传递系统的组合来检测和配置我的应用程序顶部的模态 windows 来解决问题,这修复了可靠性当前编码存在问题。
即 FindWindowEx()、SendMessage()、GetParent() 和 Task.Run()
我是 htmlelement 的新手 class!
我现在想做的是用计算机上已经存在的大量数据填充一个非常非常无聊的外部网页(该程序在所述计算机上本地执行)。手动执行的烦人且耗时的事情之一是从您的计算机 select 设备安装的图片,然后将其提交到该表单,这样做可以通过使用 HTMLElement class 和 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);
}
}
}
好吧,现在想象一下你的电脑有硬盘休眠,或者它在一个非常紧张的杀毒扫描+同时更新windows,自然出现的模式window可以占用更多时间到 10 秒。那么这意味着您在显示的对话框出现之前键入文件的路径并按回车键,这将导致程序卡住,永远不会离开未能执行的代码行,也不会向用户或编码器显示任何错误(这是预期的)。
我正在尝试做的正是那样,但同时避免了非常明显的竞争条件,我正在考虑在循环中每 500 毫秒检查一次以查看 window 是否打开,然后才执行 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 和 Whosebug,所有解决方案都基于一些随机计时器,这总是有竞争条件错误的风险。
此致!
我已经通过忽略 sendkeys 方法并使用线程和 windows 内部消息传递系统的组合来检测和配置我的应用程序顶部的模态 windows 来解决问题,这修复了可靠性当前编码存在问题。
即 FindWindowEx()、SendMessage()、GetParent() 和 Task.Run()