我有一个正在用 C# 开发的 IE BHO。它应该等待用户做一些事情,联系我们的服务器并下载一些数据,然后用结果改变当前加载网页的 DOM。
我遇到了一些与 COM 划分和线程规则相关的看似无法克服的问题——即,我似乎无法在当前线程之外访问 IE DOMDocument,而且我想不出任何方法可以在不锁定的情况下异步运行某些东西启动 IE 直到完成。
我的第一次尝试是让后台服务器通信以事件驱动的方式完成它的工作:我的程序将从 mshtml 事件(例如,BeforeNaviagate2 或 DocumentComplete)中启动通信,并从单独的事件处理程序中发布结果由服务器通信对象在完成其工作时触发。
该技术在我拼凑在一起的快速模拟器中运行良好(只是一个带有 WebBrowser 控件的简单应用程序),但在 IE 中它会引发 COM 异常,因为我试图通过单独的线程更改页面 DOM。
因此,我尝试将所有内容保留在同一个函数中,并让我的代码等待服务器通信对象使用 while 循环完成其工作,如下所示:
int waited = 0;
while (!OurServerCommRequest.ready) {
System.Threading.Thread.Sleep(1);
Application.DoEvents();
waited++;
if (waited > constants.TIMEOUT_OURSERVER_REQUEST) {
log.wL("Timed out");
}
}
这种方法的问题在于,当代码保留在原始线程中时,它会与它触发的 IE 进程同步执行(在 IE8 中,它是每个选项卡一个进程 - 就像 Google Chrome 一样 - 似乎)......因此锁定IE 界面,直到我的服务器通信完成。
最初我想在 URL 可用时立即开始处理(通过 NavigationComplete2 事件),但我发现如果我的服务器通信在用户页面加载之前完成,等待 <body> 标记变得可用也会锁定 IE - 抛出它进入一个无限循环,而我的代码等待 HTML 正文,而页面被阻止更新自身做上述循环。
我考虑过将所有这些都移到实际用户页面的 javascript 中,但似乎这样做我打开了一罐蠕虫来解决 XSS 安全问题。
所以...我的问题是这样的:是否可以在 C# IE BHO 中异步运行代码,同时仍然能够操作用户的页面 DOM?我问了一些朋友,大多数人告诉我这不太可能。我还是 COM 和 C# 的新手,来自 C/VB.net/JS/AS。
谢谢!
-汤姆