2011-02-25 12 views
12

Puedo obtener un identificador de ventana para ejecutar aplicaciones usando el siguiente código.Obtención de instancia de ventana desde el controlador de ventana

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

Pero quiero obtener la instancia de Windows desde este controlador. ¿Es posible?

¿Alguna idea rápida, por favor?

+0

¿Quiere decir Window Handle? (sin la 'r') ¿Estás buscando el objeto .NET real? –

+0

Me refiero a la manija de la ventana. – Jawahar

+0

No puede obtener System.Windows.Window desde un HWND en otro proceso. Aunque, ¿qué estás tratando de hacer? Puede haber algunas maneras de hacer lo que intenta hacer al final. –

Respuesta

11

intente lo siguiente:

IntPtr handle = process.MainWindowHandle; 

HwndSource hwndSource = HwndSource.FromHwnd(handle); 

Window = hwndSource.RootVisual as Window; 

Actualización:

Pero esto sólo funcionará dentro del mismo dominio de aplicación, porque de lo contrario significaría que usted podría compartir un objeto a través de diferentes dominios de aplicación e incluso los procesos , lo cual es obviamente imposible.

+0

Esto funciona. Pero solo para la aplicación actual. Puedo obtener una ventana para la aplicación WPF actual. Otros lanzando la excepción NRE. HwndSource devuelve nulo. Cualquier otra ayuda. – Jawahar

+0

@Jawahar: es imposible acceder a un objeto desde fuera del proceso/proceso de aplicación actual (sin utilizar el control remoto). Ver mi actualización –

+0

¿Hay alguna otra manera como usar código no administrado, digamos usando user32.dll. – Jawahar

6

En una aplicación WPF (o WinForms) hay dos 'objetos' (es decir bloques de memoria que contiene información) a una 'ventana':

  1. El sistema de ventana de objeto.
  2. Los objetos gestionados que 'envuelven' el objeto del sistema.

El acceso al objeto ventana del sistema se proporciona a través del controlador de la ventana (tipo de HWND en código no administrado, IntPtr en código administrado). Dado un identificador de ventana, que ya ha obtenido, puede manipular esa ventana con el Window API methods. Puede usar p/invoke para esto.

El acceso al objeto gestionado, que reside en el montón del proceso (o AppDomain en el caso de un proceso gestionado) está prohibido. Esta memoria está 'protegida' de otros procesos (1).

La única forma en que los objetos se pueden compartir entre los procesos (o AppDomains) es a través de la ordenación, que es un esfuerzo cooperativo por parte de ambos procesos. Esto se aplica incluso a muchos de los métodos API de Win32 cuando se accede a una ventana en otro proceso. No todo el acceso es posible sin una clasificación personalizada.

Tenga en cuenta que, a diferencia de WinForms, WPF no usa (normalmente) las ventanas del sistema para los controles. Si su objetivo es manipular el árbol visual en otro proceso/dominio de WPF, simplemente no tiene suerte a menos que ese proceso proporcione algún tipo de interfaz de Automatización.

(1) Si bien es posible leer la memoria bruta de otro proceso, los objetos en un montón administrado son objetivos en movimiento. Uno nunca podría encontrarlos, incluso si de alguna manera pudiera suspender el hilo de recolección de basura de ese proceso.

+0

+1 para los "objetivos en movimiento" que "uno nunca podría encontrar"! (El lenguaje es extremadamente colorido en general, pero este me ganó) –

Cuestiones relacionadas