@ -18,12 +18,15 @@ from threading import Timer
import datetime
import logging
import re
import copy
#Создать файл логирования
# add filemode="w" to overwrite
if not os . path . exists ( " Reports " ) :
os . makedirs ( " Reports " )
logging . basicConfig ( filename = " Reports \ ReportRobotGUIRun_ " + datetime . datetime . now ( ) . strftime ( " % Y_ % m_ %d __ % H_ % M_ % S " ) + " .log " , level = logging . INFO , format = " %(asctime)s - %(name)s - %(levelname)s - %(message)s " )
#####Внимание#######
#TODO В перспективе нужно реализовать алгоритм определения разрядности не в Robot.py, а в GUI.py, тк начинают появляться функции, на входе в которые еще неизвестна разрядность элемента + селектор может охватить сразу два элемента из 2-х разных разрядностей - обрабатываться это должно непосредственно при выполнении
####################################
#Info: GUI module of the Robot app (OpenRPA - Robot)
@ -108,9 +111,10 @@ def UIOSelector_Get_UIOList (inSpecificationList,inElement=None,inFlagRaiseExcep
if inElement is None :
#сформировать спецификацию на получение элемента
lRootElementSpecification = [ inSpecificationList [ 0 ] ]
lRootElement = PWASpecification_Get_UIO ( lRootElementSpecification )
if lRootElement is not None :
lChildrenList . append ( lRootElement . wrapper_object ( ) )
lRootElementList = PWASpecification_Get_UIO ( lRootElementSpecification )
for lRootItem in lRootElementList :
if lRootItem is not None :
lChildrenList . append ( lRootItem . wrapper_object ( ) )
#Елемент на вход поступил - выполнить е г о анализ
else :
#Получить список элементов
@ -136,7 +140,6 @@ def UIOSelector_Get_UIOList (inSpecificationList,inElement=None,inFlagRaiseExcep
if ' depth_start ' in inSpecificationList [ 0 ] :
if inSpecificationList [ 0 ] [ " depth_start " ] > 1 :
lFlagGoCheck = False
#pdb.set_trace()
#Циклический обход по детям, на предмет соответствия всем условиям
for lChildrenItem in lElementChildrenList :
#Обработка глубины depth (рекурсивный вызов для всех детей с занижением индекса глубины)
@ -149,7 +152,6 @@ def UIOSelector_Get_UIOList (inSpecificationList,inElement=None,inFlagRaiseExcep
lChildrenItemNewSpecificationList [ 0 ] [ " depth_end " ] = lChildrenItemNewSpecificationList [ 0 ] [ " depth_end " ] - 1
if ' depth_start ' in lChildrenItemNewSpecificationList [ 0 ] :
lChildrenItemNewSpecificationList [ 0 ] [ " depth_start " ] = lChildrenItemNewSpecificationList [ 0 ] [ " depth_start " ] - 1
#pdb.set_trace()
#Циклический вызов для всех детей с о скорректированной спецификацией
lResultList . extend ( UIOSelector_Get_UIOList ( lChildrenItemNewSpecificationList , lChildrenItem , inFlagRaiseException ) )
#Фильтрация
@ -246,6 +248,8 @@ def UIOSelector_Exist_Bool (inSpecificationList):
#inFlagWaitAllInMoment - доп. условие - ожидать появление всех UIOSelector одновременно
#return: [0,1,2] - index of UIOSpecification, which is appear
#old name - -
#####Внимание#####
##Функция ожидания появления элементов (тк элементы могут быть недоступны, неизвестно в каком фреймворке каждый из них может появиться)
def UIOSelectorsSecs_WaitAppear_List ( inSpecificationListList , inWaitSecs , inFlagWaitAllInMoment = False ) :
lResultFlag = False
lSecsSleep = 1 #Настроечный параметр
@ -294,7 +298,6 @@ def UIOSelectorSecs_WaitAppear_Bool (inSpecificationList,inWaitSecs):
#return None (if Process not found), int 32, or int 64
def UIOSelector_Get_BitnessInt ( inSpecificationList ) :
lResult = None
#pdb.set_trace()
#Получить объект Application (Для проверки разрядности)
lRootElement = PWASpecification_Get_PWAApplication ( inSpecificationList )
if lRootElement is not None :
@ -315,43 +318,54 @@ def Get_OSBitnessInt ():
##################################################################################################
#inControlSpecificationArray - List of dict, dict in pywinauto.find_windows notation
#Backend selection - attribute "backend" ("win32" || "uia") in 1-st list element
#return UIO object
#return list of UIO object
#old name - GetControl
def PWASpecification_Get_UIO ( inControlSpecificationArray ) :
#Определение backend
lBackend = mDefaultPywinautoBackend
#pdb.set_trace()
if " backend " in inControlSpecificationArray [ 0 ] :
lBackend = inControlSpecificationArray [ 0 ] [ " backend " ]
inControlSpecificationArray [ 0 ] . pop ( " backend " )
#Подготовка входного массива
inControlSpecificationOriginArray = inControlSpecificationArray
inControlSpecificationOriginArray = copy. deepcopy ( inControlSpecificationArray)
inControlSpecificationArray = UIOSelector_SearchProcessNormalize_UIOSelector ( inControlSpecificationArray )
#Выполнить идентификацию объектов, если передан массив
lResultList = [ ] ;
lTempObject = None
if len ( inControlSpecificationArray ) > 0 :
#Выполнить подключение к объекту
lRPAApplication = pywinauto . Application ( backend = lBackend )
#Проверка разрядности
try :
lRPAApplication . connect ( * * inControlSpecificationArray [ 0 ] )
except Exception as e :
UIOSelector_TryRestore_Dict ( inControlSpecificationArray )
#Сформировать выборку элементов, которые подходят под первый уровень спецификации
lSpecificationLvL1List = pywinauto . findwindows . find_elements ( * * inControlSpecificationArray [ 0 ] )
for lItem in lSpecificationLvL1List :
#Сделать независимую копию и установить информацию о process_id и handle
lItemControlSpecificationArray = copy . deepcopy ( inControlSpecificationArray )
lItemControlSpecificationArray [ 0 ] [ " process_id " ] = lItem . process_id
lItemControlSpecificationArray [ 0 ] [ " handle " ] = lItem . handle
lItemControlSpecificationOriginArray = copy . deepcopy ( inControlSpecificationOriginArray )
lItemControlSpecificationOriginArray [ 0 ] [ " process_id " ] = lItem . process_id
lItemControlSpecificationOriginArray [ 0 ] [ " handle " ] = lItem . handle
#Выполнить подключение к объекту
lRPAApplication = pywinauto . Application ( backend = lBackend )
#Проверка разрядности
try :
lRPAApplication . connect ( * * inControlSpecificationArray [ 0 ] )
lRPAApplication . connect ( * * lItem ControlSpecificationArray[ 0 ] )
except Exception as e :
lRPAApplication = None
if lRPAApplication is not None :
#lTempObject=lRPAApplication.window(**inControlSpecificationArray[0])
#Скорректировано из-за недопонимания структуры
lTempObject = lRPAApplication
#Нормализация массива для целей выборки объекта (удаление конфликтующих ключей)
inControlSpecificationArray = UIOSelector_SearchUIONormalize_UIOSelector ( inControlSpecificationOriginArray )
#Циклическое прохождение к недрам объекта
for lWindowSpecification in inControlSpecificationArray [ 0 : ] :
lTempObject = lTempObject . window ( * * lWindowSpecification )
return lTempObject
UIOSelector_TryRestore_Dict ( lItemControlSpecificationArray )
try :
lRPAApplication . connect ( * * lItemControlSpecificationArray [ 0 ] )
except Exception as e :
lRPAApplication = None
if lRPAApplication is not None :
#lTempObject=lRPAApplication.window(**lItemControlSpecificationArray[0])
#Скорректировано из-за недопонимания структуры
lTempObject = lRPAApplication
#Нормализация массива для целей выборки объекта (удаление конфликтующих ключей)
lItemControlSpecificationArray = UIOSelector_SearchUIONormalize_UIOSelector ( lItemControlSpecificationOriginArray )
#Циклическое прохождение к недрам объекта
for lWindowSpecification in lItemControlSpecificationArray [ 0 : ] :
lTempObject = lTempObject . window ( * * lWindowSpecification )
#Добавить объект в результирующий массив
lResultList . append ( lTempObject )
return lResultList
##################################################################################################
#inControlSpecificationArray - List of dict, dict in pywinauto.find_windows notation
#Backend selection - attribute "backend" ("win32" || "uia") in 1-st list element
@ -360,7 +374,6 @@ def PWASpecification_Get_UIO(inControlSpecificationArray):
def PWASpecification_Get_PWAApplication ( inControlSpecificationArray ) :
#Определение backend
lBackend = mDefaultPywinautoBackend
#pdb.set_trace()
if " backend " in inControlSpecificationArray [ 0 ] :
lBackend = inControlSpecificationArray [ 0 ] [ " backend " ]
inControlSpecificationArray [ 0 ] . pop ( " backend " )
@ -441,7 +454,6 @@ def UIOSelector_SearchChildByMouse_UIOTree(inElementSpecification):
#Detect backend of the elements
lFlagIsBackendWin32 = True
#Если объект имеется (не None), то выполнить построение иерархии
#pdb.set_trace()
if lElement is not None :
if lElement . backend . name == ' uia ' :
lFlagIsBackendWin32 = False
@ -1016,7 +1028,6 @@ def UIO_Highlight(lWrapperObject,colour='green',thickness=2,fill=win32defines.BS
#Установить фокус на объект, чтобы было видно выделение
lWrapperObject . set_focus ( )
time . sleep ( 0.5 )
#pdb.set_trace()
# don't draw if dialog is not visible
#if not lWrapperObject.is_visible():
# return
@ -1095,7 +1106,7 @@ if not mFlagIsDebug:
lJSONInput = ProcessCommunicator . ProcessParentReadWaitObject ( )
lProcessResponse [ " ActivitySpecificationDict " ] = lJSONInput
#Выполнить вызов функции
lProcessResponse [ " Result " ] = JSONNormalize . JSONNormalizeDictListStrInt ( locals ( ) [ lJSONInput [ ' ActivityName ' ] ] ( * lJSONInput [ ' ArgumentList ' ] , * * lJSONInput [ ' ArgumentDict ' ] ) )
lProcessResponse [ " Result " ] = JSONNormalize . JSONNormalizeDictListStrInt Bool ( locals ( ) [ lJSONInput [ ' ActivityName ' ] ] ( * lJSONInput [ ' ArgumentList ' ] , * * lJSONInput [ ' ArgumentDict ' ] ) )
except Exception as e :
#Установить флаг ошибки
lProcessResponse [ " ErrorFlag " ] = True