从Window Handle获取Window实例

我可以使用以下代码从运行的应用程序中获取Window句柄。

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

但我想从这个处理程序中获取Window实例。 可能吗?

有什么好主意吗?

请尝试以下方法:

 IntPtr handle = process.MainWindowHandle; HwndSource hwndSource = HwndSource.FromHwnd(handle); Window = hwndSource.RootVisual as Window; 

更新:

但这只能在同一个AppDomain中运行,否则就意味着你可以在不同的AppDomain甚至进程之间共享一个对象,这显然是不可能的。

在WPF应用程序(或WinForms)中,有两个“对象”(即包含信息的内存块)到“窗口”:

  1. 系统窗口对象。
  2. “包装”系统对象的托管对象。

通过窗口句柄(非托管代码中的HWND类型,托管代码中的IntPtr)提供对系统窗口对象的访问。 给定一个已经获得的窗口句柄,您可以使用Window API方法操作该窗口。 你可以使用p / invoke。

禁止访问驻留在进程堆中的托管对象(如果是托管进程,则为AppDomain)。 该存储器受到其他进程的“保护”(1)。

在进程(或AppDomains)之间共享对象的唯一方法是通过编组,这是两个进程的合作努力。 在访问另一个进程中的窗口时,这甚至适用于许多Win32 API方法。 如果没有自定义编组,并非所有访问都可以。

请注意,与WinForms不同,WPF(通常)不会使用系统窗口进行控制。 如果您的目标是操纵另一个WPF进程/域中的可视树,那么除非该进程提供某种自动化接口,否则您只是运气不好。

(1)虽然可以读取另一个进程的原始内存,但托管堆上的对象是移动目标。 即使你能以某种方式暂停该进程的垃圾收集线程,人们也永远都找不到它们。