【发布时间】:2012-05-19 17:20:24
【问题描述】:
当打开 Windows 任务管理器查看所有打开进程的 PID 时,我可以看到我的 Chrome 浏览器中所有打开的选项卡都有自己唯一的 PID,但是在使用时无论哪个选项卡处于焦点,我都会得到相同的 PID :
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
IntPtr hwnd = GetForegroundWindow();
GetWindowThreadProcessId(hwnd, out pid);
有人知道如何唯一标识浏览器标签吗?更进一步,有谁知道当浏览器标签改变状态或焦点时如何捕捉事件?任何浏览器 - Chrome、Firefox、IE
以下是我在前台窗口更改时捕获 WinEventHook 事件的完整代码:
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
namespace focusWindow2
{
public partial class Form1 : Form
{
[DllImport("user32.dll")]
static extern IntPtr SetWinEventHook(SystemEvents eventMin, SystemEvents eventMax, IntPtr hmodWinEventProc,
SystemEventHandler lpfnWinEventProc, uint idProcess, uint idThread, uint dwFlags);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool UnhookWinEvent(IntPtr hWinEventHook);
[DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
delegate void SystemEventHandler(IntPtr hWinEventHook, SystemEvents @event, IntPtr hwnd, int idObject, int idChild,
uint dwEventThread, uint dwmsEventTime);
enum SystemEvents
{
ForegroundWindowChanged = 0x3 // EVENT_SYSTEM_FOREGROUND - The only flag we care about
}
IntPtr _WinEventHook;
SystemEventHandler _WinEventHookHandler;
public Form1()
{
InitializeComponent();
// Create the handler
_WinEventHookHandler = new SystemEventHandler(WinEventHook);
// Set the hook
_WinEventHook = SetWinEventHook(SystemEvents.ForegroundWindowChanged, SystemEvents.ForegroundWindowChanged,
IntPtr.Zero, _WinEventHookHandler, 0, 0, 0);
this.FormClosing += delegate
{
UnhookWinEvent(_WinEventHook);
};
}
private void WinEventHook(IntPtr hWinEventHook, SystemEvents @event, IntPtr hwnd, int idObject, int idChild,
uint dwEventThread, uint dwmsEventTime)
{
uint pid = 0;
GetWindowThreadProcessId(hwnd, out pid);
Process p = Process.GetProcessById((int)pid);
string procName = Path.GetFileName(p.ProcessName);
textBox1.Text += procName + " " + pid + "\r\n";
}
}
}
【问题讨论】:
-
Chrome 是我所知道的唯一一个实际上为每个选项卡使用不同进程的浏览器。大多数浏览器使用多个线程。我相信您总是从 GetForegroundWindow() 获得相同进程的原因是因为这将返回主 chrome 进程而不是打开选项卡的进程。
-
@firthh:IE9 也是多进程的。
-
虽然 IE9 有多个进程,但它并不为每个选项卡使用一个进程 - 出于性能原因,它为每个进程托管多个选项卡。