2012-01-13 13 views
10

Tengo un programa con una interfaz GUI cuya configuración inicial debo hacer manualmente. AutoIt ha sido extraordinariamente útil hasta ahora, ya que proporciona formas muy sencillas de trabajar incluso con objetos de interfaz gráfica de usuario de acceso complejo (listas desplegables, menús de aparición de vuelo, etc.).Obtención de Python y AutoIT para trabajar juntos con win32com: ¿qué pasa con esos identificadores de ventana?

Sin embargo, se necesita el guión que finalmente voy a necesitar con el fin de realizar la configuración del programa que pasar una matriz grande/lista de variables - hay un montón de los diferentes parámetros que necesitan ser cambiadas.

He establecido la lógica para decidir qué estas variables de configuración usarán una secuencia de comandos de Python. Ahora estoy tratando de descubrir cómo hacer que Python y AutoIt hablen entre sí.

Llamar a un script de AutoIt personalizado desde la línea de comandos con Python está fuera de cuestión debido a la gran cantidad de variables que deberían pasarse. No se siente bonito Podría intentar que Python escriba un "archivo de clave" AutoIt, que AutoIt podría leer para establecer sus variables iniciales, pero me gustaría asegurarme de haber agotado todas las opciones para que Python trabaje directamente con AutoIt primero.

Para ese fin, he estado tratando de usar Python junto con la biblioteca win32com para interactuar con AutoIt. Las cosas parecen estar funcionando bien, siempre y cuando haga referencia a ventanas/menús/objetos por sus títulos de cadena en lugar de sus identificadores (¿memoria?). Esto es problemático, ya que mis scripts de configuración pueden estar ejecutándose en paralelo, configurando dos o más archivos separados al mismo tiempo. Si este es el caso, abrir un cuadro con una cadena de título "Abrir archivo ..." en cada archivo al mismo tiempo podría confundir las cosas.

La forma obvia de evitar esto en AutoIt es trabajar con los "controles" de los objetos en cuestión, que creo que son direcciones de memoria de algún tipo, en lugar de sus títulos de cadena. Supongo que estas son direcciones de memoria como la herramienta AutoIt Window Info, cuando se apunta a una opción de ventana/GUI en particular lista un número hexadecimal como el valor del identificador del objeto.

AutoIt tiene un conjunto de funciones que obtienen los mangos de las ventanas, menús, etc. Se llevan a cabo en la DLL de AutoIt COM, pero no hemos sido capaces de llegar a trabajar en Python. Las funciones de manejo devuelven un objeto Unicode en Python, no una cadena hexadecimal como en AutoIt. Creo que esta es la razón por la cual las funciones que luego intentan usar este "handle" en Python no funcionan.

Ejemplo:

autoIt = win32com.client.Dispatch("AutoItX3.Control") 
windowHandle = autoIt.WinGetHandle(knownWindowTitle) 
returnedWindowTitle = autoIt.WinGetTitle(windowHandle) 

Por lo general, returnedWindowTitle y knownWindowTitle no coinciden como returnedWindowTitle siempre parece ser "0". ¿Qué está pasando aquí?

¿Hay otras formas en que puedo llamar a las funciones personalizadas de AutoIt aparte de usar win32com, la línea de comandos o usar un archivo de claves AutoIt?

Gracias por su ayuda.

EDIT: Olvidé mencionar que las cadenas Unicode de hecho coinciden con los números hexadecimales que obtengo cuando imprimo la variable de manejo en AutoIt.

Por ejemplo, en Python, la variable de asa cuando se imprime me da u'000C0326 '. En AutoIt me da '0x000C0326'.

EDITAR: Algunos ensayos basados ​​en las sugerencias de Mat:

In: autoIt = win32com.client.Dispatch("AutoItX3.Control") 
In: mainWindowTitle = "Untitled" 
In: mainWindowHandle = autoIt.WinGetHandle(mainWindowTitle) 
In: mainWindowHandle 
Out: u'000204AC' 
In: testHandle = int(mainWindowHandle, 16) 
In: testHandle 
Out: 132268 
In: autoIt.WinGetTitle(testHandle) 
Out: u'0' 

EDITAR: descubrí el tipo del objeto identificador de ventana: es un objeto de Microsoft HWND. AutoIt tiene una función que puede "convertir" un número de base 16 en un objeto HWND (es decir, encontrar el objeto HWND con esa memoria de 16 números base/manejar/etc.). Solo por suerte, no pusieron esa función en AutoItX (el dll COM). Entonces, si realmente quiero correr con esto, tendré que tratar de averiguar cómo devolver el objeto al que apunta la dirección base 16, y luego transferirlo de la manera correcta a AutoItX. Probablemente parezca muy confundido, porque todo esto no está muy claro en mi cabeza en este momento.

+0

Podría ser un problema con los tipos ... No soy un usuario de Python, pero puede ejecutar algunas comprobaciones sobre el tipo de la variable 'windowHandle'. Debería ser un número entero. – Matt

+0

@Mat En Python, el tipo de la variable 'windowHandle' es una cadena unicode (por ejemplo,' u'000C0326''). ¿Debería el entero ser el número hexadecimal (por ejemplo, ''0x000C0326'') (en forma de número entero) que AutoIt imprime si se le pide que emita la variable' windowHandle'? –

+0

Sí. Si pasa una cadena, AutoIt intentará encontrar una ventana cuyo título coincida con esa cadena.En este caso, no se encuentra ninguna ventana ya que no existe una ventana con un título "000C0326". Desde mi corto tiempo con Python, querrás probar 'autoIt.WinGetTitle (int (windowHandle, 16))' o algo así, sabrás mejor que yo. Si eso no funciona, entonces deberá encontrar la forma de obtener un tipo de manejador automático en Python. – Matt

Respuesta

2

Por el bien de la búsqueda, publicaré la solución que he encontrado.

Aquí está el código:

In: autoIt = win32com.client.Dispatch("AutoItX3.Control") 
In: autoIt.AutoItSetOption("WinTitleMatchMode", 4) 
In: mainWindowTitle = "Untitled" 
In: mainWindowHandle = autoIt.WinGetHandle(mainWindowTitle) 
In: mainWindowHandle 
Out: u'000204AC' 
In: testHandle = "[HANDLE:%s]" % mainWindowHandle 
In: autoIt.WinGetTitle(testHandle) 
Out: u'Untitled - Notepad' 

autoIt.AutoItSetOption("WinTitleMatchMode", 4) le dice AutoIT a utilizar la concordancia título avanzado, que nos permite especificar un identificador de ventana con la cadena [HANDLE:000204AC].

No hay necesidad de la actual manija de la ventana aquí.

Por cierto, descubrí esta solución al tropezar con this forum post. Descubrí que a menudo es útil no restringir mis búsquedas al idioma específico que estoy buscando. La mayoría de las veces, se puede encontrar una solución en un idioma diferente que puede trasladarse fácilmente al idioma de su elección.

2

El tipo de controladores de ventana es cadena. La razón de esto es que WinList devuelve tanto el identificador de ventana como el título de la ventana. Un título no puede encajar en un tipo de manejador, pero un manejador puede encajar en un tipo de cadena (para el título). Supongo que tomaron esa decisión de diseño y la aplicaron a otras funciones también. Si observa la documentación de WinGetHandle, le indicará el tipo de devolución de un identificador: es una cadena.

AutoIt tiene una función que puede "convertir" un número base 16 en un objeto HWND.

¡Exactamente! Esa es la clave. AutoIt hace esto por ti. Está intentando convertir el manipulador en algo útil para AutoIt, pero AutoIt ya puede usar esos identificadores almacenados como cadenas.

, la prueba debe ser:

In: autoIt = win32com.client.Dispatch("AutoItX3.Control") 
In: mainWindowTitle = "Untitled" 
In: mainWindowHandle = autoIt.WinGetHandle(mainWindowTitle) 
In: mainWindowHandle 
Out: u'000204AC' 
In: autoIt.WinGetTitle(mainWindowHandle) 
Out: u'Untitled - Notepad' 

Cuando desee utilizar ese mango en otras bibliotecas, es posible que encuentre algunos problemas. Yo recomendaría entonces que trates de analizar el número como lo hiciste en tus pruebas y lo pases. AutoIt es lo suficientemente "inteligente" como para descubrir qué hacer en la mayoría de los casos, tal vez la biblioteca no.

+0

Hola Manadar, gracias por tu respuesta, pero si miras mi primer ejemplo, verás que probé exactamente lo que mencionaste. Escupe la cadena Unicode como el manejador de Ventana, pero no puede devolver el título de la ventana usando esa cadena Unicode. Como mencioné en mi última edición, creo que mientras AutoIt tiene una función que puede convertir una cadena Unicode en un objeto HWND, AutoItX no hace que esa función esté disponible a través del COM dll, por lo que las funciones accesibles a través de COM deben llamarse solo mediante el uso de títulos de ventanas (independientemente de cómo puedan manejarlo internamente). –