如何检测线程是否有Windows句柄?

4
如何在给定进程中编程检测线程是否存在窗口句柄?
Spy++可以提供此信息,但我需要通过编程实现。
我需要用C#实现这个功能,然而,.net诊断库没有提供这个信息。我想象Spy++是使用一些我不知道的Windows API调用实现的。
我可以访问正在尝试调试的系统的代码。我想嵌入一些由计时器定期调用的代码,以便检测有多少线程包含窗口句柄并记录这些信息。
谢谢。
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
...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接