I am facing a problem related to get out all the controls from some hooked process. My SpyDll launched into hooked process sucessfully, But when I check the statement
Control control = Control.FromHandle(MainWindowHandle), it returns null into control object where "MainWindowhandle"is just a native main window handle of that hooked process, which you always take from .NET "Process" class after launching that process.
But STRANGLY it happens that in some other hooked process which is the same C# .NET application, it returns valid object of Main "WinForm".
So why it will not work in above case? Are there any exceptions to use "MainWindowHandle" properly. In my case both are seperate .NET managed processes programmed in C#. Any process configuration needs to maintain specially while creating that process?
Regards
Usman
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(); );