Saltar a contenido

Automatización de una aplicación de Windows

En algunos casos, podemos automatizar aplicaciones de Windows a través de las propiedades de los elementos, como alternativa a la visión por computadora.

Esto puede ser una alternativa útil cuando no queremos preocuparnos por problemas de resolución. Simplemente podemos interactuar con la estructura de la aplicación a través de los atributos de los elementos y las ventanas.

Este tutorial te guiará a través del proceso de crear una automatización simple que interactúa con los elementos de una aplicación de Windows.

Crear un nuevo proyecto

El primer paso es crear un proyecto para una automatización de desktop, puedes seguir los mismos pasos definidos en la sección anterior.

Consulta cómo crear un proyecto de Bot desktop.

Aplicación objetivo y herramientas de inspección

Para este ejemplo simple, vamos a utilizar el estándar de Windows notepad.

Para ayudarnos a inspeccionar esta aplicación, vamos a utilizar la herramienta de inspección Accessibility Insights for Windows.

Consulta más detalles sobre el uso de herramientas de inspección.

Interactuar con la aplicación

Conexión

Con el proyecto abierto, vamos a insertar el primer paso en el archivo bot.py, que es establecer la conexión con la aplicación objetivo.

from botcity.core import DesktopBot, Backend
...
def main():
    bot = DesktopBot()

    # Application path
    app_path = "notepad.exe"

    # Launching the app
    bot.execute(app_path)

    # Connecting to the application using 'path' selector
    bot.connect_to_app(backend=Backend.UIA, path=app_path)
...

Con la aplicación abierta, podemos usar la herramienta de inspección para ver información sobre los elementos.

Herramienta de inspección

Encontrar ventanas y elementos

Con la aplicación conectada, ahora podemos usar la referencia de la ventana principal y recopilar el elemento que se refiere al editor de texto, por ejemplo.

from botcity.core import DesktopBot, Backend
...
def main():
    bot = DesktopBot()

    # Application path
    app_path = "notepad.exe"

    # Launching the app
    bot.execute(app_path)

    # Connecting to the application using 'path' selector
    bot.connect_to_app(backend=Backend.UIA, path=app_path)

    # Getting the notepad main window context using 'title_re' selector
    main_window = bot.find_app_window(title_re="Untitled - Notepad")

    # Getting the edit text area using the element 'title'
    # We were able to view this property through the spy tool
    edit = bot.find_app_element(from_parent_window=main_window, title="Text Editor")
...

Observa que utilizamos la propiedad title que obtuvimos de la herramienta de inspección. Básicamente, puedes utilizar cualquier información que aparezca para filtrar un determinado elemento.

Propiedades del elemento

Tip

Otra forma de inspeccionar los elementos de control de la aplicación es utilizar el método print_control_identifiers. Después de abrir el cuadro de diálogo y asignarlo a una variable, el método print_control_identifiers debería imprimir todos los controles disponibles. Consulta más detalles sobre esto aquí.

Realizar acciones

Con el elemento encontrado, podemos realizar las operaciones. Como este elemento es de tipo Edit, podemos insertar un contenido de texto.

from botcity.core import DesktopBot, Backend
...
def main():
    bot = DesktopBot()

    # Application path
    app_path = "notepad.exe"

    # Launching the app
    bot.execute(app_path)

    # Connecting to the application using 'path' selector
    bot.connect_to_app(backend=Backend.UIA, path=app_path)

    # Getting the notepad main window context using 'title_re' selector
    main_window = bot.find_app_window(title_re="Untitled - Notepad")

    # Getting the edit text area using the element 'title'
    # We were able to view this property through the spy tool
    edit = bot.find_app_element(from_parent_window=main_window, title="Text Editor")

    # Typing some text
    edit.type_keys("Hello! Welcome to BotCity!", with_spaces=True)
...

Info

Consulta más detalles sobre los métodos disponibles para cada tipo diferente de elemento en este enlace.

Ejecutar el Bot

Solo el código anterior sería suficiente para iniciar notepad e insertar un contenido de texto.

Hemos establecido una conexión con la aplicación y estamos realizando operaciones en el contexto de un elemento específico.

Al ejecutar el código, el resultado final se verá así:

Resultado

Acceder a otros elementos en Notepad

Con el mismo enfoque que se mencionó anteriormente, utilizando las propiedades control_type y title, vamos a acceder a otros elementos de notepad.

Acceder a menu_select

Comenzaremos accediendo a la opción Page Setup del menú File, a través del método menu_select.

# Accediendo a la opción Page Setup del menú File
main_window.menu_select("File -> Page Setup")
...

Usar select para elegir una opción en la caja de selección

Vamos a interactuar con el elemento Size, como se muestra a continuación:

Configuración de papel

Para seleccionar el tamaño del papel, vamos a mapear el control_type y title del elemento size, para poder seleccionarlos mediante el método select.

Esta vez vamos a utilizar otro enfoque para obtener la propiedad del elemento, el método print_control_identifiers, como se muestra a continuación:

# Imprimiendo los identificadores de control de la ventana "Page Setup".
main_window.print_control_identifiers()
...

Al ejecutar el código anterior, los controles de la ventana Page Setup se generarán en tu terminal.

Identificadores de control

Donde podemos ver el title y control_type del elemento, que se utilizarán a continuación como parámetros del método find_app_element.

# Finding element to select page size
size = bot.find_app_element(from_parent_window=main_window, control_type="ComboBox",
                             title="Size:")
# Selecting page type
size.select("A5")
...

Usar invoke para elegir un botón de opción

Aquí, vamos a usar invoke para seleccionar el botón de opción Landscape.

Botón de opción

Aún utilizando los identificadores de control.

Identificadores de control

Vamos a obtener el title y control_type del elemento Landscape para encontrarlo a continuación:

# Finding element to select radio button "Landscape"
orientation = bot.find_app_element(from_parent_window=main_window,
                                    control_type="RadioButton", title="Landscape")
# Method `click` is an alias of `invoke`
orientation.invoke()

# Finding element to click on button "OK"
btn_ok = bot.find_app_element(from_parent_window=main_window, title="OK")
# Clicking on button
btn_ok.click()
...

Info

En este caso, no fue posible utilizar los métodos click y click_input para seleccionar el botón de opción, ya que solo tienen control sobre elementos con la propiedad control_type="Button".

Info

invoke utiliza el llamado InvokePattern que representa una acción predeterminada para el control. Al utilizar Application(backend="uia"), el método click es un alias de invoke, donde la acción InvokePattern lleva la ventana al primer plano, permitiendo la interacción con el elemento.

Después de las acciones anteriores, la configuración de la página se verá así:

Configuración de página

Usar type_keys y click para guardar el notepad en el explorador de archivos.

Para finalizar, vamos a acceder a la opción guardar como en el menú archivo.

# Accediendo al menú Guardar como
main_window.menu_select("File -> Save As...")
...

Esta acción abrirá la ventana del explorador de archivos, como se muestra a continuación:

Guardar como

Así, vamos a definir un nombre para el archivo, en este caso será tutorial.txt, y haremos clic en el botón guardar, a través del método click.

# Finding element to type the name of file
file_name = bot.find_app_element(from_parent_window=main_window, class_name="Edit",
                                  title="File name:")
# Typing the file name
file_name.type_keys("tutorial.txt")

# Finding element to clicks on button save
btn_save = bot.find_app_element(from_parent_window=main_window, class_name="Button",
                                 title="Save")
# Clicking on button save
btn_save.click()
...

Código completo

from botcity.core import DesktopBot, Backend
...
def main():
    bot = DesktopBot()

    # Application path
    app_path = "notepad.exe"

    # Launching the app
    bot.execute(app_path)

    # Connecting to the application using 'path' selector
    bot.connect_to_app(backend=Backend.UIA, path=app_path)

    # Getting the notepad main window context using 'title_re' selector
    main_window = bot.find_app_window(title_re="Untitled - Notepad")

    # Getting the edit text area using the element 'title'
    # We were able to view this property through the spy tool
    edit = bot.find_app_element(from_parent_window=main_window, title="Text Editor")

    # Typing some text
    edit.type_keys("Hello! Welcome to BotCity!", with_spaces=True)

    # Acessing option Page Setup of File Menu
    main_window.menu_select("File -> Page Setup")

    # Finding element to select page size
    size = bot.find_app_element(from_parent_window=main_window, class_name="ComboBox",
                                    title="Size:")
    # Selecting page type
    size.select("A5")

    # Finding element to select radio button "Landscape"
    orientation = bot.find_app_element(from_parent_window=main_window,
                                        control_type="RadioButton", title="Landscape")
    # Method click() is an alias of invoke()
    orientation.invoke()

    # Finding element to click on button "OK"
    btn_ok = bot.find_app_element(from_parent_window=main_window, title="OK")
    # Clicking on button
    btn_ok.click()

    # Acessing option Save As of file Menu
    main_window.menu_select("File -> Save As...")

    # Finding element to type the name of file
    name_file = bot.find_app_element(from_parent_window=main_window, class_name="Edit",
                                        title="File name:")
    # Typing the file name
    name_file.type_keys("tutorial.txt")

    # Finding element to clicks on button save
    btn_save = bot.find_app_element(from_parent_window=main_window, class_name="Button",
                                        title="Save")
    # Clicking on button save
    btn_save.click()
...

Important

Algunas aplicaciones pueden ser más difíciles de inspeccionar y encontrar información sobre los elementos.

Utiliza las herramientas de inspección como referencia para determinar si esta es la mejor alternativa para tu automatización.

Conclusión

En este tutorial has aprendido:

  • Cómo utilizar una herramienta de inspección para examinar una aplicación de Windows.

  • Cómo conectarse a una aplicación y ver sus atributos y propiedades.

  • Cómo interactuar con un elemento que se ha encontrado.