Pregunta

Fondo

Estoy usando SendKeys() para enviar comandos de teclado para la ventana activa, pero no estoy teniendo ninguna suerte para encontrar la ventana secundaria cuando la aplicación se está ejecutando a través de RemoteApp. Todo funciona como se esperaba cuando corro la aplicación localmente.

Microsoft RemoteApp permite a los usuarios se conectan a aplicaciones a través del protocolo RDP, pero en vez de mostrar la totalidad de la máquina virtual a distancia, sólo se muestra la ventana de la aplicación. Para el usuario final, no hay diferencia entre una aplicación que se ejecuta en virtud de RemoteApp y que se ejecuta en su escritorio.

He estado usando ManagedSpy para determinar el nombre de la clase de la ventana de la aplicación .NET de modo que pueda utilizar la función de API Win32 FindWindowEx para hacer una de las ventanas hijo activos, y funciona bien. Sin embargo, estoy teniendo un problema cuando la aplicación se está ejecutando más de RemoteApp.

Todavía puedo utilizar el Process.GetProcessesByName() .NET para encontrar la aplicación, sólo tiene que tener que invocar mstsc.exe:

IntPtr hwndChild = IntPtr.Zero;
Process[] processess = Process.GetProcessesByName("mstsc");
IntPtr appHandle = IntPtr.Zero;

foreach (Process p in processess)
{
    if ((p.MainWindowHandle != IntPtr.Zero))
    {
        appHandle = p.MainWindowHandle;
    }
}

if (appHandle == IntPtr.Zero)
{
    MessageBox.Show("Application is not Running.");
    return;
}

Sin embargo, no puedo usar FindWindowEx de la misma manera. Esta pregunta gira en torno a eso.

Para que el código no administrado a decirme lo que tiene ventanas mstsc.exe activa, que utiliza Spy ++, pero para mstsc.exe se vuelve con un nombre de clase diferente, llamada RAIL_WINDOW:

text alt

Este es el código que estoy usando para encontrar la ventana Niño:

[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);

[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
hwndChild = FindWindowEx(appHandle, IntPtr.Zero, "RAIL_WINDOW", "MyApplication (Remote)");
SetForegroundWindow(hwndChild);

Preguntas

  1. Me puede utilizar Spy ++ para resaltar la ventana secundaria activa en la versión de RemoteApp de la aplicación, y me sale RAIL_WINDOW, pero me parece que no puede acceder a esta ventana mediante programación. Teniendo en cuenta el código anterior, lo que me falta para ser capaz de hacerlo?

  2. ¿Hay otras maneras de enviar pulsaciones de teclas a una aplicación que se ejecuta a través de la aplicación remota?

¿Fue útil?

Solución

Saber cómo Microsoft hace las cosas, apuesto a la "ventana de ferrocarril" no es más que un proxy mudo, local que no se molestó en respuesta a lo que es el envío de SendKeys. No he mirado, pero apuesto a que termina el envío de mensajes WM_CHAR, a la que un proxy tonto probablemente no se molestaría en responder. En su lugar, intente enviar mensajes que WM_KEYUP y WM_KEYDOWN manualmente y ver si funciona, ya que espero que transmitiría los clics del ratón y (y qué no) en lugar de las versiones traducidas.

Otros consejos

¿Qué comandos estamos enviando usando SendKeys()?

Puede ser mejor para buscar una solución alternativa en lugar de utilizar SendKeys `()'.

Y es probable que pueda aprovechar las ventajas de manejar IMsTscAxEvents :: OnRemoteWindowDisplayed caso de que le da el identificador de ventana adecuada en el momento adecuado sin llamar FindWindowEx, etc.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top