views:

278

answers:

1

Hi,

I'm currently trying to build a simple component which should monitor, if the user opens a window with a specific url (IE only). So I wrote this component and everything works fine, so I intergrated it with the application, where it was needed. The problem is, in this application PerformanceCounters are used, and these seem to disturb the behaviour of the InternetExplorer automation object.

So I wrote this little sample to demonstrate the problem:

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);
            }
        }
    }
}

This sample needs a reference to the "Microsoft Internet Controls" (SHDocVw). To test the sample, just open google and search for "test". Take the first link and open it in a new tab or window. You will see, that sometimes the "NewWindow3" event is raised, and sometimes it is not. But if you comment out line 15 (Thread start), the objects works as expected, and raises the event for every new window.

So my question is, why are is the performance counter disturbing the InternetExplorer object, and how can I use both. I tried to run the monitor component in a new AppDomain, but that didn't solve the problem. Only creating a new process was a solution, but this is want I don't want to do, for serveral reasons.

I'm testing on Win2k3 server with IE 7.

tia Martin

A: 

To keep the references in an Arraylist solves the problem. Seems that the ShellWindows Collection doesn't hold the references.

Martin Moser