Получить экземпляр 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 из этого обработчика. Возможно ли это?
Любая быстрая идея?
Ответы
Ответ 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) Хотя можно прочитать необработанную память другого процесса, объекты на управляемой куче движутся цели. Их даже никогда не найти, даже если вы можете каким-то образом приостановить сбор мусора в этом процессе.