1

当打开 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";

    }
}

}

4

1 回答 1

3

你将无法做你想做的事——至少不能以一种可靠的方式。

浏览器的实现方式不同。FireFox 和较旧的 IE 版本使用单进程模型,IE9 是多进程的,但出于性能原因,每个进程将多个选项卡分组,Chrome 每个选项卡执行一个进程。其他浏览器/浏览器版本可以随心所欲(但很可能是单进程)。您必须为要支持的浏览器编写特定的代码,并且您将处理非常深入的实现细节。

对于 Chrome,iirc 模型是一个处理渲染的“宿主窗口”。处理每个选项卡的进程是“工作进程”,主机和工作人员之间来回通信......如果 Chrome 没有用于获取工作进程 PID 的官方 API,那么不要打扰 :)

于 2012-05-11T06:35:26.090 回答