I want to build an RPA to automate some tasks in different windows computers. I’ve been looking for frameworks or libraries to do so in Python and robocorp-windows seems more robust than other options (I’ve seen RPAs written in PyAutoGUI, but I do not want to rely on image matching to find elements).
The tasks I want to automate require opening other executables. Since I’m not familiar with this library, I am writing some tests to get familiar with it:
from robocorp import windows
from robocorp.windows import WindowElement
import logging
from sys import stdout
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
console_handler = logging.StreamHandler(stdout)
formatter = logging.Formatter(
"33[95m%(levelname)s33[0m[%(lineno)s - %(funcName)s] %(message)s"
)
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)
def execute(executable: str) -> WindowElement:
"""
Execute a program and retrieve its window element
"""
desktop = windows.desktop()
logger.debug(f"opening {executable}...")
desktop.windows_run(executable)
logger.debug(f"searching for window with executable:{executable}")
return windows.find_window(f"executable:{executable.replace(' ', '%20')}")
program_x = "C:\Users\me\AppData\Local\Programs\Launcher\Launcher.exe"
firefox = "C:\Users\me\AppData\Local\Mozilla Firefox\firefox.exe"
program_x_window = execute(program_x)
firefox_window = execute(firefox)
The Problem
I expect this code to open both programs and store their respective windows in variables for later manipulation. However, the program is unable to find the handle for firefox because the path contains a whitespace (if the whitespace is not replaced it searches for the locator name:"Firefoxfirefox.exe"
instead).
The solution was to simply wrap the locator in double quotes. Instead of the following:
def execute(executable: str) -> WindowElement:
"""
Execute a program and retrieve its window element
"""
desktop = windows.desktop()
logger.debug(f"opening {executable}...")
desktop.windows_run(executable)
logger.debug(f"searching for window with executable:{executable}")
return windows.find_window(f"executable:{executable.replace(' ', '%20')}")
This solves the problem:
def execute(executable: str) -> WindowElement:
"""
Execute a given executable and retrieve the generated window element
"""
desktop = windows.desktop()
logger.debug(f"opening {executable}...")
desktop.windows_run(executable)
logger.debug(f"searching for window with executable:{executable}")
return windows.find_window(f'executable:"{executable}"') # note the double quotes wrapping the executable variable