1

現在、ユーザーが特定の 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 オブジェクトを妨害する理由と、両方を使用するにはどうすればよいかということです。新しい AppDomain で監視コンポーネントを実行しようとしましたが、問題は解決しませんでした。新しいプロセスを作成することだけが解決策でしたが、これはいくつかの理由でやりたくないことです。

IE 7 を搭載した Win2k3 サーバーでテストしています。

4

1 に答える 1

0

参照を Arraylist に保持すると、問題が解決します。ShellWindows コレクションは参照を保持していないようです。

于 2008-11-06T14:40:50.490 に答える