InternetExplorer自动化对象+ PerformanceCounter =不工作?

时间:2008-10-27 08:21:12

标签: internet-explorer automation performancecounter

我正在尝试构建一个应该监视的简单组件,如果用户打开一个具有特定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)。 要测试样本,只需打开谷歌并搜索“测试”。获取第一个链接并在新选项卡或窗口中打开它。 你会看到,有时会引发“NewWindow3”事件,有时则不会。 但是如果你注释掉第15行(Thread start),对象就会按预期工作,并为每个新窗口引发事件。

所以我的问题是,为什么性能计数器会扰乱InternetExplorer对象,我怎么能同时使用它们。我试图在新的AppDomain中运行监视器组件,但这并没有解决问题。只创建一个新流程是一个解决方案,但出于几个原因,这是我不想做的。

我正在使用IE 7在Win2k3服务器上进行测试。

1 个答案:

答案 0 :(得分:0)

保持Arraylist中的引用可以解决问题。似乎ShellWindows Collection不包含引用。