views:

96

answers:

1

How can I programmatically detect if a thread has windows handles on it for a given process?

spy++ gives me this information but I need to do it programmatically.

I need to do this in C#, however the .net diagnostics libs don't give me this information. I imagine spy++ is using some windows api call that I don't know about.

I have access to the code of the system I'm trying to debug. I want to embed some code called by a timer periodically that will detect how many thread contain windows handles and log this info.

thanks

+1  A: 

I believe you can use win api functions: EnumWindowsProc to iterate through window handles and GetWindowThreadProcessId to get the thread id and process id associated with given window handle

Please check if an example below would work for you:

this code iterates through processes and threads using System.Diagnostics; for each thread ID I'm calling GetWindowHandlesForThread function (see code below)

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 implementation:

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

result of the code above should dump into console smth like this:

...
process chrome b70
    thread b78
     window 2d04c8
     window 10354
...
    thread bf8
    thread c04
...
serge_gubenko
Many Thanks!!! That is exactly what I needed.
Dale Moody