6

我面临一个与从某个挂钩进程中取出所有控件有关的问题。我的 SpyDll 成功启动到钩子进程,但是当我检查语句时

Control control = Control.FromHandle(MainWindowHandle),它将 null 返回到控制对象,其中“MainWindowhandle”只是该挂钩进程的本机主窗口句柄,在启动该进程后,您总是从 .NET“Process”类中获取该句柄。

但奇怪的是,在同一个 C# .NET 应用程序的其他一些挂钩进程中,它返回 Main“WinForm”的有效对象。

那么为什么它在上述情况下不起作用呢?正确使用“MainWindowHandle”是否有任何例外。在我的情况下,两者都是用 C# 编程的单独的 .NET 托管进程。在创建该流程时,是否需要特别维护任何流程配置?

问候乌斯曼

4

5 回答 5

1

当您使用 WinForms 创建控件/表单时,WinForm 代码将自动保留将本机窗口句柄映射到 C# 实例的条目。当控件/表单被销毁时,该条目将被删除。因此,所有调用 Control.FromChildHandle 所做的只是搜索条目列表以查看它是否具有匹配的本机句柄,如果有,则返回关联的 C# 实例。

因此,您只能取回从 WinForms 本身创建的 Control/Form 实例的 C# 条目。附加到另一个进程的本机窗口和本机控件将永远不会返回条目。这就是为什么 is 对您不起作用并且永远不会起作用的原因,也是您在使用使用 WinForms 创建窗口的 C# 应用程序时返回有效类的原因。

于 2011-06-29T10:31:14.830 回答
1

这是因为您调用的函数“Control.FromHandle”使用哈希表从它的句柄中查找控件实例。因此,当您为没有控件实例的 HWND 调用此方法时,您将得到 null。

要使用 HWND,您应该通过 PInvoke 调用使用 Win32消息传递 API 。例如,您可以使用SendMessage发送WM_GETTEXT消息来查询窗口的文本。对于其中一些消息,Win32 窗口化 API中有各种包装器,例如GetWindowText,它们包装了上述消息。

于 2011-07-18T18:16:45.177 回答
0

您是否考虑过使用Control.FromChildHandle?它将搜索控制链,直到找到与该句柄关联的控件。

在您的第一种情况下,它可能不是直系后代。

于 2011-06-28T16:18:10.997 回答
0

1.) 请记住,可能有多个应用域,您只能在当前进程中获取当前应用域的控制对象。此外,您必须使用正确的 runtime-version afaik,但我不确定。

2.) 你为什么要控制句柄,直接使用本机句柄更方便,你甚至可以在另一个进程中使用本机函数,没有 dll 注入。如果您确实需要托管控件对象,请查看Application.OpenForms集合而不是那个句柄搜索!

于 2011-07-17T20:45:50.077 回答
0

对于任何给定的 AppDomain,T 类型的非静态成员存在于实体(T 的实例)中。类型 ot T 的静态成员存在于另一个单一实体(类型 T 本身)中。因此,一个 AppDomain 中的 T 类型或实例实际上不同于另一个 AppDomain 中的 T 类型或实例。这意味着 Control.FromHandle 仅在返回的实例与调用方法位于同一 AppDomain 时才有意义,否则它必须返回 null。

要使用另一个 AppDomain,您需要一些 COM 风格的编码,例如(伪代码):

runtimes = IClrMetaHost.EnumerateLoadedRuntimes(processHandle);
host = runtime[0].GetInterface( ICorRuntimeHost );
appdomains = host.EnumDomains();
appdomains[0].CallBack( () => dosomething(); );
于 2011-07-19T12:57:22.200 回答