v1.0.27 in Portable python x32 and x64

dev-linux
Ivan Maslov 5 years ago
parent 84c995b543
commit 1c2d3f7b0a

@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: pyOpenRPA
Version: 1.0.24
Version: 1.0.27
Summary: First open source RPA platform for business
Home-page: https://gitlab.com/UnicodeLabs/OpenRPA
Author: Ivan Maslov

@ -172,13 +172,13 @@
../../pyOpenRPA/Resources/Web/Semantic-UI-CSS-master/themes/default/assets/fonts/outline-icons.woff2,sha256=TSiDRDsk5CRSf2oKeqKJez33HyOdtANzxP92DkgUeAE,12240
../../pyOpenRPA/Resources/Web/Semantic-UI-CSS-master/themes/default/assets/images/flags.png,sha256=lNXH8WYTAcSm3Ekdct1VmgYgzZF6gm8N8bAju5bqnd0,28123
../../pyOpenRPA/Resources/Web/jQuery/jquery-3.1.1.min.js,sha256=HPMOWdIdSuVgr3FD9ZE-_MgiK8qk_MdQjrgCtfqp6U4,86713
../../pyOpenRPA/Studio/Web/Index.xhtml,sha256=8VWQhvgdybwEEhwnwGtSCgPwauqPF9A-bVndhVaF0qc,44016
../../pyOpenRPA/Studio/Web/Index.xhtml,sha256=74z3eWlmB6Yedbp91xgGtDjymUSlBcduAQ09ZxQ67f8,44241
../../pyOpenRPA/Studio/Web/favicon.ico,sha256=0vdsnwKGh6pgB0FDB5mOKO7RwbxQ9F13Zg16F1pkvXs,5430
pyOpenRPA-1.0.24.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pyOpenRPA-1.0.24.dist-info/METADATA,sha256=ZAcOkPd55_35oltDf_K8EP6bLBhMuZHOhD2Kj1fZXwA,3510
pyOpenRPA-1.0.24.dist-info/RECORD,,
pyOpenRPA-1.0.24.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97
pyOpenRPA-1.0.24.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10
pyOpenRPA-1.0.27.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pyOpenRPA-1.0.27.dist-info/METADATA,sha256=_Y3EhPYpKcvrrAWGgh0dkV-QqKaADkkSh7eOMoz0xcw,3510
pyOpenRPA-1.0.27.dist-info/RECORD,,
pyOpenRPA-1.0.27.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97
pyOpenRPA-1.0.27.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10
pyOpenRPA/Orchestrator/Orchestrator.py,sha256=mlxsd8YMs9X_Een8HfOlCv5d_LVgcx21UAQphHFfD_M,6689
pyOpenRPA/Orchestrator/Processor.py,sha256=GHXwC1B2py4mAtk9oZa-FVSJhx3no9oD2bvkj20uhNA,9051
pyOpenRPA/Orchestrator/Server.py,sha256=GH7P0L-83ONlRdVYu3oQqt2oCgXPXYjrcFb0tY_6SYU,12878
@ -368,14 +368,17 @@ pyOpenRPA/Resources/Web/jQuery/jquery-3.1.1.min.js,sha256=HPMOWdIdSuVgr3FD9ZE-_M
pyOpenRPA/Robot/Clipboard.py,sha256=q76X8L21zJwcwdoJJNPeCEwAV30xS6ylHP1WwvtxoWI,722
pyOpenRPA/Robot/IntegrationOrchestrator.py,sha256=T1g1jJM7_JMTSVP50DTM5WHrMh1w8wovvcBXl1nEokU,2656
pyOpenRPA/Robot/JSONNormalize.py,sha256=aIuVzuZDazhxkCOzoOjfhHVz66mp2FWdfPv5E7KWF5Y,3890
pyOpenRPA/Robot/ProcessBitness.py,sha256=g5RWJ4Yzz6jAFaA3bj1WHoEFphb40BsOwaUob38BvG8,4270
pyOpenRPA/Robot/ProcessCommunicator.py,sha256=Mpo2WoCrEUmY6aCSbQEXkT4qVKtN1N5NcVvG_UZxGVo,8245
pyOpenRPA/Robot/Robot.py,sha256=AVR8jzO-e_ZkW5DrLY_W9ta0eHSul997Y3U6uNVU8WE,9442
pyOpenRPA/Robot/UIDesktop.py,sha256=sUDelnGuL-9Kcw-eS5RzMnR3ynjoDokmJvkHZJdeY3o,66206
pyOpenRPA/Robot/UIDesktop.py,sha256=ehqMQmKLbkwW6iqA9bkw9tvDRni5QriLkG9P3AP_TMs,78377
pyOpenRPA/Robot/Utils/ProcessBitness.py,sha256=WlKL-DklGaoTnchtapOTM_ydxSB4yOeo9lcG3zr2VME,4524
pyOpenRPA/Robot/Utils/__init__.py,sha256=pHlSQGRFKmn5RCTHIf-3a2ooA9T2xNOWridckynP7W4,28
pyOpenRPA/Robot/Utils/__pycache__/ProcessBitness.cpython-37.pyc,,
pyOpenRPA/Robot/Utils/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Robot/ValueVerify.py,sha256=ObskxU4fOMoCGw74_nzYt6-a5jjrAckb3sdBLYyhYxY,777
pyOpenRPA/Robot/Window.py,sha256=UJl-sg4RvvJ35aG9jZOzqGVwE15XK7qPHqoOBD13xFk,431
pyOpenRPA/Robot/__init__.py,sha256=iEW3SGBJf3kYa1zocGH5vEK0woejzJpnQfOmQtIA3P0,324
pyOpenRPA/Robot/__main__.py,sha256=SRwA1L-cRhCaH8MhO3sOdc7dT6Ha2VT6Xzr7CPz4a_g,1922
pyOpenRPA/Robot/__main__.py,sha256=NlwxAG68mwoWNB4YIX15Fc2gWlL1RQ5HN8i1NyjGFdo,1965
pyOpenRPA/Robot/__pycache__/Clipboard.cpython-37.pyc,,
pyOpenRPA/Robot/__pycache__/IntegrationOrchestrator.cpython-37.pyc,,
pyOpenRPA/Robot/__pycache__/JSONNormalize.cpython-37.pyc,,
@ -390,15 +393,25 @@ pyOpenRPA/Studio/JSONNormalize.py,sha256=g0Z8G2wojCgTAdZtyRiCfe0_FHSeAi72Va7R7mk
pyOpenRPA/Studio/ProcessCommunicator.py,sha256=5hXDMa4ONBgeJBoDIfDCAW9MoiRO8cq-DdfqQSAysgk,8080
pyOpenRPA/Studio/Studio.py,sha256=7X46k0l33sgQoG6sxFFJmI5G0KKxgDggvEnzux8aonw,7014
pyOpenRPA/Studio/ValueVerify.py,sha256=ObskxU4fOMoCGw74_nzYt6-a5jjrAckb3sdBLYyhYxY,777
pyOpenRPA/Studio/Web/Index.xhtml,sha256=8VWQhvgdybwEEhwnwGtSCgPwauqPF9A-bVndhVaF0qc,44016
pyOpenRPA/Studio/Web/Index.xhtml,sha256=74z3eWlmB6Yedbp91xgGtDjymUSlBcduAQ09ZxQ67f8,44241
pyOpenRPA/Studio/Web/favicon.ico,sha256=0vdsnwKGh6pgB0FDB5mOKO7RwbxQ9F13Zg16F1pkvXs,5430
pyOpenRPA/Studio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Studio/__main__.py,sha256=RThggw-laywijkYim7zxlYDIPyj0isYLb3WXxQery2s,119
pyOpenRPA/Studio/__main__.py,sha256=_57Rnq9DKbmmlpGFqIwVrWn_LRcU8jjmMTOny4_zlP8,308
pyOpenRPA/Studio/__pycache__/JSONNormalize.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/ProcessCommunicator.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/Studio.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/ValueVerify.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/__main__.cpython-37.pyc,,
pyOpenRPA/__init__.py,sha256=zTI_hbFr447QvQDROWtoVFEPlP7Vy9op1ceyHrmIJmY,175
pyOpenRPA/Tools/RobotRDPActive/RDPConnector.py,sha256=sU79Pd4ehuubZohzUFxkuFOo79Xhicr3sY1HhKaeRhg,1903
pyOpenRPA/Tools/RobotRDPActive/SettingsExample.py,sha256=BjLCZW8fJkoHISJi_ygDG5aBl5jLdOrRolsj3wL7vww,84
pyOpenRPA/Tools/RobotRDPActive/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Tools/RobotRDPActive/__main__.py,sha256=bQZTpQoc50J4UaSRGTSQS2ZAY3iG4eLNaVTc6axXJJ8,834
pyOpenRPA/Tools/RobotRDPActive/__pycache__/RDPConnector.cpython-37.pyc,,
pyOpenRPA/Tools/RobotRDPActive/__pycache__/SettingsExample.cpython-37.pyc,,
pyOpenRPA/Tools/RobotRDPActive/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Tools/RobotRDPActive/__pycache__/__main__.cpython-37.pyc,,
pyOpenRPA/Tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Tools/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/__init__.py,sha256=8FWo2oWf0H8ujn6HQxmH46hGU0R2CTg7nUDUXHnqPoE,175
pyOpenRPA/__pycache__/__init__.cpython-37.pyc,,

@ -1,81 +0,0 @@
import pywinauto #Is needed to detect OS bitness
import struct # Need to detect Current process bitness
import subprocess #Need to create subprocess
import os # Is needed to check file/folder path
############################################
####Module, which control the Bitness between 32 and 64 python (needed for pywinauto framework to work correctly)
############################################
global mSettingsDict
mSettingsDict = {
"BitnessProcessCurrent": "64", # "64" or "32"
"BitnessOS": "64", # "64" or "32"
"Python32FullPath": None, #Set from user: "..\\Resources\\WPy32-3720\\python-3.7.2\\OpenRPARobotGUIx32.exe"
"Python64FullPath": None, #Set from user
"Python32ProcessName": "OpenRPAUIDesktopX32.exe", #Config set once
"Python64ProcessName": "OpenRPAUIDesktopX64.exe", #Config set once
"Python32Process":None,
"Python64Process":None,
"PythonArgs":["-m","pyOpenRPA"] #Start other bitness openRPA process with PIPE channel
}
#Init the global configuration
def SettingsInit(inSettingsDict):
global mSettingsDict
#Update values in settings from input
mSettingsDict.update(inSettingsDict)
#mSettingsDict = inSettingsDict
####################
#Detect OS bitness
####BitnessOS#######
lBitnessOS="32";
if pywinauto.sysinfo.is_x64_OS():
lBitnessOS="64";
inSettingsDict["BitnessOS"]=lBitnessOS
####################
#Detect current process bitness
####BitnessProcessCurrent#######
lBitnessProcessCurrent = str(struct.calcsize("P") * 8)
inSettingsDict["BitnessProcessCurrent"]=lBitnessProcessCurrent
#####################################
#Create the other bitness process if OS is 64 and we have another Python path
##########################################################################
#Check if OS is x64, else no 64 is applicable
if mSettingsDict["BitnessOS"]=="64":
#Check if current bitness is 64
if mSettingsDict["BitnessProcessCurrent"]=="64":
#create x32 if Python 32 path is exists
if mSettingsDict["Python32FullPath"] and mSettingsDict["Python32ProcessName"]:
#Calculate python.exe folder path
lPython32FolderPath= "\\".join(mSettingsDict["Python32FullPath"].split("\\")[:-1])
lPython32NewNamePath = f"{lPython32FolderPath}\\{mSettingsDict["Python32ProcessName"]}"
if not os.path.isfile(lPython32NewNamePath):
shutil.copyfile(mSettingsDict["Python32FullPath"],lPython32NewNamePath)
mSettingsDict["Python32Process"] = subprocess.Popen([lPython32NewNamePath] + mSettingsDict["Python32FullPath"],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
else:
#bitness current process is 32
#return x64 if it is exists
if mSettingsDict["Python64Process"]:
#Calculate python.exe folder path
lPython64FolderPath= "\\".join(mSettingsDict["Python64FullPath"].split("\\")[:-1])
lPython64NewNamePath = f"{lPython64FolderPath}\\{mSettingsDict["Python64ProcessName"]}"
if not os.path.isfile(lPython64NewNamePath):
shutil.copyfile(mSettingsDict["Python32FullPath"],lPython64NewNamePath)
mSettingsDict["Python64Process"] = subprocess.Popen([lPython64NewNamePath] + mSettingsDict["Python64FullPath"],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
#Return the other module bitnes
def OtherBitnessGet():
#Result template
lResult = None
global mSettingsDict
#Check if OS is x64, else no 64 is applicable
if mSettingsDict["BitnessOS"]=="64":
#Check if current bitness is 64
if mSettingsDict["BitnessProcessCurrent"]=="64":
#return x32 if it is exists
if mSettingsDict["Python32Process"]:
lResult = mSettingsDict["Python32Process"]
else:
#bitness current process is 32
#return x64 if it is exists
if mSettingsDict["Python64Process"]:
lResult = mSettingsDict["Python64Process"]
#Exit
return lResult

@ -14,11 +14,13 @@ import time
import traceback
from . import ProcessCommunicator
from . import JSONNormalize
from . import Utils #For ProcessBitness
from threading import Timer
import datetime
import logging
import re
import copy
#Создать файл логирования
# add filemode="w" to overwrite
if not os.path.exists("Reports"):
@ -34,7 +36,16 @@ mRobotLoggerFormatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)
mRobotLoggerFH.setFormatter(mRobotLoggerFormatter)
# add handler to logger object
mRobotLogger.addHandler(mRobotLoggerFH)
############################################
#When import UIDesktop init the other bitness python
#For this type UIDesktop.Utils.ProcessBitness.SettingsInit(inSettingsDict)
#inSettingsDict = {
# "Python32FullPath": None, #Set from user: "..\\Resources\\WPy32-3720\\python-3.7.2\\OpenRPARobotGUIx32.exe"
# "Python64FullPath": None, #Set from user
# "Python32ProcessName": "OpenRPAUIDesktopX32.exe", #Config set once
# "Python64ProcessName": "OpenRPAUIDesktopX64.exe" #Config set once
#}
############################################
#logging.basicConfig(filename="Reports\ReportRobotGUIRun_"+datetime.datetime.now().strftime("%Y_%m_%d")+".log", level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
@ -258,14 +269,32 @@ def UIOSelector_Get_UIO (inSpecificationList,inElement=None,inFlagRaiseException
return lResult
#################################################################################################
#Check if UIO exist (Identified by the UIOSelector)
#inSpecificationList - UIOSelector
#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!!
#UIOSelector
#old name - -
def UIOSelector_Exist_Bool (inSpecificationList):
def UIOSelector_Exist_Bool (inUIOSelector):
lResult=False
#Получить родительский объект если на вход ничего не поступило
lResultList=UIOSelector_Get_UIOList(inSpecificationList,None,False)
if len(lResultList)>0:
lResult=True
#Check the bitness
lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector)
if lSafeOtherProcess is None:
#Получить родительский объект если на вход ничего не поступило
lResultList=UIOSelector_Get_UIOList(inUIOSelector, None, False)
if len(lResultList)>0:
lResult=True
else:
# Run function from other process with help of PIPE
lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_Exist_Bool",
"ArgumentList": [inUIOSelector],
"ArgumentDict": {}}
# Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
ProcessCommunicator.ProcessChildSendObject(lSafeOtherProcess, lPIPEResuestDict)
# Get answer from child process
lPIPEResponseDict = ProcessCommunicator.ProcessChildReadWaitObject(lSafeOtherProcess)
if lPIPEResponseDict["ErrorFlag"]:
raise Exception(
f"Exception was occured in child process (message): {lPIPEResponseDict['ErrorMessage']}, (traceback): {lPIPEResponseDict['ErrorTraceback']}")
else:
lResult = lPIPEResponseDict["Result"]
return lResult
#################################################################################################
#Wait for UIO is appear (at least one of them or all at the same time)
@ -385,6 +414,21 @@ def UIOSelector_Get_BitnessInt (inSpecificationList):
lResult=32
return lResult
#################################################################################################
#Get process bitness ("32" or "64")
#inSpecificationList - UIOSelector
#old name - None
#return None (if Process not found), int 32, or int 64
def UIOSelector_Get_BitnessStr (inSpecificationList):
lResult=None
#Получить объект Application (Для проверки разрядности)
lRootElement=PWASpecification_Get_PWAApplication(inSpecificationList)
if lRootElement is not None:
if lRootElement.is64bit():
lResult="64"
else:
lResult="32"
return lResult
#################################################################################################
#Get OS bitness (32 or 64)
#old name - None
#return int 32, or int 64
@ -393,6 +437,20 @@ def Get_OSBitnessInt ():
if pywinauto.sysinfo.is_x64_OS():
lResult=64;
return lResult;
#################################################################################################
#Safe get other process or None if destination app is the other/same bitness
#inUIOSelector - selector of the destination
#return None or process (of the other bitness)
def UIOSelector_SafeOtherGet_Process(inUIOSelector):
#Default value
lResult = None
#Go check bitness if selector exists
if inUIOSelector:
#Get selector bitness
lUIOSelectorAppBitness = UIOSelector_Get_BitnessStr(inUIOSelector)
if lUIOSelectorAppBitness and Utils.ProcessBitness.mSettingsDict["BitnessProcessCurrent"] != lUIOSelectorAppBitness:
lResult = Utils.ProcessBitness.OtherProcessGet()
return lResult
##################################################################################################
#inControlSpecificationArray - List of dict, dict in pywinauto.find_windows notation
#Backend selection - attribute "backend" ("win32" || "uia") in 1-st list element
@ -450,6 +508,7 @@ def PWASpecification_Get_UIO(inControlSpecificationArray):
#return process application object
#old name - None
def PWASpecification_Get_PWAApplication(inControlSpecificationArray):
inControlSpecificationArray=copy.deepcopy(inControlSpecificationArray)
#Определение backend
lBackend=mDefaultPywinautoBackend
if "backend" in inControlSpecificationArray[0]:
@ -523,48 +582,66 @@ def UIOSelector_SearchChildByMouse_UIO(inElementSpecification):
####################################################################################################
#inElementSpecification - UIOSelector
#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!!
#old name - AutomationSearchMouseElementHierarchy
def UIOSelector_SearchChildByMouse_UIOTree(inElementSpecification):
def UIOSelector_SearchChildByMouse_UIOTree(inUIOSelector):
lItemInfo = []
#Запустить функцию поиска элемента по мыши
lElementList = UIOSelector_SearchChildByMouse_UIO(inElementSpecification)
lElement = lElementList[-1]['element']
#Detect backend of the elements
lFlagIsBackendWin32 = True
#Если объект имеется (не None), то выполнить построение иерархии
if lElement is not None:
if lElement.backend.name == 'uia':
lFlagIsBackendWin32 = False
#Циклическое создание дерева
#while lElement is not None:
lListIterator=0
lItemInfo2=lItemInfo
for lListItem in lElementList:
lElement = lListItem["element"]
#Продолжать построение иерархии во всех случаях кроме бэк uia & parent() is None
#if not lFlagIsBackendWin32 and lElement.parent() is None:
# lElement = None
#else:
#Получить информацию про объект
lItemInfo2.append(UIOEI_Convert_UIOInfo(lElement.element_info))
#Дообогатить информацией об индексе ребенка в родительском объекте
if "index" in lListItem:
if lListItem["index"] is not None:
lItemInfo2[-1]['ctrl_index']=lListItem["index"]
#Check the bitness
lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector)
if lSafeOtherProcess is None:
#Запустить функцию поиска элемента по мыши
lElementList = UIOSelector_SearchChildByMouse_UIO(inUIOSelector)
lElement = lElementList[-1]['element']
#Detect backend of the elements
lFlagIsBackendWin32 = True
#Если объект имеется (не None), то выполнить построение иерархии
if lElement is not None:
if lElement.backend.name == 'uia':
lFlagIsBackendWin32 = False
#Циклическое создание дерева
#while lElement is not None:
lListIterator=0
lItemInfo2=lItemInfo
for lListItem in lElementList:
lElement = lListItem["element"]
#Продолжать построение иерархии во всех случаях кроме бэк uia & parent() is None
#if not lFlagIsBackendWin32 and lElement.parent() is None:
# lElement = None
#else:
#Получить информацию про объект
lItemInfo2.append(UIOEI_Convert_UIOInfo(lElement.element_info))
#Дообогатить информацией об индексе ребенка в родительском объекте
if "index" in lListItem:
if lListItem["index"] is not None:
lItemInfo2[-1]['ctrl_index']=lListItem["index"]
else:
if "ctrl_index" in lListItem:
lItemInfo2[-1]['ctrl_index']=lListItem["ctrl_index"]
else:
if "ctrl_index" in lListItem:
lItemInfo2[-1]['ctrl_index']=lListItem["ctrl_index"]
else:
if "ctrl_index" in lListItem:
lItemInfo2[-1]['ctrl_index']=lListItem["ctrl_index"]
#Оборачиваем потомка в массив, потому что у родителя по структуре интерфейса может быть больше одного наследников
lItemInfo2[-1]['SpecificationChild']=[]
lItemInfo2=lItemInfo2[-1]['SpecificationChild']
#Переход на родительский объект
#lElement = lElement.parent()
lListIterator=lListIterator+1
#Добавить информацию о Backend в первый объект
lItemInfo[0]["backend"]=lElement.backend.name
#Оборачиваем потомка в массив, потому что у родителя по структуре интерфейса может быть больше одного наследников
lItemInfo2[-1]['SpecificationChild']=[]
lItemInfo2=lItemInfo2[-1]['SpecificationChild']
#Переход на родительский объект
#lElement = lElement.parent()
lListIterator=lListIterator+1
#Добавить информацию о Backend в первый объект
lItemInfo[0]["backend"]=lElement.backend.name
else:
# Run function from other process with help of PIPE
lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_SearchChildByMouse_UIOTree",
"ArgumentList": [inUIOSelector],
"ArgumentDict": {}}
# Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
ProcessCommunicator.ProcessChildSendObject(lSafeOtherProcess, lPIPEResuestDict)
# Get answer from child process
lPIPEResponseDict = ProcessCommunicator.ProcessChildReadWaitObject(lSafeOtherProcess)
if lPIPEResponseDict["ErrorFlag"]:
raise Exception(
f"Exception was occured in child process (message): {lPIPEResponseDict['ErrorMessage']}, (traceback): {lPIPEResponseDict['ErrorTraceback']}")
else:
lItemInfo = lPIPEResponseDict["Result"]
#Вернуть результат
return lItemInfo
####################################################################################################
@ -600,41 +677,36 @@ def UIO_GetCtrlIndex_Int(inElement):
return lResult
####################################################################################################
#Получить список информационных объектов, который удовлетворяет условиям
# Get the UIO Info list for the selected criteria
#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!!
#inSpecificationList - UIOSelector
#old name - PywinautoExtElementsGetInfo
def UIOSelector_Get_UIOInfoList (inSpecificationList,inElement=None):
#Получить родительский объект если на вход ничего не поступило
lResultList=UIOSelector_Get_UIOList(inSpecificationList,inElement)
lIterator = 0
for lItem in lResultList:
lResultList[lIterator]=UIOEI_Convert_UIOInfo(lResultList[lIterator].element_info)
lIterator = lIterator + 1
def UIOSelector_Get_UIOInfoList (inUIOSelector, inElement=None):
#Check the bitness
lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector)
if lSafeOtherProcess is None:
#Получить родительский объект если на вход ничего не поступило
lResultList=UIOSelector_Get_UIOList(inUIOSelector, inElement)
lIterator = 0
for lItem in lResultList:
lResultList[lIterator]=UIOEI_Convert_UIOInfo(lResultList[lIterator].element_info)
lIterator = lIterator + 1
else:
# Run function from other process with help of PIPE
lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_Get_UIOInfoList",
"ArgumentList": [inUIOSelector, inElement],
"ArgumentDict": {}}
# Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
ProcessCommunicator.ProcessChildSendObject(lSafeOtherProcess, lPIPEResuestDict)
# Get answer from child process
lPIPEResponseDict = ProcessCommunicator.ProcessChildReadWaitObject(lSafeOtherProcess)
if lPIPEResponseDict["ErrorFlag"]:
raise Exception(
f"Exception was occured in child process (message): {lPIPEResponseDict['ErrorMessage']}, (traceback): {lPIPEResponseDict['ErrorTraceback']}")
else:
lResultList = lPIPEResponseDict["Result"]
return lResultList
####################################################################################################
#Check is the UIO/UIO's by the UIOSelector exist
#inSpecificationList - UIOSelector
#old name - PywinautoExtElementExist
def UIOSelector_IsExist_Bool (inSpecificationList):
return len(UIOSelector_Get_UIOList(inSpecificationList))>0
####################################################################################################
#Wait for the UIO by the UIOSelector appear
#inSpecificationList - UIOSelector
#result - { }
#old name - PywinautoExtElementWaitAppear
#############
#Внимание! Старая функция (на замену ей пришла UIOSelectorSecs_WaitAppear_Bool)
#############
def UIOSelector_WaitAppear_Dict(inSpecificationList,inTimeout=60):
lTimeoutSeconds = 0
while (not UIOSelector_IsExist_Bool(inSpecificationList) and inTimeout>lTimeoutSeconds):
lTimeoutSeconds = lTimeoutSeconds + 0.5
#Заснуть на полсекунды
time.sleep(0.5)
return UIOSelector_IsExist_Bool(inSpecificationList)
####################################################################################################
#Try to restore (maximize) window, if it's was minimized
#(особенность uia backend - он не может прицепиться к окну, если оно свернуто)
@ -655,72 +727,124 @@ def UIOSelector_TryRestore_Dict(inSpecificationList):
return lResult
####################################################################################################
#Get the list of the UI object activities
#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!!
#inControlSpecificationArray - UIOSelector
#old name - ElementActionGetList
def UIOSelector_Get_UIOActivityList (inControlSpecificationArray):
#Получить объект
lObject=UIOSelector_Get_UIO(inControlSpecificationArray)
lActionList=dir(lObject)
lResult=dir(lObject)
#Выполнить чистку списка от неактуальных методов
for lActionItem in lActionList:
#Удалить те, которые начинаются на _
if lActionItem[0]=='_':
lResult.remove(lActionItem)
#Удалить те, которые начинаются с символа верхнего регистра
if lActionItem[0].isupper():
lResult.remove(lActionItem)
def UIOSelector_Get_UIOActivityList (inUIOSelector):
#Check the bitness
lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector)
if lSafeOtherProcess is None:
#Получить объект
lObject=UIOSelector_Get_UIO(inUIOSelector)
lActionList=dir(lObject)
lResult=dir(lObject)
#Выполнить чистку списка от неактуальных методов
for lActionItem in lActionList:
#Удалить те, которые начинаются на _
if lActionItem[0]=='_':
lResult.remove(lActionItem)
#Удалить те, которые начинаются с символа верхнего регистра
if lActionItem[0].isupper():
lResult.remove(lActionItem)
else:
# Run function from other process with help of PIPE
lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_Get_UIOActivityList",
"ArgumentList": [inUIOSelector],
"ArgumentDict": {}}
# Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
ProcessCommunicator.ProcessChildSendObject(lSafeOtherProcess, lPIPEResuestDict)
# Get answer from child process
lPIPEResponseDict = ProcessCommunicator.ProcessChildReadWaitObject(lSafeOtherProcess)
if lPIPEResponseDict["ErrorFlag"]:
raise Exception(
f"Exception was occured in child process (message): {lPIPEResponseDict['ErrorMessage']}, (traceback): {lPIPEResponseDict['ErrorTraceback']}")
else:
lResult = lPIPEResponseDict["Result"]
return lResult
####################################################################################################
#Run the activity in UIO (UI Object)
#inControlSpecificationArray - UIOSelector
#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!!
#inUIOSelector
#inActionName - UIOActivity (name) from Pywinauto
#old name - ElementRunAction
def UIOSelectorUIOActivity_Run_Dict(inControlSpecificationArray,inActionName,inArgumentList=[],inkwArgumentObject={}):
def UIOSelectorUIOActivity_Run_Dict(inUIOSelector, inActionName, inArgumentList=[], inkwArgumentObject={}):
lResult={}
#Определить объект
lObject=UIOSelector_Get_UIO(inControlSpecificationArray)
#Получить метод для вызова
lFunction = getattr(lObject, inActionName)
#Выполнить действие
#Обернуто в безопасную обработку, тк для некоторых объектов метод не работает и может выдавать ошибку типа: NotImplementedError: This method not work properly for WinForms DataGrid, use cells()
try:
return lFunction(*inArgumentList,**inkwArgumentObject)
except Exception as e:
#Если ошибка возникла на action get_properties
if inActionName=="get_properties":
lResult={}
#Ручное формирование
lResult["class_name"]=lObject.class_name()
lResult["friendly_class_name"]=lObject.friendly_class_name()
lResult["texts"]=lObject.texts()
lResult["control_id"]=lObject.control_id()
lResult["control_count"]=lObject.control_count()
lResult["automation_id"]=lObject.automation_id()
return lResult
#Check the bitness
lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector)
#Run activity if SafeOtherProcess is None
if lSafeOtherProcess is None:
#Определить объект
lObject=UIOSelector_Get_UIO(inUIOSelector)
#Получить метод для вызова
lFunction = getattr(lObject, inActionName)
#Выполнить действие
#Обернуто в безопасную обработку, тк для некоторых объектов метод не работает и может выдавать ошибку типа: NotImplementedError: This method not work properly for WinForms DataGrid, use cells()
try:
return lFunction(*inArgumentList,**inkwArgumentObject)
except Exception as e:
#Если ошибка возникла на action get_properties
if inActionName=="get_properties":
lResult={}
#Ручное формирование
lResult["class_name"]=lObject.class_name()
lResult["friendly_class_name"]=lObject.friendly_class_name()
lResult["texts"]=lObject.texts()
lResult["control_id"]=lObject.control_id()
lResult["control_count"]=lObject.control_count()
lResult["automation_id"]=lObject.automation_id()
return lResult
else:
raise e
else:
#Run function from other process with help of PIPE
lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelectorUIOActivity_Run_Dict",
"ArgumentList": [inUIOSelector, inActionName, inArgumentList, inkwArgumentObject],
"ArgumentDict": {}}
# Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
ProcessCommunicator.ProcessChildSendObject(lSafeOtherProcess, lPIPEResuestDict)
# Get answer from child process
lPIPEResponseDict = ProcessCommunicator.ProcessChildReadWaitObject(lSafeOtherProcess)
if lPIPEResponseDict["ErrorFlag"]:
raise Exception(f"Exception was occured in child process (message): {lPIPEResponseDict['ErrorMessage']}, (traceback): {lPIPEResponseDict['ErrorTraceback']}")
else:
raise e
lResult = lPIPEResponseDict["Result"]
return lResult
####################################################################################################
#Get the UIO dict of the attributes
#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!!
#old name - ElementGetInfo
def UIOSelector_Get_UIOInfo(inControlSpecificationArray):
#Подготовка входного массива
inControlSpecificationArray=UIOSelector_SearchUIONormalize_UIOSelector(inControlSpecificationArray)
#Выполнить идентификацию объектов, если передан массив
lResultList=[];
if len(inControlSpecificationArray) > 0:
#Получить объект
lTempObject=UIOSelector_Get_UIO(inControlSpecificationArray)
#Получить инфо объект
lTempObjectInfo = lTempObject.element_info
#Добавить информацию об обнаруженом объекте
lResultList.append(UIOEI_Convert_UIOInfo(lTempObjectInfo));
def UIOSelector_Get_UIOInfo(inUIOSelector):
#Check the bitness
lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector)
if lSafeOtherProcess is None:
#Подготовка входного массива
inUIOSelector=UIOSelector_SearchUIONormalize_UIOSelector(inUIOSelector)
#Выполнить идентификацию объектов, если передан массив
lResultList=[];
if len(inUIOSelector) > 0:
#Получить объект
lTempObject=UIOSelector_Get_UIO(inUIOSelector)
#Получить инфо объект
lTempObjectInfo = lTempObject.element_info
#Добавить информацию об обнаруженом объекте
lResultList.append(UIOEI_Convert_UIOInfo(lTempObjectInfo))
else:
# Run function from other process with help of PIPE
lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_Get_UIOInfo",
"ArgumentList": [inUIOSelector],
"ArgumentDict": {}}
# Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
ProcessCommunicator.ProcessChildSendObject(lSafeOtherProcess, lPIPEResuestDict)
# Get answer from child process
lPIPEResponseDict = ProcessCommunicator.ProcessChildReadWaitObject(lSafeOtherProcess)
if lPIPEResponseDict["ErrorFlag"]:
raise Exception(
f"Exception was occured in child process (message): {lPIPEResponseDict['ErrorMessage']}, (traceback): {lPIPEResponseDict['ErrorTraceback']}")
else:
lResultList = lPIPEResponseDict["Result"]
return lResultList
####################################################################################################
#Search child UIO by the: Parent UIO, X, Y
#inHierarchyList: [{"index":<>,"element":<>}] - technical argument for internal purpose
@ -812,35 +936,56 @@ def UIOXY_SearchChild_ListDict(inRootElement,inX,inY,inHierarchyList=[]):
###################################################################################################
#Get list of child UIO's by Parent UIOSelector
#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!!
#inControlSpecificationArray- UIOSelector
#old name - ElementGetChildElementList
def UIOSelector_GetChildList_UIOList(inControlSpecificationArray=[],inBackend=mDefaultPywinautoBackend):
#Подготовка входного массива
inControlSpecificationArray=UIOSelector_SearchUIONormalize_UIOSelector(inControlSpecificationArray)
#Выполнить идентификацию объектов, если передан массив
lResultList=[];
#ctypes.windll.user32.MessageBoxW(0, str(inControlSpecificationArray), "Your title", 1)
if len(inControlSpecificationArray) > 0:
#Получить объект
lTempObject = UIOSelector_Get_UIO(inControlSpecificationArray)
#Получить список дочерних объектов
lTempChildList = lTempObject.children()
lIterator=0
#Подготовить результирующий объект
for lChild in lTempChildList:
lTempObjectInfo=lChild.element_info
#Добавить информацию об обнаруженом объекте
lObjectInfoItem=UIOEI_Convert_UIOInfo(lTempObjectInfo)
#Итератор внутри объекта (для точной идентификации)
lObjectInfoItem['ctrl_index']=lIterator;
lResultList.append(lObjectInfoItem);
#Инкремент счетчика
lIterator=lIterator+1
def UIOSelector_GetChildList_UIOList(inUIOSelector=[], inBackend=mDefaultPywinautoBackend):
#mRobotLogger.info(f"File!!!!")
#mRobotLogger.info(f"inSelector:{str(inUIOSelector)}, inBackend:{str(inBackend)}")
#pdb.set_trace()
#Check the bitness
lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector)
if lSafeOtherProcess is None:
#Подготовка входного массива
inUIOSelector=UIOSelector_SearchUIONormalize_UIOSelector(inUIOSelector)
#Выполнить идентификацию объектов, если передан массив
lResultList=[]
#ctypes.windll.user32.MessageBoxW(0, str(inControlSpecificationArray), "Your title", 1)
if len(inUIOSelector) > 0:
#Получить объект
lTempObject = UIOSelector_Get_UIO(inUIOSelector)
#Получить список дочерних объектов
lTempChildList = lTempObject.children()
lIterator=0
#Подготовить результирующий объект
for lChild in lTempChildList:
lTempObjectInfo=lChild.element_info
#Добавить информацию об обнаруженом объекте
lObjectInfoItem=UIOEI_Convert_UIOInfo(lTempObjectInfo)
#Итератор внутри объекта (для точной идентификации)
lObjectInfoItem['ctrl_index']=lIterator
lResultList.append(lObjectInfoItem)
#Инкремент счетчика
lIterator=lIterator+1
else:
lResultList=BackendStr_GetTopLevelList_UIOInfo(inBackend)
#Установка бэк-енда на первый элемент
for lItem in lResultList:
lItem["backend"]=inBackend
else:
lResultList=BackendStr_GetTopLevelList_UIOInfo(inBackend)
#Установка бэк-енда на первый элемент
for lItem in lResultList:
lItem["backend"]=inBackend
# Run function from other process with help of PIPE
lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_GetChildList_UIOList",
"ArgumentList": [inUIOSelector, inBackend],
"ArgumentDict": {}}
# Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
ProcessCommunicator.ProcessChildSendObject(lSafeOtherProcess, lPIPEResuestDict)
# Get answer from child process
lPIPEResponseDict = ProcessCommunicator.ProcessChildReadWaitObject(lSafeOtherProcess)
if lPIPEResponseDict["ErrorFlag"]:
raise Exception(
f"Exception was occured in child process (message): {lPIPEResponseDict['ErrorMessage']}, (traceback): {lPIPEResponseDict['ErrorTraceback']}")
else:
lResultList = lPIPEResponseDict["Result"]
return lResultList
####################################################################################################
@ -1080,17 +1225,53 @@ def BackendStr_GetTopLevelList_UIOInfo(inBackend=mDefaultPywinautoBackend):
###################################################################################################
#Highlight the UI object
#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!!
#old name - ElementDrawOutlineNew
def UIOSelector_Highlight(inSpecificationArray):
UIO_Highlight(UIOSelector_Get_UIO(inSpecificationArray))
return
def UIOSelector_Highlight(inUIOSelector):
#Check the bitness
lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector)
if lSafeOtherProcess is None:
UIO_Highlight(UIOSelector_Get_UIO(inUIOSelector))
else:
# Run function from other process with help of PIPE
lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_Exist_Bool",
"ArgumentList": [inUIOSelector],
"ArgumentDict": {}}
# Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
ProcessCommunicator.ProcessChildSendObject(lSafeOtherProcess, lPIPEResuestDict)
# Get answer from child process
lPIPEResponseDict = ProcessCommunicator.ProcessChildReadWaitObject(lSafeOtherProcess)
if lPIPEResponseDict["ErrorFlag"]:
raise Exception(
f"Exception was occured in child process (message): {lPIPEResponseDict['ErrorMessage']}, (traceback): {lPIPEResponseDict['ErrorTraceback']}")
else:
return lPIPEResponseDict["Result"]
return True
###################################################################################################
#inSpecificationArray - UIOSelector
#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!!
#old name - ElementDrawOutlineNewFocus
def UIOSelector_FocusHighlight(inSpecificationArray):
UIO_FocusHighlight(UIOSelector_Get_UIO(inSpecificationArray))
return
def UIOSelector_FocusHighlight(inUIOSelector):
#Check the bitness
lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector)
if lSafeOtherProcess is None:
UIO_FocusHighlight(UIOSelector_Get_UIO(inUIOSelector))
else:
# Run function from other process with help of PIPE
lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_Exist_Bool",
"ArgumentList": [inUIOSelector],
"ArgumentDict": {}}
# Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
ProcessCommunicator.ProcessChildSendObject(lSafeOtherProcess, lPIPEResuestDict)
# Get answer from child process
lPIPEResponseDict = ProcessCommunicator.ProcessChildReadWaitObject(lSafeOtherProcess)
if lPIPEResponseDict["ErrorFlag"]:
raise Exception(
f"Exception was occured in child process (message): {lPIPEResponseDict['ErrorMessage']}, (traceback): {lPIPEResponseDict['ErrorTraceback']}")
else:
return lPIPEResponseDict["Result"]
return True
###################################################################################################
#old name - draw_outline_new

@ -0,0 +1,85 @@
import pywinauto #Is needed to detect OS bitness
import struct # Need to detect Current process bitness
import subprocess #Need to create subprocess
import os # Is needed to check file/folder path
import shutil #os operations
import pdb
############################################
####Module, which control the Bitness between 32 and 64 python (needed for pywinauto framework to work correctly)
############################################
global mSettingsDict
mSettingsDict = {
"BitnessProcessCurrent": "64", # "64" or "32"
"BitnessOS": "64", # "64" or "32"
"Python32FullPath": None, #Set from user: "..\\Resources\\WPy32-3720\\python-3.7.2\\OpenRPARobotGUIx32.exe"
"Python64FullPath": None, #Set from user
"Python32ProcessName": "OpenRPAUIDesktopX32.exe", #Config set once
"Python64ProcessName": "OpenRPAUIDesktopX64.exe", #Config set once
"Python32Process":None,
"Python64Process":None,
"PythonArgs":["-m","pyOpenRPA.Robot"] #Start other bitness openRPA process with PIPE channel
}
#Init the global configuration
def SettingsInit(inSettingsDict):
if inSettingsDict:
global mSettingsDict
#Update values in settings from input
mSettingsDict.update(inSettingsDict)
#mSettingsDict = inSettingsDict
####################
#Detect OS bitness
####BitnessOS#######
lBitnessOS="32";
if pywinauto.sysinfo.is_x64_OS():
lBitnessOS="64";
inSettingsDict["BitnessOS"]=lBitnessOS
####################
#Detect current process bitness
####BitnessProcessCurrent#######
lBitnessProcessCurrent = str(struct.calcsize("P") * 8)
inSettingsDict["BitnessProcessCurrent"]=lBitnessProcessCurrent
#####################################
#Create the other bitness process if OS is 64 and we have another Python path
##########################################################################
#Check if OS is x64, else no 64 is applicable
if mSettingsDict["BitnessOS"]=="64":
#Check if current bitness is 64
if mSettingsDict["BitnessProcessCurrent"]=="64":
#create x32 if Python 32 path is exists
if mSettingsDict["Python32FullPath"] and mSettingsDict["Python32ProcessName"]:
#Calculate python.exe folder path
lPython32FolderPath= "\\".join(mSettingsDict["Python32FullPath"].split("\\")[:-1])
lPython32NewNamePath = f"{lPython32FolderPath}\\{mSettingsDict['Python32ProcessName']}"
if not os.path.isfile(lPython32NewNamePath):
shutil.copyfile(mSettingsDict["Python32FullPath"],lPython32NewNamePath)
#pdb.set_trace()
mSettingsDict["Python32Process"] = subprocess.Popen([lPython32NewNamePath] + mSettingsDict["PythonArgs"],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
else:
#bitness current process is 32
#return x64 if it is exists
if mSettingsDict["Python64Process"]:
#Calculate python.exe folder path
lPython64FolderPath= "\\".join(mSettingsDict["Python64FullPath"].split("\\")[:-1])
lPython64NewNamePath = f"{lPython64FolderPath}\\{mSettingsDict['Python64ProcessName']}"
if not os.path.isfile(lPython64NewNamePath):
shutil.copyfile(mSettingsDict["Python64FullPath"],lPython64NewNamePath)
mSettingsDict["Python64Process"] = subprocess.Popen([lPython64NewNamePath] + mSettingsDict["PythonArgs"],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
#Return the other module bitnes
def OtherProcessGet():
#Result template
lResult = None
global mSettingsDict
#Check if OS is x64, else no 64 is applicable
if mSettingsDict["BitnessOS"]=="64":
#Check if current bitness is 64
if mSettingsDict["BitnessProcessCurrent"]=="64":
#return x32 if it is exists
if mSettingsDict["Python32Process"]:
lResult = mSettingsDict["Python32Process"]
else:
#bitness current process is 32
#return x64 if it is exists
if mSettingsDict["Python64Process"]:
lResult = mSettingsDict["Python64Process"]
#Exit
return lResult

@ -28,6 +28,7 @@ while True:
lFunction = getattr(UIDesktop,lJSONInput['ActivityName'])
lProcessResponse["Result"]=JSONNormalize.JSONNormalizeDictListStrIntBool(lFunction(*lJSONInput['ArgumentList'],**lJSONInput['ArgumentDict']))
except Exception as e:
lProcessResponse["Result"] = None
#Установить флаг ошибки
lProcessResponse["ErrorFlag"]=True
#Зафиксировать traceback

@ -233,11 +233,12 @@
mGlobal.TreeLoadSubTree =function (inElementId) {
//Подгрузка массива спецификаций
lSpecificationArray = mGlobal.GUIElement[inElementId].GUISelectorFull
//lSpecificationArray[0]["backend"] = $(".openrpa-value-backend")[0].value
///Загрузка данных
$.ajax({
type: "POST",
url: 'GUIAction',
data: '{"ModuleName":"UIDesktop", "ActivityName":"UIOSelector_GetChildList_UIOList","ArgumentList":['+JSON.stringify(lSpecificationArray)+']}',
data: '{"ModuleName":"UIDesktop", "ActivityName":"UIOSelector_GetChildList_UIOList","ArgumentList":['+JSON.stringify(lSpecificationArray)+'], "ArgumentDict":{"inBackend": "'+$(".openrpa-value-backend")[0].value+'"}}',
success:
function(lData,l2,l3)
{
@ -585,8 +586,10 @@
var lDataJSON=JSON.parse(lData)
$(".gui-result").html(JSON.stringify(lDataJSON.Result))
///Показать ошибку, если таковая возникла
if (lDataJSON["ErrorFlag"]) {
mGlobal.ShowModal("GUI Error",lDataJSON.ErrorMessage+" \nTraceback: "+lDataJSON.ErrorTraceback);
for (i = 0; i< lDataJSON.length; i++) {
if (lDataJSON[i]["ErrorFlag"]) {
mGlobal.ShowModal("GUI Error",lDataJSON[i].ErrorMessage+" \nTraceback: "+lDataJSON[i].ErrorTraceback);
}
}
},
dataType: "text"

@ -1,4 +1,7 @@
#Import parent folder to import current / other packages
#########################################################
import sys
lFolderPath = "\\".join(__file__.split("\\")[:-2])
sys.path.append(lFolderPath)
from Studio import Studio
lFolderPath = "\\".join(__file__.split("\\")[:-3])
sys.path.insert(0, lFolderPath)
#########################################################
from pyOpenRPA.Studio import Studio

@ -0,0 +1,50 @@
#Import parent folder to import current / other packages
from pyOpenRPA.Robot import UIDesktop #Lib to access RDP window
import os #os for process run
import time
#Connect to RDP session
"""
{
"Host": "", #Host address
"Port": "", #RDP Port
"Login": "", # Login
"Password": "", #Password
"Screen": {
"Resolution":"FullScreen", #"640x480" or "1680x1050" or "FullScreen". If Resolution not exists set full screen
"FlagUseAllMonitors": False, # True or False
"DepthBit":"" #"32" or "24" or "16" or "15"
}
}
"""
def SessionConnect(inRDPSessionConfiguration):
#Run mstsc
from pywinauto.application import Application
lRDPApplication = Application(backend="uia").start("mstsc.exe")
lProcessId = lRDPApplication.process
#Expand the parameter section
UIDesktop.UIOSelector_Get_UIO(
[
{"process": lProcessId, "backend": "uia"},
{"class_name": "ToolbarWindow32"},
{"title": "Показать параметры ", "control_type": "Button"}]
).click()
#Select flag ask login/pass
UIDesktop.UIOSelector_Get_UIO(
[
{"process": lProcessId, "backend": "win32"},
{"title":"Общие"},
{"title":"Учетные данные"},
{"title":"&Всегда запрашивать учетные данные", "class_name":"Button"}]
).check()
#Set host:port
lHostPort=inRDPSessionConfiguration['Host']
if 'Port' in inRDPSessionConfiguration:
lHostPort=f"{lHostPort}:{inRDPSessionConfiguration['Port']}"
UIDesktop.UIOSelector_Get_UIO(
[
{"process": lProcessId, "backend": "uia"},
{"title": "Компьютер:"},
{"title": "Компьютер:", "control_type": "Edit"}]
).set_text(f"{lHostPort}")
#Set user

@ -0,0 +1,6 @@
#Robot RDPActive settings
def Settings():
mDict = {
}
return mDict

@ -0,0 +1,20 @@
#Import parent folder to import current / other packages
#########################################################
import sys
#lFolderPath = "\\".join(__file__.split("\\")[:-4])
lFolderPath = "/".join(__file__.split("/")[:-4])
sys.path.insert(0, lFolderPath)
#########################################################
from pyOpenRPA.Tools.RobotRDPActive import RDPConnector
mConfiguration={
"Host": "77.77.22.22", #Host address
"Port": "7777", #RDP Port
"Login": "test", # Login
"Password": "test", #Password
"Screen": {
"Resolution":"FullScreen", #"640x480" or "1680x1050" or "FullScreen". If Resolution not exists set full screen
"FlagUseAllMonitors": False, # True or False
"DepthBit":"" #"32" or "24" or "16" or "15"
}
}
RDPConnector.SessionConnect(mConfiguration)

@ -3,7 +3,7 @@ r"""
The OpenRPA package (from UnicodeLabs)
"""
__version__ = 'v1.0.24'
__version__ = 'v1.0.27'
__all__ = []
__author__ = 'Ivan Maslov <ivan.maslov@unicodelabs.ru>'
#from .Core import Robot

@ -233,11 +233,12 @@
mGlobal.TreeLoadSubTree =function (inElementId) {
//Подгрузка массива спецификаций
lSpecificationArray = mGlobal.GUIElement[inElementId].GUISelectorFull
//lSpecificationArray[0]["backend"] = $(".openrpa-value-backend")[0].value
///Загрузка данных
$.ajax({
type: "POST",
url: 'GUIAction',
data: '{"ModuleName":"UIDesktop", "ActivityName":"UIOSelector_GetChildList_UIOList","ArgumentList":['+JSON.stringify(lSpecificationArray)+']}',
data: '{"ModuleName":"UIDesktop", "ActivityName":"UIOSelector_GetChildList_UIOList","ArgumentList":['+JSON.stringify(lSpecificationArray)+'], "ArgumentDict":{"inBackend": "'+$(".openrpa-value-backend")[0].value+'"}}',
success:
function(lData,l2,l3)
{
@ -585,8 +586,10 @@
var lDataJSON=JSON.parse(lData)
$(".gui-result").html(JSON.stringify(lDataJSON.Result))
///Показать ошибку, если таковая возникла
if (lDataJSON["ErrorFlag"]) {
mGlobal.ShowModal("GUI Error",lDataJSON.ErrorMessage+" \nTraceback: "+lDataJSON.ErrorTraceback);
for (i = 0; i< lDataJSON.length; i++) {
if (lDataJSON[i]["ErrorFlag"]) {
mGlobal.ShowModal("GUI Error",lDataJSON[i].ErrorMessage+" \nTraceback: "+lDataJSON[i].ErrorTraceback);
}
}
},
dataType: "text"

@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: pyOpenRPA
Version: 1.0.24
Version: 1.0.27
Summary: First open source RPA platform for business
Home-page: https://gitlab.com/UnicodeLabs/OpenRPA
Author: Ivan Maslov

@ -172,13 +172,13 @@
../../pyOpenRPA/Resources/Web/Semantic-UI-CSS-master/themes/default/assets/fonts/outline-icons.woff2,sha256=TSiDRDsk5CRSf2oKeqKJez33HyOdtANzxP92DkgUeAE,12240
../../pyOpenRPA/Resources/Web/Semantic-UI-CSS-master/themes/default/assets/images/flags.png,sha256=lNXH8WYTAcSm3Ekdct1VmgYgzZF6gm8N8bAju5bqnd0,28123
../../pyOpenRPA/Resources/Web/jQuery/jquery-3.1.1.min.js,sha256=HPMOWdIdSuVgr3FD9ZE-_MgiK8qk_MdQjrgCtfqp6U4,86713
../../pyOpenRPA/Studio/Web/Index.xhtml,sha256=8VWQhvgdybwEEhwnwGtSCgPwauqPF9A-bVndhVaF0qc,44016
../../pyOpenRPA/Studio/Web/Index.xhtml,sha256=74z3eWlmB6Yedbp91xgGtDjymUSlBcduAQ09ZxQ67f8,44241
../../pyOpenRPA/Studio/Web/favicon.ico,sha256=0vdsnwKGh6pgB0FDB5mOKO7RwbxQ9F13Zg16F1pkvXs,5430
pyOpenRPA-1.0.24.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pyOpenRPA-1.0.24.dist-info/METADATA,sha256=ZAcOkPd55_35oltDf_K8EP6bLBhMuZHOhD2Kj1fZXwA,3510
pyOpenRPA-1.0.24.dist-info/RECORD,,
pyOpenRPA-1.0.24.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97
pyOpenRPA-1.0.24.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10
pyOpenRPA-1.0.27.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pyOpenRPA-1.0.27.dist-info/METADATA,sha256=_Y3EhPYpKcvrrAWGgh0dkV-QqKaADkkSh7eOMoz0xcw,3510
pyOpenRPA-1.0.27.dist-info/RECORD,,
pyOpenRPA-1.0.27.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97
pyOpenRPA-1.0.27.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10
pyOpenRPA/Orchestrator/Orchestrator.py,sha256=mlxsd8YMs9X_Een8HfOlCv5d_LVgcx21UAQphHFfD_M,6689
pyOpenRPA/Orchestrator/Processor.py,sha256=GHXwC1B2py4mAtk9oZa-FVSJhx3no9oD2bvkj20uhNA,9051
pyOpenRPA/Orchestrator/Server.py,sha256=GH7P0L-83ONlRdVYu3oQqt2oCgXPXYjrcFb0tY_6SYU,12878
@ -368,14 +368,17 @@ pyOpenRPA/Resources/Web/jQuery/jquery-3.1.1.min.js,sha256=HPMOWdIdSuVgr3FD9ZE-_M
pyOpenRPA/Robot/Clipboard.py,sha256=q76X8L21zJwcwdoJJNPeCEwAV30xS6ylHP1WwvtxoWI,722
pyOpenRPA/Robot/IntegrationOrchestrator.py,sha256=T1g1jJM7_JMTSVP50DTM5WHrMh1w8wovvcBXl1nEokU,2656
pyOpenRPA/Robot/JSONNormalize.py,sha256=aIuVzuZDazhxkCOzoOjfhHVz66mp2FWdfPv5E7KWF5Y,3890
pyOpenRPA/Robot/ProcessBitness.py,sha256=g5RWJ4Yzz6jAFaA3bj1WHoEFphb40BsOwaUob38BvG8,4270
pyOpenRPA/Robot/ProcessCommunicator.py,sha256=Mpo2WoCrEUmY6aCSbQEXkT4qVKtN1N5NcVvG_UZxGVo,8245
pyOpenRPA/Robot/Robot.py,sha256=AVR8jzO-e_ZkW5DrLY_W9ta0eHSul997Y3U6uNVU8WE,9442
pyOpenRPA/Robot/UIDesktop.py,sha256=sUDelnGuL-9Kcw-eS5RzMnR3ynjoDokmJvkHZJdeY3o,66206
pyOpenRPA/Robot/UIDesktop.py,sha256=ehqMQmKLbkwW6iqA9bkw9tvDRni5QriLkG9P3AP_TMs,78377
pyOpenRPA/Robot/Utils/ProcessBitness.py,sha256=WlKL-DklGaoTnchtapOTM_ydxSB4yOeo9lcG3zr2VME,4524
pyOpenRPA/Robot/Utils/__init__.py,sha256=pHlSQGRFKmn5RCTHIf-3a2ooA9T2xNOWridckynP7W4,28
pyOpenRPA/Robot/Utils/__pycache__/ProcessBitness.cpython-37.pyc,,
pyOpenRPA/Robot/Utils/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Robot/ValueVerify.py,sha256=ObskxU4fOMoCGw74_nzYt6-a5jjrAckb3sdBLYyhYxY,777
pyOpenRPA/Robot/Window.py,sha256=UJl-sg4RvvJ35aG9jZOzqGVwE15XK7qPHqoOBD13xFk,431
pyOpenRPA/Robot/__init__.py,sha256=iEW3SGBJf3kYa1zocGH5vEK0woejzJpnQfOmQtIA3P0,324
pyOpenRPA/Robot/__main__.py,sha256=SRwA1L-cRhCaH8MhO3sOdc7dT6Ha2VT6Xzr7CPz4a_g,1922
pyOpenRPA/Robot/__main__.py,sha256=NlwxAG68mwoWNB4YIX15Fc2gWlL1RQ5HN8i1NyjGFdo,1965
pyOpenRPA/Robot/__pycache__/Clipboard.cpython-37.pyc,,
pyOpenRPA/Robot/__pycache__/IntegrationOrchestrator.cpython-37.pyc,,
pyOpenRPA/Robot/__pycache__/JSONNormalize.cpython-37.pyc,,
@ -390,15 +393,25 @@ pyOpenRPA/Studio/JSONNormalize.py,sha256=g0Z8G2wojCgTAdZtyRiCfe0_FHSeAi72Va7R7mk
pyOpenRPA/Studio/ProcessCommunicator.py,sha256=5hXDMa4ONBgeJBoDIfDCAW9MoiRO8cq-DdfqQSAysgk,8080
pyOpenRPA/Studio/Studio.py,sha256=7X46k0l33sgQoG6sxFFJmI5G0KKxgDggvEnzux8aonw,7014
pyOpenRPA/Studio/ValueVerify.py,sha256=ObskxU4fOMoCGw74_nzYt6-a5jjrAckb3sdBLYyhYxY,777
pyOpenRPA/Studio/Web/Index.xhtml,sha256=8VWQhvgdybwEEhwnwGtSCgPwauqPF9A-bVndhVaF0qc,44016
pyOpenRPA/Studio/Web/Index.xhtml,sha256=74z3eWlmB6Yedbp91xgGtDjymUSlBcduAQ09ZxQ67f8,44241
pyOpenRPA/Studio/Web/favicon.ico,sha256=0vdsnwKGh6pgB0FDB5mOKO7RwbxQ9F13Zg16F1pkvXs,5430
pyOpenRPA/Studio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Studio/__main__.py,sha256=RThggw-laywijkYim7zxlYDIPyj0isYLb3WXxQery2s,119
pyOpenRPA/Studio/__main__.py,sha256=_57Rnq9DKbmmlpGFqIwVrWn_LRcU8jjmMTOny4_zlP8,308
pyOpenRPA/Studio/__pycache__/JSONNormalize.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/ProcessCommunicator.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/Studio.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/ValueVerify.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/__main__.cpython-37.pyc,,
pyOpenRPA/__init__.py,sha256=zTI_hbFr447QvQDROWtoVFEPlP7Vy9op1ceyHrmIJmY,175
pyOpenRPA/Tools/RobotRDPActive/RDPConnector.py,sha256=sU79Pd4ehuubZohzUFxkuFOo79Xhicr3sY1HhKaeRhg,1903
pyOpenRPA/Tools/RobotRDPActive/SettingsExample.py,sha256=BjLCZW8fJkoHISJi_ygDG5aBl5jLdOrRolsj3wL7vww,84
pyOpenRPA/Tools/RobotRDPActive/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Tools/RobotRDPActive/__main__.py,sha256=bQZTpQoc50J4UaSRGTSQS2ZAY3iG4eLNaVTc6axXJJ8,834
pyOpenRPA/Tools/RobotRDPActive/__pycache__/RDPConnector.cpython-37.pyc,,
pyOpenRPA/Tools/RobotRDPActive/__pycache__/SettingsExample.cpython-37.pyc,,
pyOpenRPA/Tools/RobotRDPActive/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Tools/RobotRDPActive/__pycache__/__main__.cpython-37.pyc,,
pyOpenRPA/Tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Tools/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/__init__.py,sha256=8FWo2oWf0H8ujn6HQxmH46hGU0R2CTg7nUDUXHnqPoE,175
pyOpenRPA/__pycache__/__init__.cpython-37.pyc,,

@ -1,81 +0,0 @@
import pywinauto #Is needed to detect OS bitness
import struct # Need to detect Current process bitness
import subprocess #Need to create subprocess
import os # Is needed to check file/folder path
############################################
####Module, which control the Bitness between 32 and 64 python (needed for pywinauto framework to work correctly)
############################################
global mSettingsDict
mSettingsDict = {
"BitnessProcessCurrent": "64", # "64" or "32"
"BitnessOS": "64", # "64" or "32"
"Python32FullPath": None, #Set from user: "..\\Resources\\WPy32-3720\\python-3.7.2\\OpenRPARobotGUIx32.exe"
"Python64FullPath": None, #Set from user
"Python32ProcessName": "OpenRPAUIDesktopX32.exe", #Config set once
"Python64ProcessName": "OpenRPAUIDesktopX64.exe", #Config set once
"Python32Process":None,
"Python64Process":None,
"PythonArgs":["-m","pyOpenRPA"] #Start other bitness openRPA process with PIPE channel
}
#Init the global configuration
def SettingsInit(inSettingsDict):
global mSettingsDict
#Update values in settings from input
mSettingsDict.update(inSettingsDict)
#mSettingsDict = inSettingsDict
####################
#Detect OS bitness
####BitnessOS#######
lBitnessOS="32";
if pywinauto.sysinfo.is_x64_OS():
lBitnessOS="64";
inSettingsDict["BitnessOS"]=lBitnessOS
####################
#Detect current process bitness
####BitnessProcessCurrent#######
lBitnessProcessCurrent = str(struct.calcsize("P") * 8)
inSettingsDict["BitnessProcessCurrent"]=lBitnessProcessCurrent
#####################################
#Create the other bitness process if OS is 64 and we have another Python path
##########################################################################
#Check if OS is x64, else no 64 is applicable
if mSettingsDict["BitnessOS"]=="64":
#Check if current bitness is 64
if mSettingsDict["BitnessProcessCurrent"]=="64":
#create x32 if Python 32 path is exists
if mSettingsDict["Python32FullPath"] and mSettingsDict["Python32ProcessName"]:
#Calculate python.exe folder path
lPython32FolderPath= "\\".join(mSettingsDict["Python32FullPath"].split("\\")[:-1])
lPython32NewNamePath = f"{lPython32FolderPath}\\{mSettingsDict["Python32ProcessName"]}"
if not os.path.isfile(lPython32NewNamePath):
shutil.copyfile(mSettingsDict["Python32FullPath"],lPython32NewNamePath)
mSettingsDict["Python32Process"] = subprocess.Popen([lPython32NewNamePath] + mSettingsDict["Python32FullPath"],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
else:
#bitness current process is 32
#return x64 if it is exists
if mSettingsDict["Python64Process"]:
#Calculate python.exe folder path
lPython64FolderPath= "\\".join(mSettingsDict["Python64FullPath"].split("\\")[:-1])
lPython64NewNamePath = f"{lPython64FolderPath}\\{mSettingsDict["Python64ProcessName"]}"
if not os.path.isfile(lPython64NewNamePath):
shutil.copyfile(mSettingsDict["Python32FullPath"],lPython64NewNamePath)
mSettingsDict["Python64Process"] = subprocess.Popen([lPython64NewNamePath] + mSettingsDict["Python64FullPath"],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
#Return the other module bitnes
def OtherBitnessGet():
#Result template
lResult = None
global mSettingsDict
#Check if OS is x64, else no 64 is applicable
if mSettingsDict["BitnessOS"]=="64":
#Check if current bitness is 64
if mSettingsDict["BitnessProcessCurrent"]=="64":
#return x32 if it is exists
if mSettingsDict["Python32Process"]:
lResult = mSettingsDict["Python32Process"]
else:
#bitness current process is 32
#return x64 if it is exists
if mSettingsDict["Python64Process"]:
lResult = mSettingsDict["Python64Process"]
#Exit
return lResult

@ -14,11 +14,13 @@ import time
import traceback
from . import ProcessCommunicator
from . import JSONNormalize
from . import Utils #For ProcessBitness
from threading import Timer
import datetime
import logging
import re
import copy
#Создать файл логирования
# add filemode="w" to overwrite
if not os.path.exists("Reports"):
@ -34,7 +36,16 @@ mRobotLoggerFormatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)
mRobotLoggerFH.setFormatter(mRobotLoggerFormatter)
# add handler to logger object
mRobotLogger.addHandler(mRobotLoggerFH)
############################################
#When import UIDesktop init the other bitness python
#For this type UIDesktop.Utils.ProcessBitness.SettingsInit(inSettingsDict)
#inSettingsDict = {
# "Python32FullPath": None, #Set from user: "..\\Resources\\WPy32-3720\\python-3.7.2\\OpenRPARobotGUIx32.exe"
# "Python64FullPath": None, #Set from user
# "Python32ProcessName": "OpenRPAUIDesktopX32.exe", #Config set once
# "Python64ProcessName": "OpenRPAUIDesktopX64.exe" #Config set once
#}
############################################
#logging.basicConfig(filename="Reports\ReportRobotGUIRun_"+datetime.datetime.now().strftime("%Y_%m_%d")+".log", level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
@ -258,14 +269,32 @@ def UIOSelector_Get_UIO (inSpecificationList,inElement=None,inFlagRaiseException
return lResult
#################################################################################################
#Check if UIO exist (Identified by the UIOSelector)
#inSpecificationList - UIOSelector
#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!!
#UIOSelector
#old name - -
def UIOSelector_Exist_Bool (inSpecificationList):
def UIOSelector_Exist_Bool (inUIOSelector):
lResult=False
#Получить родительский объект если на вход ничего не поступило
lResultList=UIOSelector_Get_UIOList(inSpecificationList,None,False)
if len(lResultList)>0:
lResult=True
#Check the bitness
lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector)
if lSafeOtherProcess is None:
#Получить родительский объект если на вход ничего не поступило
lResultList=UIOSelector_Get_UIOList(inUIOSelector, None, False)
if len(lResultList)>0:
lResult=True
else:
# Run function from other process with help of PIPE
lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_Exist_Bool",
"ArgumentList": [inUIOSelector],
"ArgumentDict": {}}
# Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
ProcessCommunicator.ProcessChildSendObject(lSafeOtherProcess, lPIPEResuestDict)
# Get answer from child process
lPIPEResponseDict = ProcessCommunicator.ProcessChildReadWaitObject(lSafeOtherProcess)
if lPIPEResponseDict["ErrorFlag"]:
raise Exception(
f"Exception was occured in child process (message): {lPIPEResponseDict['ErrorMessage']}, (traceback): {lPIPEResponseDict['ErrorTraceback']}")
else:
lResult = lPIPEResponseDict["Result"]
return lResult
#################################################################################################
#Wait for UIO is appear (at least one of them or all at the same time)
@ -385,6 +414,21 @@ def UIOSelector_Get_BitnessInt (inSpecificationList):
lResult=32
return lResult
#################################################################################################
#Get process bitness ("32" or "64")
#inSpecificationList - UIOSelector
#old name - None
#return None (if Process not found), int 32, or int 64
def UIOSelector_Get_BitnessStr (inSpecificationList):
lResult=None
#Получить объект Application (Для проверки разрядности)
lRootElement=PWASpecification_Get_PWAApplication(inSpecificationList)
if lRootElement is not None:
if lRootElement.is64bit():
lResult="64"
else:
lResult="32"
return lResult
#################################################################################################
#Get OS bitness (32 or 64)
#old name - None
#return int 32, or int 64
@ -393,6 +437,20 @@ def Get_OSBitnessInt ():
if pywinauto.sysinfo.is_x64_OS():
lResult=64;
return lResult;
#################################################################################################
#Safe get other process or None if destination app is the other/same bitness
#inUIOSelector - selector of the destination
#return None or process (of the other bitness)
def UIOSelector_SafeOtherGet_Process(inUIOSelector):
#Default value
lResult = None
#Go check bitness if selector exists
if inUIOSelector:
#Get selector bitness
lUIOSelectorAppBitness = UIOSelector_Get_BitnessStr(inUIOSelector)
if lUIOSelectorAppBitness and Utils.ProcessBitness.mSettingsDict["BitnessProcessCurrent"] != lUIOSelectorAppBitness:
lResult = Utils.ProcessBitness.OtherProcessGet()
return lResult
##################################################################################################
#inControlSpecificationArray - List of dict, dict in pywinauto.find_windows notation
#Backend selection - attribute "backend" ("win32" || "uia") in 1-st list element
@ -450,6 +508,7 @@ def PWASpecification_Get_UIO(inControlSpecificationArray):
#return process application object
#old name - None
def PWASpecification_Get_PWAApplication(inControlSpecificationArray):
inControlSpecificationArray=copy.deepcopy(inControlSpecificationArray)
#Определение backend
lBackend=mDefaultPywinautoBackend
if "backend" in inControlSpecificationArray[0]:
@ -523,48 +582,66 @@ def UIOSelector_SearchChildByMouse_UIO(inElementSpecification):
####################################################################################################
#inElementSpecification - UIOSelector
#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!!
#old name - AutomationSearchMouseElementHierarchy
def UIOSelector_SearchChildByMouse_UIOTree(inElementSpecification):
def UIOSelector_SearchChildByMouse_UIOTree(inUIOSelector):
lItemInfo = []
#Запустить функцию поиска элемента по мыши
lElementList = UIOSelector_SearchChildByMouse_UIO(inElementSpecification)
lElement = lElementList[-1]['element']
#Detect backend of the elements
lFlagIsBackendWin32 = True
#Если объект имеется (не None), то выполнить построение иерархии
if lElement is not None:
if lElement.backend.name == 'uia':
lFlagIsBackendWin32 = False
#Циклическое создание дерева
#while lElement is not None:
lListIterator=0
lItemInfo2=lItemInfo
for lListItem in lElementList:
lElement = lListItem["element"]
#Продолжать построение иерархии во всех случаях кроме бэк uia & parent() is None
#if not lFlagIsBackendWin32 and lElement.parent() is None:
# lElement = None
#else:
#Получить информацию про объект
lItemInfo2.append(UIOEI_Convert_UIOInfo(lElement.element_info))
#Дообогатить информацией об индексе ребенка в родительском объекте
if "index" in lListItem:
if lListItem["index"] is not None:
lItemInfo2[-1]['ctrl_index']=lListItem["index"]
#Check the bitness
lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector)
if lSafeOtherProcess is None:
#Запустить функцию поиска элемента по мыши
lElementList = UIOSelector_SearchChildByMouse_UIO(inUIOSelector)
lElement = lElementList[-1]['element']
#Detect backend of the elements
lFlagIsBackendWin32 = True
#Если объект имеется (не None), то выполнить построение иерархии
if lElement is not None:
if lElement.backend.name == 'uia':
lFlagIsBackendWin32 = False
#Циклическое создание дерева
#while lElement is not None:
lListIterator=0
lItemInfo2=lItemInfo
for lListItem in lElementList:
lElement = lListItem["element"]
#Продолжать построение иерархии во всех случаях кроме бэк uia & parent() is None
#if not lFlagIsBackendWin32 and lElement.parent() is None:
# lElement = None
#else:
#Получить информацию про объект
lItemInfo2.append(UIOEI_Convert_UIOInfo(lElement.element_info))
#Дообогатить информацией об индексе ребенка в родительском объекте
if "index" in lListItem:
if lListItem["index"] is not None:
lItemInfo2[-1]['ctrl_index']=lListItem["index"]
else:
if "ctrl_index" in lListItem:
lItemInfo2[-1]['ctrl_index']=lListItem["ctrl_index"]
else:
if "ctrl_index" in lListItem:
lItemInfo2[-1]['ctrl_index']=lListItem["ctrl_index"]
else:
if "ctrl_index" in lListItem:
lItemInfo2[-1]['ctrl_index']=lListItem["ctrl_index"]
#Оборачиваем потомка в массив, потому что у родителя по структуре интерфейса может быть больше одного наследников
lItemInfo2[-1]['SpecificationChild']=[]
lItemInfo2=lItemInfo2[-1]['SpecificationChild']
#Переход на родительский объект
#lElement = lElement.parent()
lListIterator=lListIterator+1
#Добавить информацию о Backend в первый объект
lItemInfo[0]["backend"]=lElement.backend.name
#Оборачиваем потомка в массив, потому что у родителя по структуре интерфейса может быть больше одного наследников
lItemInfo2[-1]['SpecificationChild']=[]
lItemInfo2=lItemInfo2[-1]['SpecificationChild']
#Переход на родительский объект
#lElement = lElement.parent()
lListIterator=lListIterator+1
#Добавить информацию о Backend в первый объект
lItemInfo[0]["backend"]=lElement.backend.name
else:
# Run function from other process with help of PIPE
lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_SearchChildByMouse_UIOTree",
"ArgumentList": [inUIOSelector],
"ArgumentDict": {}}
# Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
ProcessCommunicator.ProcessChildSendObject(lSafeOtherProcess, lPIPEResuestDict)
# Get answer from child process
lPIPEResponseDict = ProcessCommunicator.ProcessChildReadWaitObject(lSafeOtherProcess)
if lPIPEResponseDict["ErrorFlag"]:
raise Exception(
f"Exception was occured in child process (message): {lPIPEResponseDict['ErrorMessage']}, (traceback): {lPIPEResponseDict['ErrorTraceback']}")
else:
lItemInfo = lPIPEResponseDict["Result"]
#Вернуть результат
return lItemInfo
####################################################################################################
@ -600,41 +677,36 @@ def UIO_GetCtrlIndex_Int(inElement):
return lResult
####################################################################################################
#Получить список информационных объектов, который удовлетворяет условиям
# Get the UIO Info list for the selected criteria
#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!!
#inSpecificationList - UIOSelector
#old name - PywinautoExtElementsGetInfo
def UIOSelector_Get_UIOInfoList (inSpecificationList,inElement=None):
#Получить родительский объект если на вход ничего не поступило
lResultList=UIOSelector_Get_UIOList(inSpecificationList,inElement)
lIterator = 0
for lItem in lResultList:
lResultList[lIterator]=UIOEI_Convert_UIOInfo(lResultList[lIterator].element_info)
lIterator = lIterator + 1
def UIOSelector_Get_UIOInfoList (inUIOSelector, inElement=None):
#Check the bitness
lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector)
if lSafeOtherProcess is None:
#Получить родительский объект если на вход ничего не поступило
lResultList=UIOSelector_Get_UIOList(inUIOSelector, inElement)
lIterator = 0
for lItem in lResultList:
lResultList[lIterator]=UIOEI_Convert_UIOInfo(lResultList[lIterator].element_info)
lIterator = lIterator + 1
else:
# Run function from other process with help of PIPE
lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_Get_UIOInfoList",
"ArgumentList": [inUIOSelector, inElement],
"ArgumentDict": {}}
# Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
ProcessCommunicator.ProcessChildSendObject(lSafeOtherProcess, lPIPEResuestDict)
# Get answer from child process
lPIPEResponseDict = ProcessCommunicator.ProcessChildReadWaitObject(lSafeOtherProcess)
if lPIPEResponseDict["ErrorFlag"]:
raise Exception(
f"Exception was occured in child process (message): {lPIPEResponseDict['ErrorMessage']}, (traceback): {lPIPEResponseDict['ErrorTraceback']}")
else:
lResultList = lPIPEResponseDict["Result"]
return lResultList
####################################################################################################
#Check is the UIO/UIO's by the UIOSelector exist
#inSpecificationList - UIOSelector
#old name - PywinautoExtElementExist
def UIOSelector_IsExist_Bool (inSpecificationList):
return len(UIOSelector_Get_UIOList(inSpecificationList))>0
####################################################################################################
#Wait for the UIO by the UIOSelector appear
#inSpecificationList - UIOSelector
#result - { }
#old name - PywinautoExtElementWaitAppear
#############
#Внимание! Старая функция (на замену ей пришла UIOSelectorSecs_WaitAppear_Bool)
#############
def UIOSelector_WaitAppear_Dict(inSpecificationList,inTimeout=60):
lTimeoutSeconds = 0
while (not UIOSelector_IsExist_Bool(inSpecificationList) and inTimeout>lTimeoutSeconds):
lTimeoutSeconds = lTimeoutSeconds + 0.5
#Заснуть на полсекунды
time.sleep(0.5)
return UIOSelector_IsExist_Bool(inSpecificationList)
####################################################################################################
#Try to restore (maximize) window, if it's was minimized
#(особенность uia backend - он не может прицепиться к окну, если оно свернуто)
@ -655,72 +727,124 @@ def UIOSelector_TryRestore_Dict(inSpecificationList):
return lResult
####################################################################################################
#Get the list of the UI object activities
#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!!
#inControlSpecificationArray - UIOSelector
#old name - ElementActionGetList
def UIOSelector_Get_UIOActivityList (inControlSpecificationArray):
#Получить объект
lObject=UIOSelector_Get_UIO(inControlSpecificationArray)
lActionList=dir(lObject)
lResult=dir(lObject)
#Выполнить чистку списка от неактуальных методов
for lActionItem in lActionList:
#Удалить те, которые начинаются на _
if lActionItem[0]=='_':
lResult.remove(lActionItem)
#Удалить те, которые начинаются с символа верхнего регистра
if lActionItem[0].isupper():
lResult.remove(lActionItem)
def UIOSelector_Get_UIOActivityList (inUIOSelector):
#Check the bitness
lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector)
if lSafeOtherProcess is None:
#Получить объект
lObject=UIOSelector_Get_UIO(inUIOSelector)
lActionList=dir(lObject)
lResult=dir(lObject)
#Выполнить чистку списка от неактуальных методов
for lActionItem in lActionList:
#Удалить те, которые начинаются на _
if lActionItem[0]=='_':
lResult.remove(lActionItem)
#Удалить те, которые начинаются с символа верхнего регистра
if lActionItem[0].isupper():
lResult.remove(lActionItem)
else:
# Run function from other process with help of PIPE
lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_Get_UIOActivityList",
"ArgumentList": [inUIOSelector],
"ArgumentDict": {}}
# Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
ProcessCommunicator.ProcessChildSendObject(lSafeOtherProcess, lPIPEResuestDict)
# Get answer from child process
lPIPEResponseDict = ProcessCommunicator.ProcessChildReadWaitObject(lSafeOtherProcess)
if lPIPEResponseDict["ErrorFlag"]:
raise Exception(
f"Exception was occured in child process (message): {lPIPEResponseDict['ErrorMessage']}, (traceback): {lPIPEResponseDict['ErrorTraceback']}")
else:
lResult = lPIPEResponseDict["Result"]
return lResult
####################################################################################################
#Run the activity in UIO (UI Object)
#inControlSpecificationArray - UIOSelector
#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!!
#inUIOSelector
#inActionName - UIOActivity (name) from Pywinauto
#old name - ElementRunAction
def UIOSelectorUIOActivity_Run_Dict(inControlSpecificationArray,inActionName,inArgumentList=[],inkwArgumentObject={}):
def UIOSelectorUIOActivity_Run_Dict(inUIOSelector, inActionName, inArgumentList=[], inkwArgumentObject={}):
lResult={}
#Определить объект
lObject=UIOSelector_Get_UIO(inControlSpecificationArray)
#Получить метод для вызова
lFunction = getattr(lObject, inActionName)
#Выполнить действие
#Обернуто в безопасную обработку, тк для некоторых объектов метод не работает и может выдавать ошибку типа: NotImplementedError: This method not work properly for WinForms DataGrid, use cells()
try:
return lFunction(*inArgumentList,**inkwArgumentObject)
except Exception as e:
#Если ошибка возникла на action get_properties
if inActionName=="get_properties":
lResult={}
#Ручное формирование
lResult["class_name"]=lObject.class_name()
lResult["friendly_class_name"]=lObject.friendly_class_name()
lResult["texts"]=lObject.texts()
lResult["control_id"]=lObject.control_id()
lResult["control_count"]=lObject.control_count()
lResult["automation_id"]=lObject.automation_id()
return lResult
#Check the bitness
lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector)
#Run activity if SafeOtherProcess is None
if lSafeOtherProcess is None:
#Определить объект
lObject=UIOSelector_Get_UIO(inUIOSelector)
#Получить метод для вызова
lFunction = getattr(lObject, inActionName)
#Выполнить действие
#Обернуто в безопасную обработку, тк для некоторых объектов метод не работает и может выдавать ошибку типа: NotImplementedError: This method not work properly for WinForms DataGrid, use cells()
try:
return lFunction(*inArgumentList,**inkwArgumentObject)
except Exception as e:
#Если ошибка возникла на action get_properties
if inActionName=="get_properties":
lResult={}
#Ручное формирование
lResult["class_name"]=lObject.class_name()
lResult["friendly_class_name"]=lObject.friendly_class_name()
lResult["texts"]=lObject.texts()
lResult["control_id"]=lObject.control_id()
lResult["control_count"]=lObject.control_count()
lResult["automation_id"]=lObject.automation_id()
return lResult
else:
raise e
else:
#Run function from other process with help of PIPE
lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelectorUIOActivity_Run_Dict",
"ArgumentList": [inUIOSelector, inActionName, inArgumentList, inkwArgumentObject],
"ArgumentDict": {}}
# Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
ProcessCommunicator.ProcessChildSendObject(lSafeOtherProcess, lPIPEResuestDict)
# Get answer from child process
lPIPEResponseDict = ProcessCommunicator.ProcessChildReadWaitObject(lSafeOtherProcess)
if lPIPEResponseDict["ErrorFlag"]:
raise Exception(f"Exception was occured in child process (message): {lPIPEResponseDict['ErrorMessage']}, (traceback): {lPIPEResponseDict['ErrorTraceback']}")
else:
raise e
lResult = lPIPEResponseDict["Result"]
return lResult
####################################################################################################
#Get the UIO dict of the attributes
#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!!
#old name - ElementGetInfo
def UIOSelector_Get_UIOInfo(inControlSpecificationArray):
#Подготовка входного массива
inControlSpecificationArray=UIOSelector_SearchUIONormalize_UIOSelector(inControlSpecificationArray)
#Выполнить идентификацию объектов, если передан массив
lResultList=[];
if len(inControlSpecificationArray) > 0:
#Получить объект
lTempObject=UIOSelector_Get_UIO(inControlSpecificationArray)
#Получить инфо объект
lTempObjectInfo = lTempObject.element_info
#Добавить информацию об обнаруженом объекте
lResultList.append(UIOEI_Convert_UIOInfo(lTempObjectInfo));
def UIOSelector_Get_UIOInfo(inUIOSelector):
#Check the bitness
lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector)
if lSafeOtherProcess is None:
#Подготовка входного массива
inUIOSelector=UIOSelector_SearchUIONormalize_UIOSelector(inUIOSelector)
#Выполнить идентификацию объектов, если передан массив
lResultList=[];
if len(inUIOSelector) > 0:
#Получить объект
lTempObject=UIOSelector_Get_UIO(inUIOSelector)
#Получить инфо объект
lTempObjectInfo = lTempObject.element_info
#Добавить информацию об обнаруженом объекте
lResultList.append(UIOEI_Convert_UIOInfo(lTempObjectInfo))
else:
# Run function from other process with help of PIPE
lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_Get_UIOInfo",
"ArgumentList": [inUIOSelector],
"ArgumentDict": {}}
# Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
ProcessCommunicator.ProcessChildSendObject(lSafeOtherProcess, lPIPEResuestDict)
# Get answer from child process
lPIPEResponseDict = ProcessCommunicator.ProcessChildReadWaitObject(lSafeOtherProcess)
if lPIPEResponseDict["ErrorFlag"]:
raise Exception(
f"Exception was occured in child process (message): {lPIPEResponseDict['ErrorMessage']}, (traceback): {lPIPEResponseDict['ErrorTraceback']}")
else:
lResultList = lPIPEResponseDict["Result"]
return lResultList
####################################################################################################
#Search child UIO by the: Parent UIO, X, Y
#inHierarchyList: [{"index":<>,"element":<>}] - technical argument for internal purpose
@ -812,35 +936,56 @@ def UIOXY_SearchChild_ListDict(inRootElement,inX,inY,inHierarchyList=[]):
###################################################################################################
#Get list of child UIO's by Parent UIOSelector
#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!!
#inControlSpecificationArray- UIOSelector
#old name - ElementGetChildElementList
def UIOSelector_GetChildList_UIOList(inControlSpecificationArray=[],inBackend=mDefaultPywinautoBackend):
#Подготовка входного массива
inControlSpecificationArray=UIOSelector_SearchUIONormalize_UIOSelector(inControlSpecificationArray)
#Выполнить идентификацию объектов, если передан массив
lResultList=[];
#ctypes.windll.user32.MessageBoxW(0, str(inControlSpecificationArray), "Your title", 1)
if len(inControlSpecificationArray) > 0:
#Получить объект
lTempObject = UIOSelector_Get_UIO(inControlSpecificationArray)
#Получить список дочерних объектов
lTempChildList = lTempObject.children()
lIterator=0
#Подготовить результирующий объект
for lChild in lTempChildList:
lTempObjectInfo=lChild.element_info
#Добавить информацию об обнаруженом объекте
lObjectInfoItem=UIOEI_Convert_UIOInfo(lTempObjectInfo)
#Итератор внутри объекта (для точной идентификации)
lObjectInfoItem['ctrl_index']=lIterator;
lResultList.append(lObjectInfoItem);
#Инкремент счетчика
lIterator=lIterator+1
def UIOSelector_GetChildList_UIOList(inUIOSelector=[], inBackend=mDefaultPywinautoBackend):
#mRobotLogger.info(f"File!!!!")
#mRobotLogger.info(f"inSelector:{str(inUIOSelector)}, inBackend:{str(inBackend)}")
#pdb.set_trace()
#Check the bitness
lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector)
if lSafeOtherProcess is None:
#Подготовка входного массива
inUIOSelector=UIOSelector_SearchUIONormalize_UIOSelector(inUIOSelector)
#Выполнить идентификацию объектов, если передан массив
lResultList=[]
#ctypes.windll.user32.MessageBoxW(0, str(inControlSpecificationArray), "Your title", 1)
if len(inUIOSelector) > 0:
#Получить объект
lTempObject = UIOSelector_Get_UIO(inUIOSelector)
#Получить список дочерних объектов
lTempChildList = lTempObject.children()
lIterator=0
#Подготовить результирующий объект
for lChild in lTempChildList:
lTempObjectInfo=lChild.element_info
#Добавить информацию об обнаруженом объекте
lObjectInfoItem=UIOEI_Convert_UIOInfo(lTempObjectInfo)
#Итератор внутри объекта (для точной идентификации)
lObjectInfoItem['ctrl_index']=lIterator
lResultList.append(lObjectInfoItem)
#Инкремент счетчика
lIterator=lIterator+1
else:
lResultList=BackendStr_GetTopLevelList_UIOInfo(inBackend)
#Установка бэк-енда на первый элемент
for lItem in lResultList:
lItem["backend"]=inBackend
else:
lResultList=BackendStr_GetTopLevelList_UIOInfo(inBackend)
#Установка бэк-енда на первый элемент
for lItem in lResultList:
lItem["backend"]=inBackend
# Run function from other process with help of PIPE
lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_GetChildList_UIOList",
"ArgumentList": [inUIOSelector, inBackend],
"ArgumentDict": {}}
# Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
ProcessCommunicator.ProcessChildSendObject(lSafeOtherProcess, lPIPEResuestDict)
# Get answer from child process
lPIPEResponseDict = ProcessCommunicator.ProcessChildReadWaitObject(lSafeOtherProcess)
if lPIPEResponseDict["ErrorFlag"]:
raise Exception(
f"Exception was occured in child process (message): {lPIPEResponseDict['ErrorMessage']}, (traceback): {lPIPEResponseDict['ErrorTraceback']}")
else:
lResultList = lPIPEResponseDict["Result"]
return lResultList
####################################################################################################
@ -1080,17 +1225,53 @@ def BackendStr_GetTopLevelList_UIOInfo(inBackend=mDefaultPywinautoBackend):
###################################################################################################
#Highlight the UI object
#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!!
#old name - ElementDrawOutlineNew
def UIOSelector_Highlight(inSpecificationArray):
UIO_Highlight(UIOSelector_Get_UIO(inSpecificationArray))
return
def UIOSelector_Highlight(inUIOSelector):
#Check the bitness
lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector)
if lSafeOtherProcess is None:
UIO_Highlight(UIOSelector_Get_UIO(inUIOSelector))
else:
# Run function from other process with help of PIPE
lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_Exist_Bool",
"ArgumentList": [inUIOSelector],
"ArgumentDict": {}}
# Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
ProcessCommunicator.ProcessChildSendObject(lSafeOtherProcess, lPIPEResuestDict)
# Get answer from child process
lPIPEResponseDict = ProcessCommunicator.ProcessChildReadWaitObject(lSafeOtherProcess)
if lPIPEResponseDict["ErrorFlag"]:
raise Exception(
f"Exception was occured in child process (message): {lPIPEResponseDict['ErrorMessage']}, (traceback): {lPIPEResponseDict['ErrorTraceback']}")
else:
return lPIPEResponseDict["Result"]
return True
###################################################################################################
#inSpecificationArray - UIOSelector
#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!!
#old name - ElementDrawOutlineNewFocus
def UIOSelector_FocusHighlight(inSpecificationArray):
UIO_FocusHighlight(UIOSelector_Get_UIO(inSpecificationArray))
return
def UIOSelector_FocusHighlight(inUIOSelector):
#Check the bitness
lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector)
if lSafeOtherProcess is None:
UIO_FocusHighlight(UIOSelector_Get_UIO(inUIOSelector))
else:
# Run function from other process with help of PIPE
lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_Exist_Bool",
"ArgumentList": [inUIOSelector],
"ArgumentDict": {}}
# Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
ProcessCommunicator.ProcessChildSendObject(lSafeOtherProcess, lPIPEResuestDict)
# Get answer from child process
lPIPEResponseDict = ProcessCommunicator.ProcessChildReadWaitObject(lSafeOtherProcess)
if lPIPEResponseDict["ErrorFlag"]:
raise Exception(
f"Exception was occured in child process (message): {lPIPEResponseDict['ErrorMessage']}, (traceback): {lPIPEResponseDict['ErrorTraceback']}")
else:
return lPIPEResponseDict["Result"]
return True
###################################################################################################
#old name - draw_outline_new

@ -0,0 +1,85 @@
import pywinauto #Is needed to detect OS bitness
import struct # Need to detect Current process bitness
import subprocess #Need to create subprocess
import os # Is needed to check file/folder path
import shutil #os operations
import pdb
############################################
####Module, which control the Bitness between 32 and 64 python (needed for pywinauto framework to work correctly)
############################################
global mSettingsDict
mSettingsDict = {
"BitnessProcessCurrent": "64", # "64" or "32"
"BitnessOS": "64", # "64" or "32"
"Python32FullPath": None, #Set from user: "..\\Resources\\WPy32-3720\\python-3.7.2\\OpenRPARobotGUIx32.exe"
"Python64FullPath": None, #Set from user
"Python32ProcessName": "OpenRPAUIDesktopX32.exe", #Config set once
"Python64ProcessName": "OpenRPAUIDesktopX64.exe", #Config set once
"Python32Process":None,
"Python64Process":None,
"PythonArgs":["-m","pyOpenRPA.Robot"] #Start other bitness openRPA process with PIPE channel
}
#Init the global configuration
def SettingsInit(inSettingsDict):
if inSettingsDict:
global mSettingsDict
#Update values in settings from input
mSettingsDict.update(inSettingsDict)
#mSettingsDict = inSettingsDict
####################
#Detect OS bitness
####BitnessOS#######
lBitnessOS="32";
if pywinauto.sysinfo.is_x64_OS():
lBitnessOS="64";
inSettingsDict["BitnessOS"]=lBitnessOS
####################
#Detect current process bitness
####BitnessProcessCurrent#######
lBitnessProcessCurrent = str(struct.calcsize("P") * 8)
inSettingsDict["BitnessProcessCurrent"]=lBitnessProcessCurrent
#####################################
#Create the other bitness process if OS is 64 and we have another Python path
##########################################################################
#Check if OS is x64, else no 64 is applicable
if mSettingsDict["BitnessOS"]=="64":
#Check if current bitness is 64
if mSettingsDict["BitnessProcessCurrent"]=="64":
#create x32 if Python 32 path is exists
if mSettingsDict["Python32FullPath"] and mSettingsDict["Python32ProcessName"]:
#Calculate python.exe folder path
lPython32FolderPath= "\\".join(mSettingsDict["Python32FullPath"].split("\\")[:-1])
lPython32NewNamePath = f"{lPython32FolderPath}\\{mSettingsDict['Python32ProcessName']}"
if not os.path.isfile(lPython32NewNamePath):
shutil.copyfile(mSettingsDict["Python32FullPath"],lPython32NewNamePath)
#pdb.set_trace()
mSettingsDict["Python32Process"] = subprocess.Popen([lPython32NewNamePath] + mSettingsDict["PythonArgs"],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
else:
#bitness current process is 32
#return x64 if it is exists
if mSettingsDict["Python64Process"]:
#Calculate python.exe folder path
lPython64FolderPath= "\\".join(mSettingsDict["Python64FullPath"].split("\\")[:-1])
lPython64NewNamePath = f"{lPython64FolderPath}\\{mSettingsDict['Python64ProcessName']}"
if not os.path.isfile(lPython64NewNamePath):
shutil.copyfile(mSettingsDict["Python64FullPath"],lPython64NewNamePath)
mSettingsDict["Python64Process"] = subprocess.Popen([lPython64NewNamePath] + mSettingsDict["PythonArgs"],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
#Return the other module bitnes
def OtherProcessGet():
#Result template
lResult = None
global mSettingsDict
#Check if OS is x64, else no 64 is applicable
if mSettingsDict["BitnessOS"]=="64":
#Check if current bitness is 64
if mSettingsDict["BitnessProcessCurrent"]=="64":
#return x32 if it is exists
if mSettingsDict["Python32Process"]:
lResult = mSettingsDict["Python32Process"]
else:
#bitness current process is 32
#return x64 if it is exists
if mSettingsDict["Python64Process"]:
lResult = mSettingsDict["Python64Process"]
#Exit
return lResult

@ -28,6 +28,7 @@ while True:
lFunction = getattr(UIDesktop,lJSONInput['ActivityName'])
lProcessResponse["Result"]=JSONNormalize.JSONNormalizeDictListStrIntBool(lFunction(*lJSONInput['ArgumentList'],**lJSONInput['ArgumentDict']))
except Exception as e:
lProcessResponse["Result"] = None
#Установить флаг ошибки
lProcessResponse["ErrorFlag"]=True
#Зафиксировать traceback

@ -233,11 +233,12 @@
mGlobal.TreeLoadSubTree =function (inElementId) {
//Подгрузка массива спецификаций
lSpecificationArray = mGlobal.GUIElement[inElementId].GUISelectorFull
//lSpecificationArray[0]["backend"] = $(".openrpa-value-backend")[0].value
///Загрузка данных
$.ajax({
type: "POST",
url: 'GUIAction',
data: '{"ModuleName":"UIDesktop", "ActivityName":"UIOSelector_GetChildList_UIOList","ArgumentList":['+JSON.stringify(lSpecificationArray)+']}',
data: '{"ModuleName":"UIDesktop", "ActivityName":"UIOSelector_GetChildList_UIOList","ArgumentList":['+JSON.stringify(lSpecificationArray)+'], "ArgumentDict":{"inBackend": "'+$(".openrpa-value-backend")[0].value+'"}}',
success:
function(lData,l2,l3)
{
@ -585,8 +586,10 @@
var lDataJSON=JSON.parse(lData)
$(".gui-result").html(JSON.stringify(lDataJSON.Result))
///Показать ошибку, если таковая возникла
if (lDataJSON["ErrorFlag"]) {
mGlobal.ShowModal("GUI Error",lDataJSON.ErrorMessage+" \nTraceback: "+lDataJSON.ErrorTraceback);
for (i = 0; i< lDataJSON.length; i++) {
if (lDataJSON[i]["ErrorFlag"]) {
mGlobal.ShowModal("GUI Error",lDataJSON[i].ErrorMessage+" \nTraceback: "+lDataJSON[i].ErrorTraceback);
}
}
},
dataType: "text"

@ -1,4 +1,7 @@
#Import parent folder to import current / other packages
#########################################################
import sys
lFolderPath = "\\".join(__file__.split("\\")[:-2])
sys.path.append(lFolderPath)
from Studio import Studio
lFolderPath = "\\".join(__file__.split("\\")[:-3])
sys.path.insert(0, lFolderPath)
#########################################################
from pyOpenRPA.Studio import Studio

@ -0,0 +1,50 @@
#Import parent folder to import current / other packages
from pyOpenRPA.Robot import UIDesktop #Lib to access RDP window
import os #os for process run
import time
#Connect to RDP session
"""
{
"Host": "", #Host address
"Port": "", #RDP Port
"Login": "", # Login
"Password": "", #Password
"Screen": {
"Resolution":"FullScreen", #"640x480" or "1680x1050" or "FullScreen". If Resolution not exists set full screen
"FlagUseAllMonitors": False, # True or False
"DepthBit":"" #"32" or "24" or "16" or "15"
}
}
"""
def SessionConnect(inRDPSessionConfiguration):
#Run mstsc
from pywinauto.application import Application
lRDPApplication = Application(backend="uia").start("mstsc.exe")
lProcessId = lRDPApplication.process
#Expand the parameter section
UIDesktop.UIOSelector_Get_UIO(
[
{"process": lProcessId, "backend": "uia"},
{"class_name": "ToolbarWindow32"},
{"title": "Показать параметры ", "control_type": "Button"}]
).click()
#Select flag ask login/pass
UIDesktop.UIOSelector_Get_UIO(
[
{"process": lProcessId, "backend": "win32"},
{"title":"Общие"},
{"title":"Учетные данные"},
{"title":"&Всегда запрашивать учетные данные", "class_name":"Button"}]
).check()
#Set host:port
lHostPort=inRDPSessionConfiguration['Host']
if 'Port' in inRDPSessionConfiguration:
lHostPort=f"{lHostPort}:{inRDPSessionConfiguration['Port']}"
UIDesktop.UIOSelector_Get_UIO(
[
{"process": lProcessId, "backend": "uia"},
{"title": "Компьютер:"},
{"title": "Компьютер:", "control_type": "Edit"}]
).set_text(f"{lHostPort}")
#Set user

@ -0,0 +1,6 @@
#Robot RDPActive settings
def Settings():
mDict = {
}
return mDict

@ -0,0 +1,20 @@
#Import parent folder to import current / other packages
#########################################################
import sys
#lFolderPath = "\\".join(__file__.split("\\")[:-4])
lFolderPath = "/".join(__file__.split("/")[:-4])
sys.path.insert(0, lFolderPath)
#########################################################
from pyOpenRPA.Tools.RobotRDPActive import RDPConnector
mConfiguration={
"Host": "77.77.22.22", #Host address
"Port": "7777", #RDP Port
"Login": "test", # Login
"Password": "test", #Password
"Screen": {
"Resolution":"FullScreen", #"640x480" or "1680x1050" or "FullScreen". If Resolution not exists set full screen
"FlagUseAllMonitors": False, # True or False
"DepthBit":"" #"32" or "24" or "16" or "15"
}
}
RDPConnector.SessionConnect(mConfiguration)

@ -3,7 +3,7 @@ r"""
The OpenRPA package (from UnicodeLabs)
"""
__version__ = 'v1.0.24'
__version__ = 'v1.0.27'
__all__ = []
__author__ = 'Ivan Maslov <ivan.maslov@unicodelabs.ru>'
#from .Core import Robot

@ -233,11 +233,12 @@
mGlobal.TreeLoadSubTree =function (inElementId) {
//Подгрузка массива спецификаций
lSpecificationArray = mGlobal.GUIElement[inElementId].GUISelectorFull
//lSpecificationArray[0]["backend"] = $(".openrpa-value-backend")[0].value
///Загрузка данных
$.ajax({
type: "POST",
url: 'GUIAction',
data: '{"ModuleName":"UIDesktop", "ActivityName":"UIOSelector_GetChildList_UIOList","ArgumentList":['+JSON.stringify(lSpecificationArray)+']}',
data: '{"ModuleName":"UIDesktop", "ActivityName":"UIOSelector_GetChildList_UIOList","ArgumentList":['+JSON.stringify(lSpecificationArray)+'], "ArgumentDict":{"inBackend": "'+$(".openrpa-value-backend")[0].value+'"}}',
success:
function(lData,l2,l3)
{
@ -585,8 +586,10 @@
var lDataJSON=JSON.parse(lData)
$(".gui-result").html(JSON.stringify(lDataJSON.Result))
///Показать ошибку, если таковая возникла
if (lDataJSON["ErrorFlag"]) {
mGlobal.ShowModal("GUI Error",lDataJSON.ErrorMessage+" \nTraceback: "+lDataJSON.ErrorTraceback);
for (i = 0; i< lDataJSON.length; i++) {
if (lDataJSON[i]["ErrorFlag"]) {
mGlobal.ShowModal("GUI Error",lDataJSON[i].ErrorMessage+" \nTraceback: "+lDataJSON[i].ErrorTraceback);
}
}
},
dataType: "text"

@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: pyOpenRPA
Version: 1.0.24
Version: 1.0.27
Summary: First open source RPA platform for business
Home-page: https://gitlab.com/UnicodeLabs/OpenRPA
Author: Ivan Maslov

@ -189,7 +189,6 @@ pyOpenRPA/Resources/Web/jQuery/jquery-3.1.1.min.js
pyOpenRPA/Robot/Clipboard.py
pyOpenRPA/Robot/IntegrationOrchestrator.py
pyOpenRPA/Robot/JSONNormalize.py
pyOpenRPA/Robot/ProcessBitness.py
pyOpenRPA/Robot/ProcessCommunicator.py
pyOpenRPA/Robot/Robot.py
pyOpenRPA/Robot/UIDesktop.py
@ -197,6 +196,8 @@ pyOpenRPA/Robot/ValueVerify.py
pyOpenRPA/Robot/Window.py
pyOpenRPA/Robot/__init__.py
pyOpenRPA/Robot/__main__.py
pyOpenRPA/Robot/Utils/ProcessBitness.py
pyOpenRPA/Robot/Utils/__init__.py
pyOpenRPA/Studio/JSONNormalize.py
pyOpenRPA/Studio/ProcessCommunicator.py
pyOpenRPA/Studio/Studio.py
@ -204,4 +205,9 @@ pyOpenRPA/Studio/ValueVerify.py
pyOpenRPA/Studio/__init__.py
pyOpenRPA/Studio/__main__.py
pyOpenRPA/Studio/Web/Index.xhtml
pyOpenRPA/Studio/Web/favicon.ico
pyOpenRPA/Studio/Web/favicon.ico
pyOpenRPA/Tools/__init__.py
pyOpenRPA/Tools/RobotRDPActive/RDPConnector.py
pyOpenRPA/Tools/RobotRDPActive/SettingsExample.py
pyOpenRPA/Tools/RobotRDPActive/__init__.py
pyOpenRPA/Tools/RobotRDPActive/__main__.py

@ -3,7 +3,7 @@ r"""
The OpenRPA package (from UnicodeLabs)
"""
__version__ = 'v1.0.24'
__version__ = 'v1.0.27'
__all__ = []
__author__ = 'Ivan Maslov <ivan.maslov@unicodelabs.ru>'
#from .Core import Robot
Loading…
Cancel
Save