I do not want to use Thread.Sleep with SHDocVw.ShellWindows

I have a program in which I should get an instance of SHDocVw.InternetExplorer from a running IE8 process. To get an instance, see the sample code below. For some reason, it will not work without Thread.Sleep.

Browser.HWND throws an InvalidCastException for all instances in m_IEFoundBrowsers if Thread.Sleep is deleted. When using Thread.Sleep, it works for IE8 windows.

Does anyone know how to do this without using Thread.Sleep? (I do not like to use the sleep function, usually it just pushes problems into the future ...)

Code example:

InternetExplorer m_IEBrowser = null; ShellWindows m_IEFoundBrowsers = new ShellWindowsClass(); Thread.Sleep(10); foreach (InternetExplorer Browser in m_IEFoundBrowsers) { try { if (Browser.HWND == (int)m_Proc.MainWindowHandle) { m_IEBrowser = Browser; break; } } catch(InvalidCastException ice) { //Do nothing. Browser.HWND could not execute for this item. } } 
+4
source share
2 answers

I came across the following link which seems to support Hans comment: http://weblogs.asp.net/joberg/archive/2005/05/03/405283.aspx

The article says:

The Internet management library contains "ShellWindowsClass", which is basically a collection of all shell windows (ex: IE) generated through the desktop. This component provides the "Windows Registered" event handler that we are going to connect to. As soon as we wait until the corresponding window is registered, we are going to link our Office Internet Explorer to the shell window found. To determine if a window has been found, we iterate over the registered windows, and we try to find the handle corresponding to the handle of the process that we previously launched. We will use "ManualResetEvent", a synchronization primitive to wait a certain amount of time for the window to register.

I expect that you can easily correlate these ideas with your problem.

+5
source

An article published by David solved the problem. When I run the code for the first time in my program, it works as described in the article. But if I exit the program, leave open IE8 open, open my program again, then the windows_WindowRegistered method will get problems with InvalidCastExceptions. Handling these exceptions, as shown below, made it work as needed.

EXAMPLE CODE:

 private void windows_WindowRegistered(int lCookie) { if (process == null) return; // This wasn't our window for sure for (int i = 0; i < windows.Count; i++) { try { InternetExplorerLibrary.InternetExplorer ShellWindow = windows.Item(i) as InternetExplorerLibrary.InternetExplorer; if (ShellWindow != null) { IntPtr tmpHWND = (IntPtr)ShellWindow.HWND; if (tmpHWND == process.MainWindowHandle) { IE = ShellWindow; waitForRegister.Set(); // Signal the constructor that it is safe to go on now. return; } } } catch (InvalidCastException ice) { //Do nothing. Browser.HWND could not execute for this item. } } } 
+2
source

Source: https://habr.com/ru/post/1339053/


All Articles