Internet explorer WatiN、Internet Explorer启动和IWebBrowser2窗口句柄
我正在研究WatiN的以下代码,该代码负责启动和连接Internet Explorer:Internet explorer WatiN、Internet Explorer启动和IWebBrowser2窗口句柄,internet-explorer,watin,hwnd,iwebbrowser2,Internet Explorer,Watin,Hwnd,Iwebbrowser2,我正在研究WatiN的以下代码,该代码负责启动和连接Internet Explorer: private static IEBrowser CreateIEPartiallyInitializedInNewProcess(Uri uri) { var m_Proc = CreateIExploreInNewProcess(uri); var helper = new AttachToIeHelper(); var action =
private static IEBrowser CreateIEPartiallyInitializedInNewProcess(Uri uri)
{
var m_Proc = CreateIExploreInNewProcess(uri);
var helper = new AttachToIeHelper();
var action = new TryFuncUntilTimeOut(TimeSpan.FromSeconds(Settings.AttachToBrowserTimeOut))
{
SleepTime = TimeSpan.FromMilliseconds(500)
};
var ie = action.Try(() =>
{
m_Proc.Refresh();
var mainWindowHandle = m_Proc.MainWindowHandle;
// return mainWindowHandle != IntPtr.Zero ? GetIWebBrowser2Directly(mainWindowHandle) : null;
return mainWindowHandle != IntPtr.Zero
? helper.FindIEPartiallyInitialized(new AttributeConstraint("hwnd", mainWindowHandle.ToString()))
: null;
});
if (ie != null) return ie._ieBrowser;
// if (ie != null) return new IEBrowser(ie);
throw new BrowserNotFoundException("IE", "Timeout while waiting to attach to newly created instance of IE.", Settings.AttachToBrowserTimeOut);
}
WatiN所做的是启动Internet Explorer并等待它得到.MainWindowHandle(显示Internet Explorer内内容的“窗口”的句柄)。一旦获得此窗口句柄,它将获得在用户桌面上启动并运行的所有IWebBrowser2窗口的列表,并尝试将进程的.MainWindowHandle与来自IWebBrowser2集合的一个窗口句柄(如果有)相匹配
这种方法最重要的问题是,IWebBrowser2.HWND属性(需要与.MainWindowHandle进行比较)可能是有问题的、不稳定的和喜怒无常的,因为当您尝试访问它时(至少在我正在运行测试的机器上),它每隔一段时间就会抛出InvalidCastException。此外,还有这样一个操作的开销
我的问题是,对于那些可能更了解我的windows编程知识的人来说:既然HWND无论如何都会匹配,为什么我们不使用.MainWindowHandle值通过使用以下方法立即检索所需的IWebBrowser2(请参阅上面注释掉的代码)(受WatiN在ShellWindow2.cs内部使用的代码启发):
(作为旁注,我们甚至可以创建一个代理对象(如我在另一篇文章中所述)来缓存窗口句柄,以避免向IWebBrowser2.HWND索要它)
这对我来说很好。我看不到HWNDs之间有任何冲突或不匹配-不知道是否有我可能错过的角落案例。我很想在WatiN论坛上询问这一点,但我想先在程序员中心询问一下,以防我错过一些明显的东西
提前谢谢大家。任何提示都将不胜感激
干杯,
Dominick我开始深入研究InternetExplorer的内部窗口结构,并提出了以下层次结构(当然,不相关的窗口也可以使用): IEFrame
|
--TabWindowClass-1--转换-->第一个IWebBrowser2
|
--TabWindowClass-2--转换-->第二个IWebBrowser2
|
…
|
--TabWindowClass N--转换-->N-IWebBrowser2
通过测试,我在Windows7+IE9(9.0.8112.16421)中得到了以下发现
private static IWebBrowser2 GetIWebBrowser2Directly(IntPtr embeddedWebBrowserWindowHandle)
{
IHTMLDocument2 document2 = UtilityClass.TryFuncIgnoreException(() => IEUtils.IEDOMFromhWnd(embeddedWebBrowserWindowHandle));
if (document2 == null) return null;
IHTMLWindow2 parentWindow = UtilityClass.TryFuncIgnoreException(() => document2.parentWindow);
if (parentWindow == null) return null;
return UtilityClass.TryFuncIgnoreException(() => ShellWindows2.RetrieveIWebBrowser2FromIHtmlWindw2Instance(parentWindow));
}