В настоящее время я пытаюсь создать простой компонент, который должен отслеживать, если пользователь открывает окно с определенным 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.