.NET (C #): получать дочерние окна, когда у вас есть только дескриптор процесса или PID? - PullRequest
22 голосов
/ 17 сентября 2008

Вид особой задачи:

  • Я запускаю процесс с System.Diagnostics.Process.Start(..)
  • Процесс открывает заставку - эта заставка становится главным окном.
  • Заставка закрывается и отображается «реальный» пользовательский интерфейс. Главное окно (заставка) теперь недействительно.
  • У меня все еще есть объект Process, и я могу запросить его дескриптор, модуль и т. Д. Но дескриптор главного окна теперь недопустим.

Мне нужно получить интерфейс процесса (или дескриптор интерфейса) на этом этапе. Предположим, я не могу изменить поведение процесса, чтобы сделать его проще (или разумнее).

Я посмотрел в Интернете, но, признаюсь, я не искал больше часа. Казалось бы, это должно быть несколько тривиально: - (

Ответы [ 9 ]

10 голосов
/ 17 сентября 2008

Если вы не возражаете против использования Windows API, вы можете использовать EnumWindowsProc и проверить каждый из описываемых дескрипторов, используя GetWindowThreadProcessId (чтобы увидеть что это в вашем процессе), а затем, возможно, IsWindowVisible, GetWindowCaption и GetWindowTextLength, чтобы определить, какой hWnd в вашем процессе - тот, который вам нужен.

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

7 голосов
/ 17 сентября 2008

@ ageektrapped находится на правильном пути, однако FindWindow не будет искать дочерние окна.

Для этого вам нужно будет использовать FindWindowEx

3 голосов
/ 27 декабря 2010

Спасибо за ваши ответы. Благодаря вам здесь, я понял, как узнать, находится ли главное окно процесса впереди или нет:

N.B. Конечно, для этого нужны System.Diagnostic и System.Runtime.Interrop

public bool IsWindowActive(Int32 PID)
{
  return IsWindowActive(Process.GetProcessById(PID));
}

[DllImport("user32.dll")]
private static extern
IntPtr GetForegroundWindow();

public bool IsWindowActive(Process proc)
{
  proc.Refresh();
  return proc.MainWindowHandle.Equals(GetForegroundWindow());
}
2 голосов
/ 18 октября 2008

Вы можете обнаружить, что если вы вызовете .Refresh (), вы получите новое окно верхнего уровня.

1 голос
/ 29 октября 2008

Использовать Process.GetProcessById (proc.Id); где proc был твоим заставкой. У меня работает.

Теперь, как получить доступ к свойствам главного окна в System.Windows.Forms, чтобы сфокусировать его без использования win32? В конце концов .net должен быть универсальным решением - не так ли?

1 голос
/ 17 сентября 2008

Насколько я понимаю MainWindowHandle свойство запускаемого вами процесса недопустимо. В этом случае вы можете использовать функцию FindWindow (из Win32 SDK), которая возвращает нужный дескриптор окна. Все, что вам нужно, это имя класса главного окна целевого приложения. Вы можете получить его, используя Spy ++ или Winspector . Вы также должны убедиться, что у вас есть правильное окно, проверив идентификатор этого окна с помощью GetWindowThreadProcessId.

Наконец, я должен сказать, что я не эксперт по Win32, и, возможно, для вашего дела найдется лучшее решение.

1 голос
/ 17 сентября 2008

Если вы знаете заголовок окна, вы можете использовать вызов Win32 FindWindow через P / Invoke.

Вы можете найти подпись здесь на pinvoke.net

0 голосов
/ 10 января 2009

Свойство MainWindowHandle кэшируется после первого доступа, поэтому вы не видите его изменения даже после того, как дескриптор становится недействительным. Информация Грег Узелака верна. Вызов Proces.Refresh заставит следующий вызов Process.MainWindowHandle заново выполнить логику, чтобы найти новый дескриптор главного окна. Логика Майкла также работает, потому что у нового Процесса нет кэшированной версии MainWindowHandle.

0 голосов
/ 10 января 2009

Где-то в коде создается «настоящее» главное окно. Вы можете просто сохранить дескриптор окна в это время, а затем после закрытия заставки вы можете установить Application.MainWindow в реальное окно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...