C# 从窗口句柄获取窗口实例

C# 从窗口句柄获取窗口实例,c#,.net,wpf,C#,.net,Wpf,我可以通过使用以下代码运行应用程序来获取窗口句柄 foreach (ProcessModule module in process.Modules) { if (module.ModuleName.Contains("PresentationFramework.dll") || module.ModuleName.Contains("PresentationFramework.ni.dll")) { IntPtr window = process.MainWindowHandle

我可以通过使用以下代码运行应用程序来获取窗口句柄

foreach (ProcessModule module in process.Modules)
{
  if (module.ModuleName.Contains("PresentationFramework.dll") || module.ModuleName.Contains("PresentationFramework.ni.dll"))
  {
    IntPtr window = process.MainWindowHandle;
  }
}
但是我想从这个处理程序中获取窗口实例。可能吗

有什么好主意吗?

试试以下方法:

IntPtr handle = process.MainWindowHandle;

HwndSource hwndSource = HwndSource.FromHwnd(handle);

Window = hwndSource.RootVisual as Window;
更新:

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

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

  • 系统窗口对象
  • “包装”系统对象的托管对象
  • 通过窗口句柄(非托管代码中的typeof HWND,托管代码中的IntPtr)提供对系统窗口对象的访问。给定已获得的窗口句柄,可以使用。您可以为此使用p/invoke

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

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

    请注意,与WinForms不同,WPF(通常)不使用系统窗口进行控件。如果您的目标是在另一个WPF进程/域中操纵可视化树,那么您就太倒霉了,除非该进程提供某种自动化接口


    (1) 虽然可以读取另一个进程的原始内存,但托管堆上的对象是移动目标。即使您可以以某种方式挂起该进程的垃圾收集线程,也无法找到它们。

    您是指窗口句柄吗?(不带“r”)是否正在查找实际的.NET对象?无法在另一个进程中从HWND获取System.Windows.Window。尽管如此,你想做什么?也许有一些方法可以完成你最终想要做的事情,这很有效。但仅适用于当前应用程序。我可以获取当前WPF应用程序的窗口。其他人抛出NRE异常。HwndSource返回null。任何其他帮助。@Jawahar-无法从当前AppDoAdmin/进程外部访问对象(不使用远程处理)。请参阅我的更新。是否有其他类似于使用非托管代码的方法,例如使用user32.dll。@Jawahar-这是一个概念性问题,不特定于.NET。不能跨进程共享相同的对象。假设您从另一个进程获得了一个窗口实例。现在问问自己,如果更改此窗口的某些属性(例如位置),会发生什么情况?如果可能的话,那么任何程序都可以操纵任何其他程序的窗口……有人知道如何做相反的事情吗?我需要从现有的窗口对象中获取IntPtr句柄。+1表示“永远都找不到”的“移动目标”!(这门语言总体上非常丰富多彩,但这门语言赢得了我的好感)