【问题标题】:C# How do I get unique PID for each browser tab in external browser ie. Chrome/Firefox/IEC# 如何获取外部浏览器中每个浏览器选项卡的唯一 PID,即。铬/火狐/IE
【发布时间】: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 有多个进程,但它并不为每个选项卡使用一个进程 - 出于性能原因,它为每个进程托管多个选项卡。

标签: c# browser tabs pid


【解决方案1】:

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

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

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

【讨论】:

  • 好的,非常感谢。我想,作为第二种方法,我将不得不尝试使用计时器方法并每隔几秒钟检查一次浏览器 url 是否有变化..
  • 我对 C# .net 编程有点陌生,但我真正想做的是记录在特定 url 上花费了多少时间。因此,使用上面的代码,我可以检测浏览器何时获得焦点,然后当浏览器是焦点窗口时,启动计时器以不断检查 url 并记录时间,如果 url 与我正在寻找的匹配。并在浏览器失去焦点时停止计时器。我更愿意为此使用事件,但看起来不可能。如果您对我有任何指示或建议,请告诉我。
  • 如果你想可靠地做到这一点,你应该考虑编写浏览器扩展/插件......但你必须为每个主要浏览器写一些东西:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多