WindowsAppEnv

WindowsAppEnv 类的使用场景如下:

  • 打开指定文档。
  • 使用不同的策略(containsfuzzyregex匹配文档窗口
  • 使用各种策略(containsfuzzyregex匹配实例化计划中每个步骤所需的控件
  • 关闭指定文档。

以下章节详细解释了窗口和控件的匹配策略及其使用方法。

匹配策略

WindowsAppEnv 类中,匹配策略是确定如何将 windowcontrol 名称与给定文档名称或目标文本匹配的规则。根据配置文件,可以选择三种不同的匹配策略:containsfuzzyregex

  • Contains 匹配是最简单的策略,适用于窗口和文档名称完全匹配的情况。
  • Fuzzy 匹配更灵活,即使窗口标题和文档名称之间存在拼写错误或部分匹配,也能进行匹配。
  • Regex 匹配提供了最大的灵活性,非常适合窗口标题中复杂的匹配模式。

1. 窗口匹配示例

find_matching_window 方法负责根据配置的匹配策略匹配窗口。以下是您可以使用它通过提供文档名称来查找窗口的方法:

示例

# Initialize your application object (assuming app_object is already defined)
app_env = WindowsAppEnv(app_object)

# Define the document name you're looking for
doc_name = "example_document_name"

# Call find_matching_window to find the window that matches the document name
matching_window = app_env.find_matching_window(doc_name)

if matching_window:
    print(f"Found matching window: {matching_window.element_info.name}")
else:
    print("No matching window found.")

解释

  • app_env.find_matching_window(doc_name) 将搜索所有打开的窗口,并使用配置中定义的策略(contains、fuzzy 或 regex)匹配窗口标题。
  • 如果找到匹配项,matching_window 对象将包含匹配的窗口,您可以打印窗口的名称。
  • 如果未找到匹配项,它将返回 None

2. 控件匹配示例

要在窗口中查找匹配的控件,您可以使用 find_matching_controller 方法。此方法需要一个过滤后的控件字典和一个要匹配的控件文本。

示例

# Initialize your application object (assuming app_object is already defined)
app_env = WindowsAppEnv(app_object)

# Define a filtered annotation dictionary of controls (control_key, control_object)
# Here, we assume you have a dictionary of UIAWrapper controls from a window.
filtered_annotation_dict = {
    1: some_control_1,  # Example control objects
    2: some_control_2,  # Example control objects
}

# Define the control text you're searching for
control_text = "submit_button"

# Call find_matching_controller to find the best match
controller_key, control_selected = app_env.find_matching_controller(filtered_annotation_dict, control_text)

if control_selected:
    print(f"Found matching control with key {controller_key}: {control_selected.window_text()}")
else:
    print("No matching control found.")

解释

  • filtered_annotation_dict 是一个字典,其中键表示控件的 ID,值是控件对象 (UIAWrapper)。
  • control_text 是您在这些控件中搜索的文本。
  • app_env.find_matching_controller(filtered_annotation_dict, control_text) 将根据定义的策略计算每个控件的匹配分数,并返回匹配分数最高的控件。
  • 如果找到匹配项,它将返回控件对象 (control_selected) 及其键 (controller_key),可用于进一步交互。

参考

表示 Windows 应用程序环境。

初始化 Windows 应用程序环境。

参数
  • app_object (对象) –

    包含应用程序信息的应用程序对象。

源代码位于 env/env_manager.py
29
30
31
32
33
34
35
36
37
38
def __init__(self, app_object: object) -> None:
    """
    Initializes the Windows Application Environment.
    :param app_object: The app object containing information about the application.
    """

    self.app_window = None
    self.app_root_name = app_object.app_root_name
    self.app_name = app_object.description.lower()
    self.win_app = app_object.win_app

close()

尝试正常关闭应用程序;如果失败或未关闭,则强制终止进程。

源代码位于 env/env_manager.py
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
def close(self) -> None:
    """
    Tries to gracefully close the application; if it fails or is not closed, forcefully terminates the process.
    """

    try:
        # Gracefully close the application window
        if self.app_window and self.app_window.process_id():
            self.app_window.close()
        sleep(1)
        # Forcefully close the application window
        if self.app_window.element_info.name.lower() != "":
            self._check_and_kill_process()
    except Exception as e:
        logging.warning(
            f"Graceful close failed: {e}. Attempting to forcefully terminate the process."
        )
        self._check_and_kill_process()
        raise e

find_matching_controller(filtered_annotation_dict, control_text)

" 选择最佳匹配的控制器。

参数
  • filtered_annotation_dict (字典[整数, UIAWrapper]) –

    过滤后的注释字典。

  • control_text (字符串) –

    控件的文本内容,用于提供额外上下文。

返回
  • 元组[字符串, UIAWrapper]

    包含所选控制器键和控件对象的元组。

源代码位于 env/env_manager.py
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
def find_matching_controller(
    self, filtered_annotation_dict: Dict[int, UIAWrapper], control_text: str
) -> Tuple[str, UIAWrapper]:
    """ "
    Select the best matched controller.
    :param filtered_annotation_dict: The filtered annotation dictionary.
    :param control_text: The text content of the control for additional context.
    :return: Tuple containing the key of the selected controller and the control object.s
    """
    control_selected = None
    controller_key = None
    highest_score = 0

    # Iterate through the filtered annotation dictionary to find the best match
    for key, control in filtered_annotation_dict.items():
        # Calculate the matching score using the match function
        score = self._calculate_match_score(control, control_text)

        # Update the selected control if the score is higher
        if score > highest_score:
            highest_score = score
            controller_key = key
            control_selected = control

    return controller_key, control_selected

find_matching_window(doc_name)

根据进程名称和配置的匹配策略查找匹配的窗口。

参数
  • doc_name (字符串) –

    与应用程序关联的文档名称。

返回
  • 可选[UIAWrapper]

    匹配的窗口,如果未找到匹配项则为 None。

源代码位于 env/env_manager.py
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
def find_matching_window(self, doc_name: str) -> Optional[UIAWrapper]:
    """
    Finds a matching window based on the process name and the configured matching strategy.
    :param doc_name: The document name associated with the application.
    :return: The matched window or None if no match is found.
    """

    desktop = Desktop(backend=_BACKEND)
    windows_list = desktop.windows()
    for window in windows_list:
        window_title = window.element_info.name.lower()
        if self._match_window_name(window_title, doc_name):
            self.app_window = window
            return window
    return None

start(copied_template_path)

启动 Windows 环境。

参数
  • copied_template_path (字符串) –

    用于启动环境的复制模板的文件路径。

源代码位于 env/env_manager.py
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
def start(self, copied_template_path: str) -> None:
    """
    Starts the Windows environment.
    :param copied_template_path: The file path to the copied template to start the environment.
    """

    from ufo.automator.ui_control import openfile

    file_controller = openfile.FileController(_BACKEND)
    try:
        file_controller.execute_code(
            {"APP": self.win_app, "file_path": copied_template_path}
        )
    except Exception as e:
        logging.exception(f"Failed to start the application: {e}")
        raise