我目前正在尝试构建一个应该监视的简单组件,如果用户打开具有特定 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 控件”(SHDocVw) 的引用。要测试示例,只需打开谷歌并搜索“测试”。获取第一个链接并在新选项卡或窗口中打开它。您会看到,有时会引发“NewWindow3”事件,有时不会。但是,如果您注释掉第 15 行(线程开始),对象将按预期工作,并为每个新窗口引发事件。
所以我的问题是,为什么性能计数器会干扰 InternetExplorer 对象,我该如何同时使用它们。我尝试在新的 AppDomain 中运行监视器组件,但这并没有解决问题。仅创建一个新流程是一种解决方案,但出于多种原因,这是我不想做的。
我正在使用 IE 7 在 Win2k3 服务器上进行测试。