c# - AutoIT, o botón User32 haciendo clic en trabajar esporádicamente
windows automation (3)
Estoy tratando de automatizar las pruebas de una aplicación, y estoy atascado en un problema que me cuesta solucionarlo.
La aplicación tiene botones de Windows estándar, y he intentado con AutoIT y el dll de User32 hacer clic en algunos de estos botones. A veces los botones se hacen clic correctamente (¡yay!) Y a veces fallan (¡abucheo!) - pero lo que es peor, AutoIT está convencida de que hizo clic en el botón (¡doble boo!) Que luego genera falsos positivos (¡triple boo!). Cuando vi que estaba convencido, me refiero a que el clic fue exitoso cuando no lo era.
Estoy ejecutando la aplicación en Win Server 2K8, esta aplicación no tiene nada de especial, aparte de que usa ventanas MDI, y algunos de los botones están en ventanas MDI. Algunos, sin embargo, no están dentro de las ventanas de MDI (ventana de inicio de sesión, por ejemplo, antes de que se cree la ventana principal).
Aquí está mi orden de comandos:
Buscar el botón en la ventana (éxito, siempre) Poner la ventana en primer plano (éxito) Activar la ventana (éxito) Activar el botón (éxito) Enfocar el botón (éxito) Si el botón está enfocado y el botón está habilitado, entonces Pinchalo. (Éxito / Fracaso, comportamiento impredecible. No puedo precisar por qué tiene éxito a veces, y por qué a veces falla ...)
Otros detalles:
En ocasiones, se hace clic en el pedido, que debería abrir otra ventana. Esa ventana está cerrada, luego se vuelve a hacer clic en el botón, y esta vez no sucede nada. Otras veces funciona como se esperaba.
Me estoy ejecutando como administrador y UAC está completamente deshabilitado.
No es un problema de tiempo, que yo sepa, porque me aseguro de que el botón esté enfocado y habilitado antes de intentar hacer clic en él, y veo que el botón capta la atención enfocada.
Y como mencioné, también he intentado esto con solo una simple llamada a User32 / SendMessage, y esto también falla.
Por último, pero no menos importante, esto no ocurre cuando interactúo manualmente con la aplicación. Siempre he tenido clics en los botones reales.
¿Alguna idea?
ACTUALIZAR
Aquí hay otra variable a la ecuación que debería haber mencionado: esto está sucediendo en una máquina virtual (porque ahí es donde necesito ejecutarla). Puedo hacer algunas pruebas limitadas en mi propia máquina, pero para obtener algunas pruebas verdaderas, debe estar en la máquina virtual. Al hacer clic en mi propio cuadro dev parece ser confiable, lo que hace que esto sea aún más desconcertante.
He estado probando esto en otra VM, y también parece estar funcionando allí. En cuanto a las dos máquinas virtuales, están ejecutando la misma versión de Windows, la misma versión de mi aplicación, la misma versión de AutoIT, etc.
Lo reduje a un detalle, que, por suerte, no puedo configurarlo y tengo que poner un ticket para cambiar cualquier configuración. La diferencia en configuraciones es esta:
En la máquina virtual que no funciona, el administrador del dispositivo muestra un mouse que es un mouse vmware. En la VM que está funcionando, el administrador de dispositivos muestra un mouse que es PS / 2 mouse. Obviamente, ambos son ratones de software, pero me pregunto ahora si el mouse VMWare podría estar actuando de manera diferente, y haciendo que los clics de los botones no siempre funcionen. No estoy seguro de qué tan probable sea esta solución, porque según entiendo, usar la llamada Send32 de User32 en realidad no usa el mouse, sino que envía el mismo mensaje que el mouse habría enviado, pero vale la pena intentarlo ...
Usted dice que ha enfocado con éxito el botón, ¿ha intentado enviar un evento de la Spacebar
lugar de un MouseClick
?
Send("{SPACE}")
(Creo que esa es la sintaxis. No soy realmente un AutoIt regular)
La barra espaciadora generalmente se puede usar para interactuar con la mayoría de los controles clicables, como botones y casillas de verificación. En mi experiencia, los clics de mouse simulados e incluso ControlClicks
son mucho menos confiables que las pulsaciones de teclado por razones raras e inconsistentes. Mis condolencias.
En cuanto a detectar que se hace clic en el botón, quizás lo más fácil sea hacer que el botón realice un cambio en la forma que AutoIT
puede detectar. Por ejemplo, una etiqueta de estado que dice Ready
hasta que el usuario presiona el botón. Cuando el usuario presiona el botón, el texto cambia a Processing
. Si es necesario, puede hacer que la etiqueta sea invisible (o colocada fuera de los límites del formulario), de modo que el usuario no pueda verla, pero AutoIt puede hacerlo.
He simulado tu caso y funciona al 100% en Windows 7 :
using System.Runtime.InteropServices;
[DllImport("user32.dll", SetLastError = true)]
static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo);
void ClickFocusedControl()
{
const uint KEYEVENTF_EXTENDEDKEY = 0x1;
const uint KEYEVENTF_KEYUP = 0x2;
keybd_event(13, Convert.ToByte(0), KEYEVENTF_EXTENDEDKEY, UIntPtr.Zero); //Generates a KEY_DOWN
keybd_event(13, Convert.ToByte(0), KEYEVENTF_KEYUP, UIntPtr.Zero); // Generates a KEY_UP
}
Probablemente haya tenido éxito al resolver este problema cuando publicó esta pregunta, pero todavía no hay una buena respuesta, así que publicaré la mía:
Tuve el mismo problema en una máquina virtual que ejecuta Windows Server 2008 R2: no pude enviar una pulsación de tecla ni hacer nada a través de Win32 API SendMessage a un programa en particular (y su ventana principal).
De acuerdo con este Q / A , este es un problema UIPI (que está allí desde Windows Vista). Simplemente debe desactivar su UAC para resolver este problema. Lo probé y funciona. Se pueden encontrar más alternativas a través del enlace que proporcioné.