我可以使用以下代码从运行的应用程序中获取Window句柄。
foreach (ProcessModule module in process.Modules)
{
if (module.ModuleName.Contains("PresentationFramework.dll") || module.ModuleName.Contains("PresentationFramework.ni.dll"))
{
IntPtr window = process.MainWindowHandle;
}
}
但是我想从这个处理程序中获取Window实例。有可能吗?
请快点提问?
答案 0 :(得分:11)
尝试以下方法:
IntPtr handle = process.MainWindowHandle;
HwndSource hwndSource = HwndSource.FromHwnd(handle);
Window = hwndSource.RootVisual as Window;
<强>更新强>
但这只能在同一个AppDomain中运行,否则就意味着你可以在不同的AppDomains甚至进程之间共享一个对象,这显然是不可能的。
答案 1 :(得分:7)
在WPF应用程序(或WinForms)中,有两个“对象”(即包含信息的内存块)到“窗口”:
通过窗口句柄(非托管代码中的HWND类型,托管代码中的IntPtr)提供对系统窗口对象的访问。给定一个已经获得的窗口句柄,您可以使用Window API methods操作该窗口。你可以使用p / invoke。
禁止访问驻留在进程堆中的托管对象(如果是托管进程,则访问AppDomain)。该存储器受到其他进程(1)的“保护”。
在进程(或AppDomains)之间共享对象的唯一方法是通过编组,这是两个进程的合作努力。在访问另一个进程中的窗口时,这甚至适用于许多Win32 API方法。如果没有自定义编组,并非所有访问都可以。
请注意,与WinForms不同,WPF(通常)不会将系统窗口用于控件。如果您的目标是操纵另一个WPF进程/域中的可视化树,那么除非该进程提供某种自动化接口,否则您只是运气不好。
(1)虽然可以读取另一个进程的原始内存,但托管堆上的对象是移动目标。即使你能以某种方式暂停该过程的垃圾收集线程,人们也永远都找不到它们。