【问题标题】:Get Window instance from Window Handle从窗口句柄获取窗口实例
【发布时间】:2011-02-25 11:02:19
【问题描述】:

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

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

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

有什么快速的想法吗?

【问题讨论】:

  • 你是说窗把手吗? (不带“r”)您在寻找实际的 .NET 对象吗?
  • 您无法从另一个进程中的 HWND 获取 System.Windows.Window。即使,你想做什么?最终可能有一些方法可以做你想做的事情。

标签: c# .net wpf


【解决方案1】:

尝试以下方法:

IntPtr handle = process.MainWindowHandle;

HwndSource hwndSource = HwndSource.FromHwnd(handle);

Window = hwndSource.RootVisual as Window;

更新:

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

【讨论】:

  • 这行得通。但仅适用于当前应用程序。我可以获得当前 WPF 应用程序的窗口。其他人抛出 NRE 异常。 HwndSource 返回 null。任何其他帮助。
  • @Jawahar - 无法从当前 AppDoamin/Process 外部访问对象(不使用远程处理)。查看我的更新。
  • 有没有其他方法,比如使用非托管代码,比如使用 user32.dll。
  • @Jawahar - 这是一个概念性问题,并非特定于 .NET。您不能跨进程共享相同的对象。假设您从不同的进程中获得了窗口的实例。现在问问自己,如果你改变了这个窗口的一些属性(例如位置)会发生什么?如果有可能,那么任何程序都可以操作任何其他程序的窗口......
  • 有人知道如何反其道而行之吗?我需要从现有的 Window 对象中获取 IntPtr 句柄。
【解决方案2】:

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

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

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

禁止访问驻留在进程堆中的托管对象(或托管进程中的 AppDomain)。此内存受到其他进程的“保护”(1)。

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

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

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

【讨论】:

  • +1 表示“永远找不到”的“移动目标”! (语言整体上非常丰富多彩,但这一个赢得了我)
猜你喜欢
  • 2011-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-22
  • 2013-01-25
  • 2014-01-28
  • 2011-01-28
  • 1970-01-01
相关资源
最近更新 更多