Я не хочу использовать Thread.Sleep с SHDocVw.ShellWindows - PullRequest
4 голосов
/ 09 февраля 2011

У меня есть программа, в которой я должен получить экземпляр SHDocVw.InternetExplorer из запущенного процесса IE8. Для получения экземпляра запускается приведенный ниже пример кода. По некоторым причинам это не будет работать без Thread.Sleep.

Browser.HWND создает исключение InvalidCastException для всех экземпляров m_IEFoundBrowsers, если Thread.Sleep удален. При использовании Thread.Sleep он работает для окон IE8.

Кто-нибудь знает, как это сделать, не используя Thread.Sleep? (Мне не нравится использовать функцию сна, обычно она просто выдвигает проблемы в будущее ...)

Пример кода:

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.  
      }  
}          

Ответы [ 2 ]

5 голосов
/ 09 февраля 2011

Я наткнулся на следующую ссылку, которая, кажется, поддерживает комментарий Ганса: http://weblogs.asp.net/joberg/archive/2005/05/03/405283.aspx

В статье говорится:

Библиотека интернет-управления содержит «ShellWindowsClass», который является в основном коллекция всех Окна оболочки (например, IE) через рабочий стол. Этот компонент предоставляет обработчик событий «Windows Registered», что мы собираемся подключить к. Как только процесс запущен, будем ждать пока соответствующее окно зарегистрировано тогда мы собираемся соединить наши Контроль Internet Explorer в оболочке окно найдено. Чтобы определить, если окно найдено, перебираем зарегистрированные окна, и мы пытаемся найти ручку, которая соответствует ручке процесса, который мы ранее запустили. Мы будем использовать «ManualResetEvent» примитив синхронизации для ожидания определенное количество времени для окна быть зарегистрированным.

Полагаю, вы сможете относительно легко сопоставить эти идеи с вашей проблемой.

2 голосов
/ 10 февраля 2011

Статья, опубликованная Дэвидом, решила проблему. При первом запуске кода в моей программе он работает, как описано в статье. Но если я выйду из программы, оставлю открытый IE8 открытым, снова открою мою программу, тогда у метода windows_WindowRegistered возникли проблемы с InvalidCastExceptions. Обработка этих исключений, как показано ниже, заставила его работать по мере необходимости.

ПРИМЕРНЫЙ КОД:

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.
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...