Why Control.FromHandle(IntPtr) returns null in one hooked process and returns valid object of “Form”? in another hooked process?

旧城冷巷雨未停 提交于 2019-12-05 10:46:26

1.) Keep in mind, that there may be multiple appdomains and you can only get the control-objects of the current appdomain in the current process. Also you have to use the right ruuntime-version afaik, but I am not sure about that.

2.) Why do you want the control handle anyways, it is much more convinient to work with native handles directly, you can even use the native functions from within another process, no dll injection. If you really need the managed control-objects, then check out the Application.OpenForms collection instead of that handle search!

When you create a Control/Form using WinForms the WinForm code will automatically keep an entry that maps the native window handle to the C# instance. When the Control/Form is destroyed that entry is then removed. So all calling Control.FromChildHandle does is search the list of entries to see if it has a matching native handle and if so returns the associated C# instance.

Therefore you will only get back C# entries for Control/Form instances created from WinForms itself. Native windows and native control from attaching to another process will never return an entry. That is why is does not work for you and never will and also why you get back a valid class when working with a C# application which has used WinForms to create the window.

This is due to the fact that the function you are calling "Control.FromHandle" uses a hash table to lookup the control instance from it's handle. So when you call this method for an HWND that does not have a control instance you will get null.

To use an HWND you should use the Win32 Messaging API via PInvoke calls. For instance, You can use SendMessage to send a WM_GETTEXT message to query the window's text. For some of these messages there are various wrappers in the Win32 Windowing API like GetWindowText which wrap the above message.

Have you looked into using Control.FromChildHandle? It will search the control chain until it finds a control associated with that handle.

In your first case it might not be a direct descendant.

For any given AppDomain the non-static members of a type of T live in an entity (an instance of T). The static members of a type ot T live in a another single entity (the type T itself). So effectively a type or instance of T in one AppDomain is different from a type or instance of T in another AppDomain. This means that Control.FromHandle only makes sense if the returned instance is in the same AppDomain as the calling method, otherwise it has to return a null.

To work with another AppDomain you need some COM style coding, something like (psuedocode):

runtimes = IClrMetaHost.EnumerateLoadedRuntimes(processHandle);
host = runtime[0].GetInterface( ICorRuntimeHost );
appdomains = host.EnumDomains();
appdomains[0].CallBack( () => dosomething(); );
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!