Как я могу определить, есть ли у потока дескрипторы окон?
Как программно определить, есть ли у потока дескрипторы окон для данного процесса?
Spy++ дает мне эту информацию, но мне нужно сделать это программно.
Мне нужно сделать это в C#, однако библиотеки диагностики.net не дают мне этой информации. Я полагаю, что Spy++ использует некоторые вызовы Windows API, о которых я не знаю.
У меня есть доступ к коду системы, которую я пытаюсь отладить. Я хочу периодически вставлять некоторый код, вызываемый таймером, который будет определять, сколько потоков содержит дескрипторы окон, и регистрировать эту информацию.
Спасибо
1 ответ
Я полагаю, что вы можете использовать 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
...