6

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

Usman
  • 2,742
  • 4
  • 44
  • 82

5 Answers5

1

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.

Phil Wright
  • 22,580
  • 14
  • 83
  • 137
  • @ Phil : I am not talking about native porcesses :-) Both processes are managed process BTW. But Taking the native window handle of one process is the WAY to reach you that processes main Form Window. This is not meant that I am finding a native process main window handle. The process is still managed, and always to me , you have to use this handle for getting the controls inside the MainForm of hooked MANAGED process. Now you can understand this strange problem. But the fact is one process is created inside VS2010, of whome always Control.FromHandle(MainWindowHandle) – Usman Jun 29 '11 at 12:10
  • @Phile continue : returns valid object of WinForm which contained child controls , while other process was being CONVERTED FROM BACK VERSIONS OF VS2008 to VS2010, and here it fails to return the same object...:-( – Usman Jun 29 '11 at 12:11
  • Aha, I didn't realise that. In that case I do not know the answer. You could try stepping through the base class code to see what is happening. – Phil Wright Jun 30 '11 at 02:09
  • You may want to look at `Form.CreateHandle()` method. When a Form is created it doesn't necessarily has a native handle right away. So it would be best if a constructor for that form actually called it first thing to ensure that. – Sergei Z Jul 13 '11 at 04:36
1

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.

csharptest.net
  • 62,602
  • 11
  • 71
  • 89
  • 1
    but i mentioned in detail , with bottom to one of, that everything was working as per expectation 100% correctly , when the process was developed unver VS2010 tested under same IDE and code. But when code was developed under VS2008 and converted back to V2010 , there at that point Control.FromHandle(Hwnd) returns null. So what is this? If you know little more elaboration and understanding check bottom discussion between me and "PhilWright". – Usman Jul 19 '11 at 09:51
  • Load both versions in WinDiff and see what changed. – hoodaticus Jul 19 '11 at 16:50
0

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.

Brandon Moretz
  • 7,512
  • 3
  • 33
  • 43
  • I checked out on your suggestion. This one also returning null as well in 2nd case where Contro.FromHandle(IntPtr) was returning null. In other case where proper "Form" object is returned, same is returned as well now.. – Usman Jun 28 '11 at 19:00
  • I detected the problem, the process of whome Control.FromHandle returns null, this project was being converted from some older version to VS2010. Might be, although this should also work, but i don't know Why..? – Usman Jun 28 '11 at 19:47
  • @Usman This should be agnostic of the IDE it was created in, the Windows should behave the same no matter what as they're all created the same though the Windows API. Are there any other distinguishing characteristics between the two applications ? – Brandon Moretz Jun 28 '11 at 21:51
  • How to check that? via .NET Reflector or via PE Processors? as Yes agree!! This is a strange problem and it should not occur any more. I need to make my framework compatible with back VS created processes as well. It should not behave like this. How can I check it out that both processes are different and VS 2008 might have added some extra flag during project build which is not properly detected by VS 2010. Project runs fine, but problem comes when I query to MainForm of that process to give me all of its child controls via Control.FromHandle(MainWindowHandle). – Usman Jun 29 '11 at 07:37
  • sorry its PE Explorers not processor – Usman Jun 29 '11 at 07:44
0

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!

Zotta
  • 2,513
  • 1
  • 21
  • 27
  • I have only handle of the process which I need to hook and another dll I need to inject. So how can I collect "Forms" or can use Application.OpenForms for taking Control handles. Remember this issue always occure, if some app VS 9.0 app is attached with VS 2010 (i.e if some VS 2010 process hooks VS 2008 or VS 2003,2005) apps, NO CONTROL HANDLE or main FORM HANDLE is returned when use IntPtr Process handle. – Usman Aug 19 '11 at 11:23
0

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(); );
jyoung
  • 5,071
  • 4
  • 30
  • 47