Подтвердить что ты не робот

Получить экземпляр Window из окна Handle

Я могу получить дескриптор Window из запущенных приложений, используя следующий код.

foreach (ProcessModule module in process.Modules)
{
  if (module.ModuleName.Contains("PresentationFramework.dll") || module.ModuleName.Contains("PresentationFramework.ni.dll"))
  {
    IntPtr window = process.MainWindowHandle;
  }
}

Но я хочу получить экземпляр Window из этого обработчика. Возможно ли это?

Любая быстрая идея?

4b9b3361

Ответ 1

Попробуйте следующее:

IntPtr handle = process.MainWindowHandle;

HwndSource hwndSource = HwndSource.FromHwnd(handle);

Window = hwndSource.RootVisual as Window;

Update:

Но это будет работать только внутри одного и того же AppDomain, потому что в противном случае это означало бы, что вы могли бы обмениваться объектами между различными AppDomains и даже процессами, что, очевидно, невозможно.

Ответ 2

В приложении WPF (или WinForms) в "окно" есть два "объекта" (то есть блоки, содержащие информацию):

  • Объект системного окна.
  • Управляемые объекты, которые "обертывают" системный объект.

Доступ к объекту системного окна осуществляется через дескриптор окна (typeof HWND в неуправляемом коде, IntPtr в управляемом коде). Учитывая обработчик окна, который вы уже получили, вы можете управлять этим окном с помощью методов Window API. Вы можете использовать p/invoke для этого.

Доступ к управляемому объекту, который находится в куче процесса (или AppDomain в случае управляемого процесса), запрещен. Эта память "защищена" от других процессов (1).

Единственный способ, которым объекты могут быть разделены между процессами (или AppDomains), - это маршаллинг, который является совместным усилием со стороны обоих процессов. Это касается даже многих методов Win32 API при обращении к окну в другом процессе. Не все доступ возможен без пользовательской сортировки.

Обратите внимание, что в отличие от WinForms, WPF не использует (обычно) системные окна для элементов управления. Если ваша цель - манипулировать визуальным деревом в другом процессе/домене WPF, вам просто не повезло, если этот процесс не предоставляет какой-то интерфейс автоматизации.

(1) Хотя можно прочитать необработанную память другого процесса, объекты на управляемой куче движутся цели. Их даже никогда не найти, даже если вы можете каким-то образом приостановить сбор мусора в этом процессе.