C#如何为外部浏览器即Chrome/Firefox/ie中的每个浏览器选项卡获取唯一的PID

C#如何为外部浏览器即Chrome/Firefox/ie中的每个浏览器选项卡获取唯一的PID,c#,browser,tabs,pid,C#,Browser,Tabs,Pid,当打开Windows任务管理器以查看所有打开进程的PID时,我可以看到我的Chrome浏览器中所有打开的选项卡都有其唯一的PID,但是,无论使用哪个选项卡,我都会获得相同的PID: [DllImport("user32.dll")] static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] static extern uint GetWindowThreadProcessId(IntPtr hWnd, out u

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

    }
}

}

你不能做你想做的事——至少不能以可靠的方式

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


对于Chrome,iirc模型是一个处理渲染的“主机窗口”。处理每个选项卡的过程是“工作进程”,主机和工作进程之间来回通信。。。如果Chrome没有为工作进程获取PID的官方API,那就不用麻烦了:)

Chrome是我所知道的唯一一个为每个选项卡使用不同进程的浏览器。大多数浏览器使用多线程。我相信您总是从GetForegroundWindow()获得相同进程的原因是,这将返回主chrome进程,而不是打开选项卡的进程。@Firth:IE9也是多进程的。虽然IE9有多个进程,但它并不是每个选项卡都使用一个进程-出于性能原因,它每个进程都有多个选项卡。好的,非常感谢你。我想,作为第二种方法,我必须尝试使用计时器方法,每隔几秒钟检查浏览器url是否有变化。我对C#net编程有点陌生,但我真正想做的是记录在特定url上花费的时间。因此,通过上面的代码,我可以检测浏览器何时获得焦点,然后当浏览器处于焦点窗口时,启动计时器以持续检查url和日志时间,如果url与我要查找的url匹配。当浏览器失去焦点时停止定时器。我更愿意使用事件来实现这一点,但看起来不太可能。请让我知道,如果你有任何的指针或建议给我。如果你想做到这一点可靠,你应该考虑编写浏览器扩展/插件。。。但是你必须为每个主要的浏览器写一些东西:)