From 1c2d3f7b0aeb076e559cabb254608377b463e32b Mon Sep 17 00:00:00 2001 From: Ivan Maslov Date: Sun, 17 Nov 2019 11:33:20 +0300 Subject: [PATCH] v1.0.27 in Portable python x32 and x64 --- .../INSTALLER | 0 .../pyOpenRPA-1.0.27.dist-info}/METADATA | 2 +- .../pyOpenRPA-1.0.27.dist-info}/RECORD | 37 +- .../WHEEL | 0 .../top_level.txt | 0 .../pyOpenRPA/Robot/ProcessBitness.py | 81 --- .../pyOpenRPA/Robot/UIDesktop.py | 495 ++++++++++++------ .../pyOpenRPA/Robot/Utils/ProcessBitness.py | 85 +++ .../pyOpenRPA/Robot/Utils/__init__.py | 1 + .../site-packages/pyOpenRPA/Robot/__main__.py | 1 + .../pyOpenRPA/Studio/Web/Index.xhtml | 9 +- .../pyOpenRPA/Studio/__main__.py | 9 +- .../Tools/RobotRDPActive/RDPConnector.py | 50 ++ .../Tools/RobotRDPActive/SettingsExample.py | 6 + .../Tools/RobotRDPActive/__init__.py | 0 .../Tools/RobotRDPActive/__main__.py | 20 + .../site-packages/pyOpenRPA/Tools/__init__.py | 0 .../Lib/site-packages/pyOpenRPA/__init__.py | 2 +- .../pyOpenRPA/Studio/Web/Index.xhtml | 9 +- .../INSTALLER | 0 .../pyOpenRPA-1.0.27.dist-info}/METADATA | 2 +- .../pyOpenRPA-1.0.27.dist-info}/RECORD | 37 +- .../WHEEL | 0 .../top_level.txt | 0 .../pyOpenRPA/Robot/ProcessBitness.py | 81 --- .../pyOpenRPA/Robot/UIDesktop.py | 495 ++++++++++++------ .../pyOpenRPA/Robot/Utils/ProcessBitness.py | 85 +++ .../pyOpenRPA/Robot/Utils/__init__.py | 1 + .../site-packages/pyOpenRPA/Robot/__main__.py | 1 + .../pyOpenRPA/Studio/Web/Index.xhtml | 9 +- .../pyOpenRPA/Studio/__main__.py | 9 +- .../Tools/RobotRDPActive/RDPConnector.py | 50 ++ .../Tools/RobotRDPActive/SettingsExample.py | 6 + .../Tools/RobotRDPActive/__init__.py | 0 .../Tools/RobotRDPActive/__main__.py | 20 + .../site-packages/pyOpenRPA/Tools/__init__.py | 0 .../Lib/site-packages/pyOpenRPA/__init__.py | 2 +- .../pyOpenRPA/Studio/Web/Index.xhtml | 9 +- Sources/pyOpenRPA.egg-info/PKG-INFO | 2 +- Sources/pyOpenRPA.egg-info/SOURCES.txt | 10 +- Sources/pyOpenRPA/__init__.py | 2 +- 41 files changed, 1102 insertions(+), 526 deletions(-) rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{pyOpenRPA-1.0.24.dist-info => pyOpenRPA-1.0.27.dist-info}/INSTALLER (100%) rename Resources/{WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.24.dist-info => WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.27.dist-info}/METADATA (99%) rename Resources/{WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.24.dist-info => WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.27.dist-info}/RECORD (96%) rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{pyOpenRPA-1.0.24.dist-info => pyOpenRPA-1.0.27.dist-info}/WHEEL (100%) rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{pyOpenRPA-1.0.24.dist-info => pyOpenRPA-1.0.27.dist-info}/top_level.txt (100%) delete mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/ProcessBitness.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/Utils/ProcessBitness.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/Utils/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/RDPConnector.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/SettingsExample.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/__main__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Tools/__init__.py rename Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/{pyOpenRPA-1.0.24.dist-info => pyOpenRPA-1.0.27.dist-info}/INSTALLER (100%) rename Resources/{WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.24.dist-info => WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.27.dist-info}/METADATA (99%) rename Resources/{WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.24.dist-info => WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.27.dist-info}/RECORD (96%) rename Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/{pyOpenRPA-1.0.24.dist-info => pyOpenRPA-1.0.27.dist-info}/WHEEL (100%) rename Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/{pyOpenRPA-1.0.24.dist-info => pyOpenRPA-1.0.27.dist-info}/top_level.txt (100%) delete mode 100644 Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/ProcessBitness.py create mode 100644 Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/Utils/ProcessBitness.py create mode 100644 Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/Utils/__init__.py create mode 100644 Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/RDPConnector.py create mode 100644 Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/SettingsExample.py create mode 100644 Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/__init__.py create mode 100644 Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/__main__.py create mode 100644 Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Tools/__init__.py diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.24.dist-info/INSTALLER b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.27.dist-info/INSTALLER similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.24.dist-info/INSTALLER rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.27.dist-info/INSTALLER diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.24.dist-info/METADATA b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.27.dist-info/METADATA similarity index 99% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.24.dist-info/METADATA rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.27.dist-info/METADATA index 36da9e91..c0435c84 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.24.dist-info/METADATA +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.27.dist-info/METADATA @@ -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 diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.24.dist-info/RECORD b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.27.dist-info/RECORD similarity index 96% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.24.dist-info/RECORD rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.27.dist-info/RECORD index 81c8efc1..1b785355 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.24.dist-info/RECORD +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.27.dist-info/RECORD @@ -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,, diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.24.dist-info/WHEEL b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.27.dist-info/WHEEL similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.24.dist-info/WHEEL rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.27.dist-info/WHEEL diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.24.dist-info/top_level.txt b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.27.dist-info/top_level.txt similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.24.dist-info/top_level.txt rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.27.dist-info/top_level.txt diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/ProcessBitness.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/ProcessBitness.py deleted file mode 100644 index 8c3f7a2c..00000000 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/ProcessBitness.py +++ /dev/null @@ -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 \ No newline at end of file diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/UIDesktop.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/UIDesktop.py index c2a6badf..74e7ae13 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/UIDesktop.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/UIDesktop.py @@ -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 diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/Utils/ProcessBitness.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/Utils/ProcessBitness.py new file mode 100644 index 00000000..6ffd4a99 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/Utils/ProcessBitness.py @@ -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 \ No newline at end of file diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/Utils/__init__.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/Utils/__init__.py new file mode 100644 index 00000000..069ade8c --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/Utils/__init__.py @@ -0,0 +1 @@ +from . import ProcessBitness \ No newline at end of file diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/__main__.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/__main__.py index 286d12e6..6ccc71bd 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/__main__.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/__main__.py @@ -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 diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Studio/Web/Index.xhtml b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Studio/Web/Index.xhtml index fcd68d2d..218df737 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Studio/Web/Index.xhtml +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Studio/Web/Index.xhtml @@ -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" diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Studio/__main__.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Studio/__main__.py index 66bc60f9..155d41d4 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Studio/__main__.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Studio/__main__.py @@ -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 \ No newline at end of file +lFolderPath = "\\".join(__file__.split("\\")[:-3]) +sys.path.insert(0, lFolderPath) +######################################################### +from pyOpenRPA.Studio import Studio \ No newline at end of file diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/RDPConnector.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/RDPConnector.py new file mode 100644 index 00000000..1d751b20 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/RDPConnector.py @@ -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 + diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/SettingsExample.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/SettingsExample.py new file mode 100644 index 00000000..549e7d43 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/SettingsExample.py @@ -0,0 +1,6 @@ +#Robot RDPActive settings +def Settings(): + mDict = { + + } + return mDict \ No newline at end of file diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/__init__.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/__main__.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/__main__.py new file mode 100644 index 00000000..2e5729ef --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/__main__.py @@ -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) \ No newline at end of file diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Tools/__init__.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Tools/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/__init__.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/__init__.py index 4dfd5250..4cb9341d 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/__init__.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/__init__.py @@ -3,7 +3,7 @@ r""" The OpenRPA package (from UnicodeLabs) """ -__version__ = 'v1.0.24' +__version__ = 'v1.0.27' __all__ = [] __author__ = 'Ivan Maslov ' #from .Core import Robot \ No newline at end of file diff --git a/Resources/WPy32-3720/python-3.7.2/pyOpenRPA/Studio/Web/Index.xhtml b/Resources/WPy32-3720/python-3.7.2/pyOpenRPA/Studio/Web/Index.xhtml index fcd68d2d..218df737 100644 --- a/Resources/WPy32-3720/python-3.7.2/pyOpenRPA/Studio/Web/Index.xhtml +++ b/Resources/WPy32-3720/python-3.7.2/pyOpenRPA/Studio/Web/Index.xhtml @@ -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" diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.24.dist-info/INSTALLER b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.27.dist-info/INSTALLER similarity index 100% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.24.dist-info/INSTALLER rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.27.dist-info/INSTALLER diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.24.dist-info/METADATA b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.27.dist-info/METADATA similarity index 99% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.24.dist-info/METADATA rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.27.dist-info/METADATA index 36da9e91..c0435c84 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.24.dist-info/METADATA +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.27.dist-info/METADATA @@ -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 diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.24.dist-info/RECORD b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.27.dist-info/RECORD similarity index 96% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.24.dist-info/RECORD rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.27.dist-info/RECORD index 81c8efc1..1b785355 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.24.dist-info/RECORD +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.27.dist-info/RECORD @@ -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,, diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.24.dist-info/WHEEL b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.27.dist-info/WHEEL similarity index 100% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.24.dist-info/WHEEL rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.27.dist-info/WHEEL diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.24.dist-info/top_level.txt b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.27.dist-info/top_level.txt similarity index 100% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.24.dist-info/top_level.txt rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.27.dist-info/top_level.txt diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/ProcessBitness.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/ProcessBitness.py deleted file mode 100644 index 8c3f7a2c..00000000 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/ProcessBitness.py +++ /dev/null @@ -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 \ No newline at end of file diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/UIDesktop.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/UIDesktop.py index c2a6badf..74e7ae13 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/UIDesktop.py +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/UIDesktop.py @@ -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 diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/Utils/ProcessBitness.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/Utils/ProcessBitness.py new file mode 100644 index 00000000..6ffd4a99 --- /dev/null +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/Utils/ProcessBitness.py @@ -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 \ No newline at end of file diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/Utils/__init__.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/Utils/__init__.py new file mode 100644 index 00000000..069ade8c --- /dev/null +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/Utils/__init__.py @@ -0,0 +1 @@ +from . import ProcessBitness \ No newline at end of file diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/__main__.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/__main__.py index 286d12e6..6ccc71bd 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/__main__.py +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/__main__.py @@ -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 diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Studio/Web/Index.xhtml b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Studio/Web/Index.xhtml index fcd68d2d..218df737 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Studio/Web/Index.xhtml +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Studio/Web/Index.xhtml @@ -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" diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Studio/__main__.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Studio/__main__.py index 66bc60f9..155d41d4 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Studio/__main__.py +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Studio/__main__.py @@ -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 \ No newline at end of file +lFolderPath = "\\".join(__file__.split("\\")[:-3]) +sys.path.insert(0, lFolderPath) +######################################################### +from pyOpenRPA.Studio import Studio \ No newline at end of file diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/RDPConnector.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/RDPConnector.py new file mode 100644 index 00000000..1d751b20 --- /dev/null +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/RDPConnector.py @@ -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 + diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/SettingsExample.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/SettingsExample.py new file mode 100644 index 00000000..549e7d43 --- /dev/null +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/SettingsExample.py @@ -0,0 +1,6 @@ +#Robot RDPActive settings +def Settings(): + mDict = { + + } + return mDict \ No newline at end of file diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/__init__.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/__main__.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/__main__.py new file mode 100644 index 00000000..2e5729ef --- /dev/null +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/__main__.py @@ -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) \ No newline at end of file diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Tools/__init__.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Tools/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/__init__.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/__init__.py index 4dfd5250..4cb9341d 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/__init__.py +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/__init__.py @@ -3,7 +3,7 @@ r""" The OpenRPA package (from UnicodeLabs) """ -__version__ = 'v1.0.24' +__version__ = 'v1.0.27' __all__ = [] __author__ = 'Ivan Maslov ' #from .Core import Robot \ No newline at end of file diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/pyOpenRPA/Studio/Web/Index.xhtml b/Resources/WPy64-3720/python-3.7.2.amd64/pyOpenRPA/Studio/Web/Index.xhtml index fcd68d2d..218df737 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/pyOpenRPA/Studio/Web/Index.xhtml +++ b/Resources/WPy64-3720/python-3.7.2.amd64/pyOpenRPA/Studio/Web/Index.xhtml @@ -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" diff --git a/Sources/pyOpenRPA.egg-info/PKG-INFO b/Sources/pyOpenRPA.egg-info/PKG-INFO index 0af72cdf..584c6cad 100644 --- a/Sources/pyOpenRPA.egg-info/PKG-INFO +++ b/Sources/pyOpenRPA.egg-info/PKG-INFO @@ -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 diff --git a/Sources/pyOpenRPA.egg-info/SOURCES.txt b/Sources/pyOpenRPA.egg-info/SOURCES.txt index 7fc9c0f8..d76ce56d 100644 --- a/Sources/pyOpenRPA.egg-info/SOURCES.txt +++ b/Sources/pyOpenRPA.egg-info/SOURCES.txt @@ -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 \ No newline at end of file +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 \ No newline at end of file diff --git a/Sources/pyOpenRPA/__init__.py b/Sources/pyOpenRPA/__init__.py index 4dfd5250..4cb9341d 100644 --- a/Sources/pyOpenRPA/__init__.py +++ b/Sources/pyOpenRPA/__init__.py @@ -3,7 +3,7 @@ r""" The OpenRPA package (from UnicodeLabs) """ -__version__ = 'v1.0.24' +__version__ = 'v1.0.27' __all__ = [] __author__ = 'Ivan Maslov ' #from .Core import Robot \ No newline at end of file