4

スレッドに特定のプロセスの Windows ハンドルがあるかどうかをプログラムで検出するにはどうすればよいですか?

spy++ はこの情報を提供してくれますが、プログラムで行う必要があります。

C# でこれを行う必要がありますが、.net 診断ライブラリではこの情報が得られません。spy++ は、私が知らない Windows API 呼び出しを使用していると思います。

デバッグしようとしているシステムのコードにアクセスできます。ウィンドウハンドルを含むスレッドの数を検出し、この情報をログに記録するタイマーによって定期的に呼び出されるコードを埋め込みたいと思います。

ありがとう

4

1 に答える 1

3

win api 関数を使用できると思います: EnumWindowsProcを使用してウィンドウ ハンドルを反復処理し、GetWindowThreadProcessIdを使用して特定のウィンドウ ハンドルに関連付けられたスレッド ID とプロセス ID を取得します。

以下の例が当てはまるかどうかを確認してください。

このコードは、System.Diagnostics を使用してプロセスとスレッドを反復処理します。スレッド ID ごとに GetWindowHandlesForThread 関数を呼び出しています (以下のコードを参照)

foreach (Process procesInfo in Process.GetProcesses())
{
    Console.WriteLine("process {0} {1:x}", procesInfo.ProcessName, procesInfo.Id);
    foreach (ProcessThread threadInfo in procesInfo.Threads)
    {
        Console.WriteLine("\tthread {0:x}", threadInfo.Id);
        IntPtr[] windows = GetWindowHandlesForThread(threadInfo.Id);
        if (windows != null && windows.Length > 0)
            foreach (IntPtr hWnd in windows)
                Console.WriteLine("\t\twindow {0:x}", hWnd.ToInt32());
    }
}

GetWindowHandlesForThread の実装:

private IntPtr[] GetWindowHandlesForThread(int threadHandle)
{
    _results.Clear();
    EnumWindows(WindowEnum, threadHandle);
    return _results.ToArray();
}

private delegate int EnumWindowsProc(IntPtr hwnd, int lParam);

[DllImport("user32.Dll")]
private static extern int EnumWindows(EnumWindowsProc x, int y);
[DllImport("user32.dll")]
public static extern int GetWindowThreadProcessId(IntPtr handle, out int processId);

private List<IntPtr> _results = new List<IntPtr>();

private int WindowEnum(IntPtr hWnd, int lParam)
{          
    int processID = 0;
    int threadID = GetWindowThreadProcessId(hWnd, out processID);
    if (threadID == lParam) _results.Add(hWnd);
    return 1;
}

上記のコードの結果は、次のようにコンソールにダンプされます。

...
process chrome b70
    thread b78
        window 2d04c8
        window 10354
...
    thread bf8
    thread c04
...
于 2009-12-18T03:48:51.377 に答える