Мне было интересно, как бы я поступил так, поскольку я пробовал множество различных функций user32 и проводил всесторонние исследования в Интернете, но, к сожалению, пока не смог найти решение.
Существует приложение, которое имеет 5 потоков.Доступ к этим потокам может быть легко осуществлен с помощью метода GetProcessById класса .NET, при условии PID процесса.Однако не похоже, что есть функция, которую я могу использовать для предоставления идентификатора потока и перечисления его окон (родительского или дочернего).В одной из этих тем всего 10 окон, 9 скрытых и одно видимое.Название этой видимой темы - то, что я пытаюсь получить программно.
Мой последний подход состоял в том, чтобы захватить дескриптор процесса, поместить его через EnumChildWindows и попытаться таким образом добавить каждый дескриптор окна в коллекцию, но моя коллекция всегда пуста.
Вот скриншот того, что я вижу в инструменте ProcessThreadsView:
Что-то мне не хватает?Я написал автору инструмента по электронной почте, чтобы увидеть, как он это делает, но я решил попросить вас, ребята, посмотреть, есть ли установленный подход.
Обновление: Я пытался использоватьGetGUIThreadInfo, вот как я это называю:
[StructLayout(LayoutKind.Sequential)]
public struct Rect
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
[StructLayout(LayoutKind.Sequential)]
public struct GUITHREADINFO
{
public uint cbSize;
public uint flags;
public IntPtr hwndActive;
public IntPtr hwndFocus;
public IntPtr hwndCapture;
public IntPtr hwndMenuOwner;
public IntPtr hwndMoveSize;
public IntPtr hwndCaret;
public Rect rcCaret;
}
static IEnumerable<IntPtr> EnumerateThreadWindowHandlesByProcessId(int processId)
{
List<IntPtr> threadWindowHandles = new List<IntPtr>();
foreach (ProcessThread thread in Process.GetProcessById(processId).Threads)
{
GUITHREADINFO threadInfo = new GUITHREADINFO();
threadInfo.cbSize = (uint)Marshal.SizeOf(threadInfo);
bool returnValue = GetGUIThreadInfo((uint)thread.Id, out threadInfo);
threadWindowHandles.Add(threadInfo.hwndActive);
}
return threadWindowHandles;
}
Обновление 2:
Используя EnumThreadWindows, вот что я получил:
public delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam);
[DllImport("user32.dll")]
static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);
private static bool ThreadWindows(IntPtr handle, IntPtr param)
{
//get window from handle later, testing for now
logger.Info("foo bar");
return true;
}
[STAThread]
public void Execute()
{
Process[] processes = Process.GetProcessesByName("MyProcessName");
Process processOfInterest = processes[0];
foreach (ProcessThread thread in processOfInterest.Threads)
{
EnumThreadWindows(thread.Id, new EnumThreadDelegate(ThreadWindows), IntPtr.Zero);
}
}