2012-05-11 13 views
1

開いているすべてのプロセスのPIDを表示するためにWindowsタスクマネージャを開くと、Chromeブラウザの開いているすべてのタブに独自のPIDがあることがわかります。使用時のフォーカス:C#外部ブラウザの各ブラウザタブに固有のPIDを取得するにはどうすればいいですか? Chrome/Firefox/IE

[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); 

ブラウザのタブを一意に識別する方法を知っている人はいますか?さらに、ブラウザのタブが状態やフォーカスを変更したときにイベントをキャッチする方法を知っている人はいますか?

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"; 

    } 
} 

}

+0

私が知っている唯一のブラウザは、タブごとに異なるプロセスを実際に使用しているブラウザです。ほとんどのブラウザは複数のスレッドを使用します。あなたが常にGetForegroundWindow()から同じプロセスを取得する理由は、開いているタブのプロセスではなく、メインのクロムプロセスを返すためです。 – firthh

+0

@firthh:IE9もマルチプロセスです。 –

+0

IE9には複数のプロセスがありますが、タブごとに1つのプロセスは使用されません。パフォーマンス上の理由から、プロセスごとに複数のタブをホストします。 – snemarch

答えて

3

あなたは何を行うことができるようにするつもりはないされています - 任意のブラウザクロームやFirefox、IE

以下は前面のウィンドウの変更がWinEventHookイベントをキャッチ私の完全なコードですあなたはしたいです - 少なくとも信頼性の高い方法ではありません。

ブラウザの実装方法は異なります。 FireFox以前のIEバージョンでは1プロセスモデルを使用しています。IE9はマルチプロセスですが、パフォーマンス上の理由からプロセスごとにいくつかのタブをグループ化し、Chromeはタブごとに1つのプロセスを実行します。他のブラウザー/ブラウザーのバージョンは、何でもしています(しかし、おそらくはシングルプロセス)。サポートしたいブラウザ用の特定のコードを記述する必要があります。詳細な実装の詳細を扱うことになります。

Chromeの場合、iircモデルはレンダリングを処理する1つの「ホストウィンドウ」です。各タブを処理するプロセスは「ワーカープロセス」で、ホストとワーカーの間で通信を行います... ChromeにワーカープロセスのPIDを取得するための公式のAPIがない場合は、気にしないでください:)

+0

ありがとう、ありがとうございます。私は2番目のアプローチとして、私はタイマーのアプローチを使用し、ブラウザのURLを変更する秒数秒を確認する必要があります.. – MElliott

+0

私はちょっとC#プログラミングに新しいですが、私は本当にやろうとしている特定のURLにどれくらいの時間が費やされたかを記録します。したがって、上記のコードでは、ブラウザがフォーカスを獲得したときにブラウザがフォーカスウィンドウを検出したときに、そのURLが探しているものと一致する場合に、継続的にURLをチェックして時間を記録するタイマーを開始します。ブラウザがフォーカスを失ったときにタイマーを停止します。私はこのためにイベントを使用することを好みましたが、可能であるようには見えません。あなたに私に指針や提案があれば教えてください。 – MElliott

+0

あなたがそれを確実にしたいのであれば、あなたはブラウザの拡張機能/アドオンを書いてみるべきですが、各主要なブラウザのために何かを書く必要があります:) – snemarch

関連する問題