16

I am able get a Window handle from running applications using the following code.

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

But I want to get the Window instance from this handler. Is it possible?

Any quick idea please?

2
  • Do you mean Window Handle? (without the 'r') Are you looking for the actual .NET object? Commented Feb 25, 2011 at 11:06
  • You can't get a System.Windows.Window from a HWND in another process. Even though, what are you trying to do? There may be some ways to do what you're trying to do in the end. Commented Feb 25, 2011 at 15:49

2 Answers 2

12

Try the following:

IntPtr handle = process.MainWindowHandle;

HwndSource hwndSource = HwndSource.FromHwnd(handle);

Window = hwndSource.RootVisual as Window;

Update:

But this will work only inside the same AppDomain, because otherwise it would mean that you could share an object across different AppDomains and even processes, which is obviously impossible.

Sign up to request clarification or add additional context in comments.

5 Comments

This works. But only for the current application. I can get window for the current WPF application. Others throwing NRE exception. The HwndSource returning null. Any other help.
@Jawahar - It is impossible to access an object from outside the current AppDoamin/Process (without using Remoting). See my update.
Is there any other way like using unmanaged code, say using user32.dll.
@Jawahar - This is a conceptual issue, not specific to .NET. You cannot share the same objects across processes. Lets say you got the instance of a window from a different process. Now ask yourself, what should happen if you change some properties of this window (e.g. position)? If it was possible, then any program could manipulate windows of any other program...
Does anybody have an idea how to do the opposite? I need to get IntPtr handle from existing Window object.
9

In a WPF application (or WinForms) there are two 'objects' (that is blocks of memory containing information) to a 'window':

  1. The system window object.
  2. The managed objects that 'wraps' the system object.

Access to the system window object is provided through the window handle (typeof HWND in unmanaged code, IntPtr in managed code). Given a window handle, which you already obtained, you can manipulate that window using the Window API methods. You can use p/invoke for this.

Access to the managed object, which resides in the heap of the process (or AppDomain in the case of a managed process) is forbidden. This memory is 'protected' from other processes(1).

The only way that objects can be shared between processes (or AppDomains) is through marshalling which is a cooperative effort on the part of both processes. This applies even to many of the Win32 API methods when accessing a window in another process. Not all access is possible without custom marshalling.

Note that unlike WinForms, WPF does not (normally) use system windows for controls. If your aim is to manipulate the visual tree in another WPF process/domain, you're simply out of luck unless that process provides some sort of Automation interface.

(1) While it is possible to read the raw memory of another process, objects on a managed heap are moving targets. One could never even find them, even if you could somehow suspend the garbage collecting thread of that process.

1 Comment

+1 for the "moving targets" that "one could never even find"! (the language is extremely colorful overall but this one won me over)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.