diff --git a/Wiki/RUS Tutorial/DesktopGUI_Habr/2. Calc MouseSearch Hex.png b/Wiki/RUS Tutorial/DesktopGUI_Habr/2. Calc MouseSearch Hex.png new file mode 100644 index 00000000..7b54639c Binary files /dev/null and b/Wiki/RUS Tutorial/DesktopGUI_Habr/2. Calc MouseSearch Hex.png differ diff --git a/Wiki/RUS Tutorial/DesktopGUI_Habr/2. Calc Vid Programmist.png b/Wiki/RUS Tutorial/DesktopGUI_Habr/2. Calc Vid Programmist.png new file mode 100644 index 00000000..f2248672 Binary files /dev/null and b/Wiki/RUS Tutorial/DesktopGUI_Habr/2. Calc Vid Programmist.png differ diff --git a/Wiki/RUS Tutorial/DesktopGUI_Habr/2. MonitoringModeProgrammer_Run_64.cmd b/Wiki/RUS Tutorial/DesktopGUI_Habr/2. MonitoringModeProgrammer_Run_64.cmd new file mode 100644 index 00000000..4156cf8a --- /dev/null +++ b/Wiki/RUS Tutorial/DesktopGUI_Habr/2. MonitoringModeProgrammer_Run_64.cmd @@ -0,0 +1,3 @@ +cd %~dp0..\OpenRPA\Sources +..\Resources\WPy64-3720\python-3.7.2.amd64\python.exe "..\..\OpenRPA Habr\2. MonitoringModeProgrammer_Run_64.py" +pause >nul \ No newline at end of file diff --git a/Wiki/RUS Tutorial/DesktopGUI_Habr/2. MonitoringModeProgrammer_Run_64.py b/Wiki/RUS Tutorial/DesktopGUI_Habr/2. MonitoringModeProgrammer_Run_64.py new file mode 100644 index 00000000..4377385e --- /dev/null +++ b/Wiki/RUS Tutorial/DesktopGUI_Habr/2. MonitoringModeProgrammer_Run_64.py @@ -0,0 +1,17 @@ +from pyOpenRPA.Robot import UIDesktop # Импорт модуля, который умеет управлять UI элеметами GUI приложений +import time # Библиотека сна алгоритма +import os # Билбиотека системных функций, позволит открять калькулятор, если это потребуется +lUIOSelectorCalculator = [{"title":"Калькулятор","class_name":"CalcFrame","backend":"win32"}] # Сформировали UIO селектор из студии pyOpenRPA +while True: # Вечный цикл + lExistBool = UIDesktop.UIOSelector_Exist_Bool(inUIOSelector=lUIOSelectorCalculator) # Проверить наличие окна по UIO селектору + if not lExistBool: # Проверить наличие окна калькулятора + os.system("calc") # Открыть калькулятор + else: # Проверить, что окно калькулятора не свернуто + lUIOCalculator = UIDesktop.UIOSelector_Get_UIO(inSpecificationList=lUIOSelectorCalculator) # Получить UIO экземпляр + if lUIOCalculator.is_minimized(): # Проверить, что калькулятор находится в свернутом виде + lUIOCalculator.restore() # Восстановить окно калькулятора из свернутого вида + else: + lCalcHex_IsExistBool = UIDesktop.UIOSelector_Exist_Bool(inUIOSelector=[{"class_name":"CalcFrame","backend":"win32"},{ "title":"Hex", "depth_start":3, "depth_end": 3}]) # Проверить наличие UI элемента по UIO селектору + if not lCalcHex_IsExistBool: # Проверить, что UI элемент отсутствует + lUIOCalculator.menu_select("&Вид -> &Программист") # Выполнить смену режима калькулятора + time.sleep(1) # Выполнить сон на 1 сек., после чего перейти на следующую итерацию \ No newline at end of file diff --git a/Wiki/RUS Tutorial/DesktopGUI_Habr/2. pyOpenRPA Studio Calc UI hex UIO.png b/Wiki/RUS Tutorial/DesktopGUI_Habr/2. pyOpenRPA Studio Calc UI hex UIO.png new file mode 100644 index 00000000..57ef7c0c Binary files /dev/null and b/Wiki/RUS Tutorial/DesktopGUI_Habr/2. pyOpenRPA Studio Calc UI hex UIO.png differ diff --git a/Wiki/RUS Tutorial/DesktopGUI_Habr/2. pyOpenRPA Studio Calc UI hex.png b/Wiki/RUS Tutorial/DesktopGUI_Habr/2. pyOpenRPA Studio Calc UI hex.png new file mode 100644 index 00000000..3c8d42a5 Binary files /dev/null and b/Wiki/RUS Tutorial/DesktopGUI_Habr/2. pyOpenRPA Studio Calc UI hex.png differ diff --git a/Wiki/RUS Tutorial/DesktopGUI_Habr/2. pyOpenRPA Studio.png b/Wiki/RUS Tutorial/DesktopGUI_Habr/2. pyOpenRPA Studio.png new file mode 100644 index 00000000..9e6e68f1 Binary files /dev/null and b/Wiki/RUS Tutorial/DesktopGUI_Habr/2. pyOpenRPA Studio.png differ diff --git a/Wiki/RUS Tutorial/DesktopGUI_Habr/2. pyOpenRPA Tutorial Habr welcome.pptx b/Wiki/RUS Tutorial/DesktopGUI_Habr/2. pyOpenRPA Tutorial Habr welcome.pptx new file mode 100644 index 00000000..09a38321 Binary files /dev/null and b/Wiki/RUS Tutorial/DesktopGUI_Habr/2. pyOpenRPA Tutorial Habr welcome.pptx differ diff --git a/Wiki/RUS Tutorial/DesktopGUI_Habr/2. pyOpenRPA welcome.png b/Wiki/RUS Tutorial/DesktopGUI_Habr/2. pyOpenRPA welcome.png new file mode 100644 index 00000000..ce0b2ef2 Binary files /dev/null and b/Wiki/RUS Tutorial/DesktopGUI_Habr/2. pyOpenRPA welcome.png differ diff --git a/Wiki/RUS Tutorial/DesktopGUI_Habr/DesktopGUI_Habr.md b/Wiki/RUS Tutorial/DesktopGUI_Habr/DesktopGUI_Habr.md new file mode 100644 index 00000000..3208e32f --- /dev/null +++ b/Wiki/RUS Tutorial/DesktopGUI_Habr/DesktopGUI_Habr.md @@ -0,0 +1,336 @@ +Специально для Хабр я начинаю серию статей-туториалов по использованию RPA платформы [OpenRPA](https://habr.com/ru/post/506766/). Буду рад получить от вас комментарии и замечания, если возникнут какие-либо вопросы. Надеюсь, что эта история не оставит вас равнодушными. + +![pyOpenRPA Туториал. Управление оконными GUI приложениями](https://habrastorage.org/webt/p8/_q/mo/p8_qmot0fkekqnwyqids33fthae.png) + +Ранее я писал о том, что [OpenRPA](https://habr.com/ru/post/506766/) - это первая open source RPA платформа, которая позволяет польностью избавить себя от платных RPA аналогов. И, как выяснилось в процессе, эта тема позволяет не просто снять компании с "лицензионной иглы", а еще и увеличить получаемые бизнес-эффекты от разработанных роботов. Ведь архитектура новых RPA оказалась гораздо "легче" и, как следствие, быстрее. + +Благодарю всех читателей, которые проявили интерес к моей [предыдущей статье](https://habr.com/ru/post/506766/) - я очень ценю мнение других, потому что именно это позволяет мне предлагать общественности наиболее актуальные решения. Еще раз спасибо вам за проявленный интерес! + +В рамках этой статьи будет приведена подробная инструкция по разработке робота, который будет манипулировать оконными GUI приложениями. + +*Под оконными приложениями понимаются все виды GUI приложений, которые не визуализируются в WEB браузерах.* + + + +# Ремарка. OpenRPA теперь становится pyOpenRPA +С момента опубликования [предыдущей статьи](https://habr.com/ru/post/506766/) произошли небольшие изменения в названии RPA платформы, а именно: [OpenRPA](https://gitlab.com/UnicodeLabs/OpenRPA) переименовывается в [pyOpenRPA]([https://gitlab.com/UnicodeLabs/OpenRPA]). + + + +## С чем это связано? +Дело в том, что само по себе название OpenRPA является "говорящим", и "лежит на поверхности". По этой причине его выбрал я, а через некоторое время и другие. Так как концепция [pyOpenRPA]([https://gitlab.com/UnicodeLabs/OpenRPA]) заключается в абсолютно безвоздмездном использовании и открытости для всех, в этой RPA платформе нет каких-либо бюджетов. В связи с этим нет возможности и отстаивать монопольное право на использование названия (да это и не нужно). В связи с этим, было принято решение немного скорректировать название, чтобы избавить пользователей от возможной путаницы. + +По поводу [OpenRPA от другой команды](https://github.com/open-rpa/openrpa): очень надеюсь, что им удастся реализовать свою идею, превзойти по всем параметрам платные RPA платформы, и сохранить свою открытось. В мире open source мы не конкуренты, а коллеги, которые трудятся в одном и том же направлении - в направлении создания полезного открытого продукта. Если говорить про их RPA платформу, то там поставлена цель создания аналога коммерческой RPA платформы с визуальным программированием в основе. Идея очень интересная и привлекательная, но крайне трудозатратная по исполнению (ведь не просто так лучшие RPA платформы постоянно дорабатываются огромными командами разработчиков, что ведет к комерциализации проекта). Желаю им удачи в достижении поставленных целей. + + + +# Навигация по статьям + +Так как [pyOpenRPA](https://gitlab.com/UnicodeLabs/OpenRPA) - это достаточно крупная RPA платформа: туториал будет составлен в виде серий статей, в которых будут освещаться ключевые технологии. А уже освоив эти технологии, у вас появится возможность углубиться в то, что вам нужно. + +**Ниже приведу планируемый перечень статей по этой тематике (для навигации):** + +- [Отказываемся от платных RPA платформ и базируемся на OpenSource (pyOpenRPA)](https://habr.com/ru/post/506766/) +- \>> pyOpenRPA туториал. Управление оконными GUI приложениями +- pyOpenRPA туториал. Управление WEB приложениями (то, что мы смотрим в Chrome, Firefox, Opera) +- pyOpenRPA туториал. Управление клавиатурой & мышью +- pyOpenRPA туториал. Распознавание графических объектов на экране + + + +# Немного теории и терминов +Давайте попробуем разобраться в том, как устроены GUI приложения, и почему мы можем ими управлять. + +Начнем с простого. Рассмотрим на примере классического блокнота, что видим мы, и что видит робот. + + + +## Что видим мы? +![Notepad_human](https://habrastorage.org/webt/gk/q_/ky/gkq_kyyivmojkiynqossxayojck.png) + +## Что видит робот? +![Notepad_pyOpenRPA](https://habrastorage.org/webt/nj/sj/zx/njsjzxdzjzdimm_ushvz-f5eqaw.png) + + + +## Интерпретация +Благодаря архитектуре современных операционных систем у сторонних программ имеется программная возможность по обращению к [UI элементам - они же UIO](https://ru.wikipedia.org/wiki/%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81_%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8F) сторонних GUI приложений. Эта возможность изначально разрабатывалась для того, чтобы позволить программистам проводить [регрессионное тестирование свеого софта](https://ru.wikipedia.org/wiki/%D0%A0%D0%B5%D0%B3%D1%80%D0%B5%D1%81%D1%81%D0%B8%D0%BE%D0%BD%D0%BD%D0%BE%D0%B5_%D1%82%D0%B5%D1%81%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5), но позже выяснилось, что эту возможность можно использовать и в бизнес-процессах компании. + +Как мы видим на изображении выше, для робота, блокнот - это набор различных UIO. Причем не просто UIO, а UIO c **набором различных атрибутов, и набором различных действий**. И что самое главное - наш робот имеет полный доступ ко всем этим атрибутам и действиям. + +> **Примеры атрибутов
** +> - hidden - элемент спрятан в GUI интерфейсе от глаз пользователя
+> - disabled - элемент недоступен для выполнения действий (нажатие, наведение мышкой и и т.д.)
+ +> **Примеры действий** +> - left click - клик левой кнопкой мыши
+> - right click - клик правой кнопкой мыши
+> - type text - ввод текста в активную область
+> - scroll up - пролистывание активной области вверх
+> - scroll down - пролистывание активной области вниз
+> - scroll left - пролистывание активной области влево
+> - scroll right - пролистывание активной области вправо
+ +Тут вы можете мне возразить, что это все ерунда, потому что в любой операционной системе реализованы алгоритмы, обеспечивающие разграничение информационных потоков, и одно приложение не может "залезть" в другое приложение. А я вам на это скажу, что это, действительно так, **но только для программного (технического) уровня**. Вся эта история с безопасностью не работает, когда речь заходит о доступе к GUI интерфейсам других приложений. + + + +## Что такое UIO? +UIO - это User Interface Object (терминология pyOpenRPA). В целях обеспечения максимальной совместимости, этот экземпляр наследуется от обьектной модели, разработанной в библиотеке [pywinauto (нажми, чтобы получить список доступных функций класса)](https://pywinauto.readthedocs.io/en/latest/code/pywinauto.base_wrapper.html). + +Данный подход позволяет имплементировать полезную функциональность, которая уже была успешно разработана в других бибилотеках, и дополнить ее недостающей функциональностью. В нашем случае, недостающей функциональностью является возможность динамического обращения к UIO обьектам по UIO селекторам. + + + +## Правила формирования UIO селектора (UIOSelector) + +UIO селектор - это список характеристических словарей (спецификаций UIO). Данные спецификации UIO содержат условия, с помощью которых библиотека pyOpenRPA определит UIO, удовлетворяющий условиям, заданным в спецификации UIO. Индекс спецификации UIO в списке UIO селектора харакетризует уровень вложенности целевого UIO. + +Говоря другим языком, UIO селектор - это перечень условий, под которые может попасть 0, 1 или n UIO. + +Ниже приведен перечень атрибутов - условий, которые можно использовать в спецификациях UIO: + ``` +[ + { + "depth_start" :: [int, start from 1] :: глубина, с которой начинается поиск (по умолчанию 1), + "depth_end" :: [int, start from 1] :: глубина, до которой ведется поиск (по умолчанию 1), + "ctrl_index" || "index" :: [int, starts from 0] :: индекс UIO в списке у родительского UIO, + "title" :: [str] :: идентичное наименование атрибута *title* искомого объекта UIO, + "title_re" :: [str] :: регулярное выражение (python диалект) для отбора UIO, у которого атрибут *title* должен удовлетворять условию данного регулярного выражения, + "rich_text" :: [str] :: идентичное наименование атрибута *rich_text* искомого объекта UIO, + "rich_text_re" :: [str] :: регулярное выражение (python диалект) для отбора UIO, у которого атрибут *rich_text* должен удовлетворять условию данного регулярного выражения, + "class_name" :: [str] :: идентичное наименование атрибута *class_name* искомого объекта UIO, + "class_name_re" :: [str] :: регулярное выражение (python диалект) для отбора UIO, у которого атрибут *class_name* должен удовлетворять условию данного регулярного выражения, + "friendly_class_name" :: [str] :: идентичное наименование атрибута *friendly_class_name* искомого объекта UIO, + "friendly_class_name_re" :: [str] :: регулярное выражение (python диалект) для отбора UIO, у которого атрибут *friendly_class_name* должен удовлетворять условию данного регулярного выражения, + "control_type" :: [str] :: идентичное наименование атрибута *control_type* искомого объекта UIO, + "control_type_re" :: [str] :: регулярное выражение (python диалект) для отбора UIO, у которого атрибут *control_type* должен удовлетворять условию данного регулярного выражения, + "is_enabled" :: [bool] :: признак, что UIO доступен для выполнения действий, + "is_visible" :: [bool] :: признак, что UIO отображается на экране, + "backend" :: [str, "win32" || "uia"] :: вид способа адресации к UIO (по умолчанию "win32"). Внимание! Данный атрибут может быть указан только для первого элемента списка UIO селектора. Для остальных элементов списка данный атрибут будет проигнорирован. + }, + { ... спецификация UIO следующего уровня иерархии } +] + ``` +**Пример UIO селектора** + ``` +[ + {"class_name":"CalcFrame", "backend":"win32"}, # Спецификация UIO 1-го уровня вложенности + {"title":"Hex", "depth_start":3, "depth_end": 3} # Спецификация UIO 1+3-го уровня вложенности (так как установлены атрибуты depth_start|depth_stop, определяющие глубину поиска UIO) +] + ``` + +*PS. Перечень функций по работе с UIO селектором представлен в модуле UIDesktop (pyOpenRPA/Robot/UIDesktop.py). Именно эти функции будут использоваться при дальнейшей разработке робота. +Ознакомиться в полным перечнем функций модуля UIDesktop [можно здесь](https://gitlab.com/UnicodeLabs/OpenRPA/-/blob/master/Wiki/05.2.-Theory-&-practice.-Desktop-app-UI-access-(win32-and-UI-automation-dlls).md)* + + + +# (По шагам) робот своими руками +Вот мы и добрались до самого интересного и важного раздела этого туториала - это пошаговый пример по созданию своего первого робота с использованием pyOpenRPA. + +В качестве экспериментального робота поставим себе следующую цель: **Разработать робота, который будет контролировать вид интерфейса в приложении "Калькулятор"**. Если вид интерфейса будет отличаться от вида "Программист", то робот должен будет выставить данный вид в автоматическом режиме. + + + +## Шаг 0. Подготовим интерпретатор Python 3 для нового робота (развернем pyOpenRPA) +В отличии от подавляющего большинства RPA платформ, в pyOpenRPA реализован другой подход подключения к проекту. Если в остальных RPA платформах необходимо писать робота на языке этой платформы (текстовый, или графический, или скриптовый язык), то в случае pyOpenRPA именно вы определяете где, как и когда нужно использовать эту библиотеку в проекте. + +Доступно несколько вариантов загрузки [pyOpenRPA](https://gitlab.com/UnicodeLabs/OpenRPA): +- Вариант 1, простой. Скачать преднастроенную портативную версию с [GitLab страницы проекта](https://gitlab.com/UnicodeLabs/OpenRPA) +- Вариант 2, посложнее. Установить pyOpenRPA в свою версию интерпретатора Python 3 (pip install pyOpenRPA) + + + +## Шаг 1. Создать проект робота +Для того, чтобы начать проект робота, необходимо создать папку проекта. В дальнейшем я затрону тему организации папок проектов для промышленных программных роботов. Но на текущий момент не буду заострять внимание на этом, чтобы сконцентрироваться непосредственно на основном - на логике работы с GUI окнами. + +**Создадим следующую структуру проекта:** +- Папка "RobotCalc": + - Файл "RobotCalc_1.py" - скрипт робота 1, который мы пишем сейчас + - Файл "RobotCalc_1_Run_x64.cmd" - скрипт запуска робота 1 + - Файл "RobotCalc_2.py" - скрипт робота 2, дополнение + - Файл "RobotCalc_2_Run_x64.cmd" - скрипт запуска робота 2 + +.cmd файлы в этом проекте играют важную роль - именно благодаря этим файлам мы будем иметь возможность выполнять запуск интересующего нас робота простым кликом по файлу. + +**Ниже приведу пример "RobotCalc_1_Run_x64.cmd" файла (файл "RobotCalc_2_Run_x64.cmd" аналогичен):** +``` +cd %~dp0 +..\Resources\WPy64-3720\python-3.7.2.amd64\python.exe "RobotCalc_1.py" +pause >nul +``` + + + +## Шаг 2. Запустить студию pyOpenRPA и сформировать необходимые UIO селекторы +- Открыть калькулятор (win + r > calc > enter) + +**Если вы скачали преднастроенную версию pyOpenRPA с GitLab (вариант 1, простой):** +- Выполнить запуск cmd файла web студии pyOpenRPA из репозитория "pyOpenRPA\Studio\pyOpenRPA.Studio_x64.cmd" + +**Если вы скачали пакет pyOpenRPA с помощью pip install pyOpenRPA (вариант 2, посложнее):** +- Выполнить запуск интерпретатора python со следующими аргументами: python -m pyOpenRPA.Studio "..\Studio\SettingsStudioExample.py", где SettingsStudioExample.py - это конфигурационный файл запуска студии pyOpenRPA. Преднастроенный шаблон этого файла можно [скачать с репозитория pyOpenRPA в GitLab](https://gitlab.com/UnicodeLabs/OpenRPA/-/blob/master/Studio/SettingsStudioExample.py) + +При любом из вариантов через 5 - 15 сек. должна автоматически отобразиться web студия pyOpenRPA (см. ниже) + +![pyOpenRPA_studio](https://habrastorage.org/webt/zu/pm/v7/zupmv75pwn3nseyb3mdnuzwzrwa.png) +*Внешний вид web студии pyOpenRPA* + + + +- В списке открытых оконных GUI приложений найти калькулятор и активировать режим поиска UI элемента по наведению указателя мыши (Кнопка "Mouse search") +- Переключиться на калькулятор (alt + tab) +- Навести указатель мыши на тот элемент, который нам необходим для того, чтобы определить состояние интерфейса калькулятора. Выберем radio кнопку Hex. Зеленая окантовка появляется поверх калькулятора благодаря студии pyOpenRPA - именно таким образом студия сообщает нам о том, какой UI элемент она видит в калькулятора по той точке, куда наведен указатель мыши. + +![calc_radiobutton](https://habrastorage.org/webt/cm/rq/qs/cmrqqsomsdbcyez1kdo6_tzmcgm.png) + +*Студии pyOpenRPA подсвечивает зеленой окантовкой обнаруженный UI элемент по месту указателя мыши на калькуляторе* + +- Для того, чтобы остановить процесс поиска UI элемента необходимо зажать клавишу ctrl на 2-4 секунды, после чего в WEB интерфейсе студии появится иерархния до UI элемента, который студия подсвечивала зеленой окантовкой. + + + +![pyOpenRPA_studio_calc_ui_hex](https://habrastorage.org/webt/vh/ai/tl/vhaitlupj8ntvxgj10rebcgp2ay.png) + +*Студия pyOpenRPA отобразила иерархию нахождения UI элемента в калькуляторе после отправки сигнала завершения поиска UI элементов (длительное нажатие ctrl)* + +- Для того, чтобы убедиться в том, что элемент был обнаружен корректно, достаточно нажать кнопку "Highlight" по тому UI элементу, который интересует. Программа повторно нарисует эеленую окантовку поверх того UI элемента, который был обнаружен. + +- Далее выполнить клик по UI элементу в окне иерархии в студии, после чего перейти в окно редактирования UIO селектора (UIO селектор далее будет использоваться в коде робота в Python 3) + + + +![pyOpenRPA_studio_calc_ui_hex_uio](https://habrastorage.org/webt/y2/_b/ck/y2_bckz1fb7c6z9x1gpyllqv2es.png) + +*Студия pyOpenRPA сформировала UIO селектор в автоматическом режиме к UI элементу калькулятора* + +- В нашем примере UI элемент расположен на 4-м уровне вложенности с атрибутом title = "Hex". В автоматическом режиме pyOpenRPA формирует UIO селектор по индексам расположения в вышестоящих UI элементах. Такой подход достаточно нежелательно использовать в конечных роботах, потому что индексы расположения UI элементов могут динамически изменяться во время работы программы. + +- Произведем преобразование нашего UIO селектора: +``` +[{"title":"Калькулятор","class_name":"CalcFrame","backend":"win32"},{"ctrl_index":0},{"ctrl_index":6},{"ctrl_index":1}] +``` +в следующий вид: + +``` +[{"class_name":"CalcFrame","backend":"win32"},{ "title":"Hex", "depth_start":3, "depth_end": 3}] +``` +- В результате преобразований убрали лишнее условие "title":"Калькулятор" и промежуточные уровни, которые характеризовались только индексами нахождения UI элементов. Вместо этого добавили условие поиска "title":"Hex" и установили область поиска "depth_start":3, "depth_end": 3 (в нашем случае это необходимо, потому что мы убрали явные уровни вложенности). Атрибуты "class_name" накладывает условие, что надо искать прилоежние с class_name = CalcFrame, а backend указывает pyOpenRPA, какую систему поиска UI элементов использовать (win32 или uia, у каждой и них есть + и -) +- С помощью кнопки "Hightlight element" убедимся в том, что UI элемент, по-прежнему, обнаруживается студией pyOpenRPA (при нажатии на кнопку поверх UI элемента должна быть отрисована зеленая окантовка - новый UIO селектор работает корректно) + + + +- Данный UIO селектор будем использовать в роботе для проверки состояния интерфейса калькулятора: если UI элемент успешно обнаруживается, то режим калькулятора установлен верный. Если UI элемент не обнаруживается, то режим калькулятора установлен неверный, и его нужно будет изменить. Для того, чтобы проверить наличие UI элемента по UIO селектору воспользуемся функцией **pyOpenRPA.Robot.UIDesktop.UIOSelector_Exist_Bool** +``` +lCalcHex_IsExistBool = UIDesktop.UIOSelector_Exist_Bool(inUIOSelector=[{"class_name":"CalcFrame","backend":"win32"},{ "title":"Hex", "depth_start":3, "depth_end": 3}]) # Проверить наличие UI элемента по UIO селектору +``` + +- Для того, чтобы установить режим программиста, воспользуемся еще одной возможностью win32 - активация события, расположенного в меню приложения (см. ниже). + +![Calc Vid Programmist](https://habrastorage.org/webt/-u/u-/ss/-uu-ss0_0dp6bg5pnw8opmbay38.png) + +*Вид "Программист" в калькуляторе* + + +Активация элемента меню выполняется с помощью специальной функции *menu_select* у корневого UIO объекта GUI приложения. + + + +- С помощью студии pyOpenRPA сформируем UIO селектор корневого объекта калькулятора + + ``` +lUIOSelectorCalculator = [{"title":"Калькулятор","class_name":"CalcFrame","backend":"win32"}] # Сформировали UIO селектор из студии pyOpenRPA +``` + +- Далее запросим UIO объект по UIO селектору, после чего вызовем функцию *menu_select*, в которую передадим строковый адрес вызываемого элемента меню + + ``` +lUIOCalculator = UIDesktop.UIOSelector_Get_UIO(inSpecificationList=lUIOSelectorCalculator) # Получить UIO экземпляр +lUIOCalculator.menu_select("&Вид -> &Программист") # Выполнить смену режима калькулятора +``` + + + +## Шаг 3. Консолидируем код в проекте робота + +Обадая всеми необходимыми UIO селекторами и функциями, перейдем к составлению целостного скрипта робота. Ниже я приведу код RobotCalc_1.py файла, готового для запуска (python.exe "RobotCalc_1.py") c детальным описанием каждой строки. + +``` +from pyOpenRPA.Robot import UIDesktop # Импорт модуля, который умеет управлять UI элеметами GUI приложений +import time # Библиотека сна алгоритма +import os # Библиотека системных функций, позволит открять калькулятор, если это потребуется +lUIOSelectorCalculator = [{"title":"Калькулятор","class_name":"CalcFrame","backend":"win32"}] # Сформировали UIO селектор из студии pyOpenRPA +while True: # Вечный цикл + lUIOCalculator = UIDesktop.UIOSelector_Get_UIO(inSpecificationList=lUIOSelectorCalculator) # Получить UIO экземпляр + lCalcHex_IsExistBool = UIDesktop.UIOSelector_Exist_Bool(inUIOSelector=[{"class_name":"CalcFrame","backend":"win32"},{ "title":"Hex", "depth_start":3, "depth_end": 3}]) # Проверить наличие UI элемента по UIO селектору + if not lCalcHex_IsExistBool: # Проверить, что UI элемент отсутствует + lUIOCalculator.menu_select("&Вид -> &Программист") # Выполнить смену режима калькулятора + time.sleep(1) # Выполнить сон на 1 сек., после чего перейти на следующую итерацию +``` + +Внимание! При запуске робота убедитесь в том, что калькулятор находится в активном состоянии на экране вашего компьютера. Робот начнет отслеживать состояние калькулятора. Если в калькуляторе не будет установлен режим программиста, то робот в течение 1 секунды вернет его в данный режим. + + + +## Дополнение. Дорабатываем робота, чтобы он еще включал калькулятор (если он выключен), раскрывал его (если он свернут) + +- Для решения поставленной задачи мы уже обладаем всеми необходимыми UIO селекторами. Необходимо только определиться с функциями, которые дополнительно будем использовать. + +- Для запуска калькулятора будем использовать функцию *os.system* + +``` +os.system("calc") # Открыть калькулятор +``` + + +- Для проверки состояния окна (свернуто в трэй или развернуто) *is_minimized* + +``` +lUIOCalculator.is_minimized() +``` + +- Для восстановления свернутого окна будем использовать функцию *restore* + +``` +lUIOCalculator.restore() # Восстановить окно калькулятора из свернутого вида +``` + + + +- Итого получим следующий исходный код робота (файл RobotCalc_2.py). + +``` +from pyOpenRPA.Robot import UIDesktop # Импорт модуля, который умеет управлять UI элеметами GUI приложений +import time # Библиотека сна алгоритма +import os # Билбиотека системных функций, позволит открять калькулятор, если это потребуется +lUIOSelectorCalculator = [{"title":"Калькулятор","class_name":"CalcFrame","backend":"win32"}] # Сформировали UIO селектор из студии pyOpenRPA +while True: # Вечный цикл + lExistBool = UIDesktop.UIOSelector_Exist_Bool(inUIOSelector=lUIOSelectorCalculator) # Проверить наличие окна по UIO селектору + if not lExistBool: # Проверить наличие окна калькулятора + os.system("calc") # Открыть калькулятор + else: # Проверить, что окно калькулятора не свернуто + lUIOCalculator = UIDesktop.UIOSelector_Get_UIO(inSpecificationList=lUIOSelectorCalculator) # Получить UIO экземпляр + if lUIOCalculator.is_minimized(): # Проверить, что калькулятор находится в свернутом виде + lUIOCalculator.restore() # Восстановить окно калькулятора из свернутого вида + else: + lCalcHex_IsExistBool = UIDesktop.UIOSelector_Exist_Bool(inUIOSelector=[{"class_name":"CalcFrame","backend":"win32"},{ "title":"Hex", "depth_start":3, "depth_end": 3}]) # Проверить наличие UI элемента по UIO селектору + if not lCalcHex_IsExistBool: # Проверить, что UI элемент отсутствует + lUIOCalculator.menu_select("&Вид -> &Программист") # Выполнить смену режима калькулятора + time.sleep(1) # Выполнить сон на 1 сек., после чего перейти на следующую итерацию +``` + +*PS 1. Для сравнения: Реализация аналогичного алгоритма в другой RPA платформе с помощью инструментов визуального программирования потребует в **3-4 раза больше пространства рабочей области экрана** (в связи со спецификой визуального программирования).* + +*PS 2. Перечень всех функций в модуле UIDesktop (pyOpenRPA/Robot/UIDesktop.py) +Ознакомиться в полным перечнем функций модуля UIDesktop [можно здесь](https://gitlab.com/UnicodeLabs/OpenRPA/-/blob/master/Wiki/05.2.-Theory-&-practice.-Desktop-app-UI-access-(win32-and-UI-automation-dlls).md)* + + + +# Подведем итоги +Итак, мы успешно преодолели первые шаги по созданию бесплатных программных роботов. Безусловно, эта статья покрывает далеко не все области программной роботизации. В следующих статьях-туториалах мы остановимся на оставшихся "столпах" роботизированного управления (мышь, клавиатура, распознавание изображения с экрана и web манипуляции). + +Надеюсь, что рассмотренные технологии, в первую очередь, помогут вам или вашей компании в достижении поставленных целей. А во вторую очередь, пусть получают выгоду и другие участники RPA рынка (да, я про вендоров платных RPA платформ, многие из которых базируются в США). + +Всегда открыт к вашим комментариям, и буду рад помочь вам в решении ваших вопросов. + +До скорых публикаций! \ No newline at end of file diff --git a/Wiki/RUS Tutorial/DesktopGUI_Habr/Notepad_human.PNG b/Wiki/RUS Tutorial/DesktopGUI_Habr/Notepad_human.PNG new file mode 100644 index 00000000..b7de187a Binary files /dev/null and b/Wiki/RUS Tutorial/DesktopGUI_Habr/Notepad_human.PNG differ diff --git a/Wiki/RUS Tutorial/DesktopGUI_Habr/Notepad_pyOpenRPA.png b/Wiki/RUS Tutorial/DesktopGUI_Habr/Notepad_pyOpenRPA.png new file mode 100644 index 00000000..aba4a920 Binary files /dev/null and b/Wiki/RUS Tutorial/DesktopGUI_Habr/Notepad_pyOpenRPA.png differ diff --git a/Wiki/RUS Tutorial/Navigation.md b/Wiki/RUS Tutorial/Navigation.md new file mode 100644 index 00000000..3af10792 --- /dev/null +++ b/Wiki/RUS Tutorial/Navigation.md @@ -0,0 +1,11 @@ + +# Навигация по статьям + +Так как [pyOpenRPA](https://gitlab.com/UnicodeLabs/OpenRPA) - это достаточно крупная RPA платформа: туториал будет составлен в виде серий статей, в которых будут освещаться ключевые технологии. А уже освоив эти технологии, у вас появится возможность углубиться в то, что вам нужно. + +**Ниже приведу планируемый перечень статей по этой тематике (для навигации):** + +- [pyOpenRPA туториал. Управление оконными GUI приложениями](DesktopGUI_Habr/DesktopGUI_Habr.md) +- pyOpenRPA туториал. Управление WEB приложениями (то, что мы смотрим в Chrome, Firefox, Opera) +- pyOpenRPA туториал. Управление клавиатурой & мышью +- pyOpenRPA туториал. Распознавание графических объектов на экране