Как я могу определить, есть ли у потока дескрипторы окон? - PullRequest
4 голосов
/ 17 декабря 2009

Как программно определить, есть ли у потока дескрипторы окон для данного процесса?

spy ++ дает мне эту информацию, но мне нужно сделать это программно.

Мне нужно сделать это в C #, однако библиотеки диагностики .net не дают мне этой информации. Я полагаю, что Spy ++ использует вызов Windows API, о котором я не знаю.

У меня есть доступ к коду системы, которую я пытаюсь отладить. Я хочу периодически вставлять некоторый код, вызываемый таймером, который будет определять, сколько потоков содержит дескрипторы окон, и регистрировать эту информацию.

спасибо

1 Ответ

3 голосов
/ 18 декабря 2009

Я полагаю, что вы можете использовать функции Win API: EnumWindowsProc для итерации по дескрипторам окна и GetWindowThreadProcessId для получения идентификатора потока и идентификатора процесса, связанных с данным дескриптором окна

Пожалуйста, проверьте, подойдет ли вам приведенный ниже пример:

этот код перебирает процессы и потоки, используя System.Diagnostics; для каждого идентификатора потока я вызываю функцию 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
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...