Объект автоматизации InternetExplorer + PerformanceCounter = не работает? - PullRequest
1 голос
/ 27 октября 2008

В настоящее время я пытаюсь создать простой компонент, который должен отслеживать, если пользователь открывает окно с определенным URL (только IE). Итак, я написал этот компонент, и все отлично работает, поэтому я интегрировал его с приложением, где это было необходимо. Проблема в том, что в этом приложении используются PerformanceCounters, которые, похоже, нарушают поведение объекта автоматизации InternetExplorer.

Итак, я написал этот небольшой пример, чтобы продемонстрировать проблему:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Diagnostics;
using SHDocVw;

namespace IEHookTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread t = new Thread(PerfCounter);
            t.Start();

            URLInterceptor.Instance.StartListening();
            Console.ReadLine();
        }

        private static void PerfCounter()
        {
            PerformanceCounter cpuPc = 
                new PerformanceCounter("Processor", "% Processor Time", "_Total", true);
            do
            {
                float x = cpuPc.NextValue();
                System.Diagnostics.Debug.WriteLine(x);
                Thread.Sleep(50);
            } while (true);
        }
    }

    class URLInterceptor
    {
        private const string DEMANDED_URL = "test";
        private ShellWindows _shellWindows = new ShellWindows();

        public static readonly URLInterceptor Instance = new URLInterceptor();
        private static int _count = 0;
        private URLInterceptor()
        {
        }

        public void StartListening()
        {
            _count++;
            _shellWindows.WindowRegistered -= ShellWindows_WindowRegistered;
            _shellWindows.WindowRegistered += new DShellWindowsEvents_WindowRegisteredEventHandler(ShellWindows_WindowRegistered);
            FindIEs();
        }

        private void FindIEs()
        {
            int count = 0;
            foreach (InternetExplorer browser in _shellWindows)
            {
                browser.NewWindow3 -= browser_NewWindow3;
                browser.NewWindow3 += new DWebBrowserEvents2_NewWindow3EventHandler(browser_NewWindow3);
                count++;
            }
        }

        private void ShellWindows_WindowRegistered(int lCookie)
        {
            FindIEs();
        }

        private void browser_NewWindow3(ref object ppDisp,
                                        ref bool Cancel,
                                        uint dwFlags,
                                        string bstrUrlContext,
                                        string bstrUrl)
        {
            if (!string.IsNullOrEmpty(bstrUrl) && bstrUrl.ToLower().Contains(DEMANDED_URL))
            {
                Cancel = true;
                Console.WriteLine("catched URL: " + bstrUrl);
            }
        }
    }
}

В этом образце нужна ссылка на «Microsoft Internet Controls» (SHDocVw). Чтобы проверить образец, просто откройте Google и выполните поиск «test». Возьмите первую ссылку и откройте ее в новой вкладке или окне. Вы увидите, что иногда возникает событие «NewWindow3», а иногда нет. Но если вы закомментируете строку 15 (начало потока), объекты будут работать так, как ожидается, и генерирует событие для каждого нового окна.

Итак, мой вопрос: почему счетчик производительности мешает объекту InternetExplorer и как я могу использовать оба. Я попытался запустить компонент монитора в новом домене приложений, но это не решило проблему. Решением было создание только нового процесса, но я этого не хочу по нескольким причинам.

Я тестирую на сервере Win2k3 с IE 7.

1 Ответ

0 голосов
/ 06 ноября 2008

Хранение ссылок в Arraylist решает проблему. Похоже, что коллекция ShellWindows не содержит ссылок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...