From b7f88de8bf0813763236d0a860b4e63e1ddaef55 Mon Sep 17 00:00:00 2001 From: Ivan Maslov Date: Mon, 28 Sep 2020 18:07:08 +0300 Subject: [PATCH] # Support multiple processes in 1 RDP session --- .../Orchestrator/RobotRDPActive/Processor.py | 57 ++++++++++++++++--- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/Sources/pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py b/Sources/pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py index 0cd4862b..77e764f3 100644 --- a/Sources/pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py +++ b/Sources/pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py @@ -5,6 +5,7 @@ from . import CMDStr # Create CMD Strings from . import Connector # RDP API from . import ConnectorExceptions # Exceptions import time # sleep function +import psutil # ATTENTION gSettings = None # Gsettings will be initialized after the import module @@ -38,13 +39,17 @@ def RDPSessionConnect(inRDPSessionKeyStr, inHostStr, inPortStr, inLoginStr, inPa return True # Disconnect the RDP session -def RDPSessionDisconnect(inRDPSessionKeyStr): +def RDPSessionDisconnect(inRDPSessionKeyStr, inBreakTriggerProcessWOExeList = []): global gSettings lSessionHex = gSettings["RobotRDPActive"]["RDPList"].get(inRDPSessionKeyStr,{}).get("SessionHex", None) if lSessionHex: - gSettings["RobotRDPActive"]["RDPList"].pop(inRDPSessionKeyStr,None) - Connector.SessionClose(inSessionHexStr=lSessionHex) - Connector.SystemRDPWarningClickOk() # Click all warning messages + lProcessListResult = [] + if len(inBreakTriggerProcessWOExeList) > 0: + lProcessListResult = ProcessListGet(inProcessNameWOExeList=inBreakTriggerProcessWOExeList) # Run the task manager monitor + if len(lProcessListResult["ProcessWOExeList"]) == 0: # Start disconnect if no process exist + gSettings["RobotRDPActive"]["RDPList"].pop(inRDPSessionKeyStr,None) + Connector.SessionClose(inSessionHexStr=lSessionHex) + Connector.SystemRDPWarningClickOk() # Click all warning messages return True # RDP Session reconnect @@ -66,16 +71,20 @@ def RDPSessionMonitorStop(inRDPSessionKeyStr): return lResult # Logoff the RDP session -def RDPSessionLogoff(inRDPSessionKeyStr): +def RDPSessionLogoff(inRDPSessionKeyStr, inBreakTriggerProcessWOExeList = []): global gSettings lResult = True lCMDStr = "shutdown -L" # CMD logoff command # Calculate the session Hex lSessionHex = gSettings["RobotRDPActive"]["RDPList"].get(inRDPSessionKeyStr,{}).get("SessionHex", None) if lSessionHex: - # Run CMD - dont crosscheck because CMD dont return value to the clipboard when logoff - Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="RUN", inLogger=gSettings["Logger"], inRDPConfigurationItem=gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr]) - gSettings["RobotRDPActive"]["RDPList"].pop(inRDPSessionKeyStr,None) # Remove item from RDPList + lProcessListResult = [] + if len(inBreakTriggerProcessWOExeList) > 0: + lProcessListResult = ProcessListGet(inProcessNameWOExeList=inBreakTriggerProcessWOExeList) # Run the task manager monitor + if len(lProcessListResult["ProcessWOExeList"]) == 0: # Start logoff if no process exist + # Run CMD - dont crosscheck because CMD dont return value to the clipboard when logoff + Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="RUN", inLogger=gSettings["Logger"], inRDPConfigurationItem=gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr]) + gSettings["RobotRDPActive"]["RDPList"].pop(inRDPSessionKeyStr,None) # Remove item from RDPList return lResult # Check RDP Session responsibility TODO NEED DEV + TEST @@ -131,7 +140,6 @@ def RDPSessionCMDRun(inRDPSessionKeyStr, inCMDStr, inModeStr="CROSSCHECK"): Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=inCMDStr, inModeStr=inModeStr, inLogger=gSettings["Logger"], inRDPConfigurationItem=gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr]) return lResult - # Create CMD str to stop process def RDPSessionProcessStop(inRDPSessionKeyStr, inProcessNameWEXEStr, inFlagForceCloseBool): global gSettings @@ -170,4 +178,35 @@ def RDPSessionFileStoredRecieve(inRDPSessionKeyStr, inRDPFilePathStr, inHostFile # Run CMD if lSessionHex: Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="LISTEN", inClipboardTimeoutSec = 120, inLogger=gSettings["Logger"], inRDPConfigurationItem=gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr]) + return lResult + + + +# # # # # # # Technical defs # # # # # # # # # # # # +#Check activity of the list of processes +def ProcessListGet(inProcessNameWOExeList=[]): + '''Get list of running process sorted by Memory Usage and filtered by inProcessNameWOExeList''' + lMapUPPERInput = {} # Mapping for processes WO exe + lResult = {"ProcessWOExeList":[],"ProcessDetailList":[]} + # Create updated list for quick check + lProcessNameWOExeList = [] + for lItem in inProcessNameWOExeList: + if lItem is not None: + lProcessNameWOExeList.append(f"{lItem.upper()}.EXE") + lMapUPPERInput[f"{lItem.upper()}.EXE"]= lItem + # # + # Iterate over the list + for proc in psutil.process_iter(): + try: + # Fetch process details as dict + pinfo = proc.as_dict(attrs=['pid', 'name', 'username']) + pinfo['vms'] = proc.memory_info().vms / (1024 * 1024) + pinfo['NameWOExeUpperStr'] = pinfo['name'][:-4].upper() + # Add if empty inProcessNameWOExeList or if process in inProcessNameWOExeList + if len(lProcessNameWOExeList)==0 or pinfo['name'].upper() in lProcessNameWOExeList: + pinfo['NameWOExeStr'] = lMapUPPERInput[pinfo['name'].upper()] + lResult["ProcessDetailList"].append(pinfo) # Append dict to list + lResult["ProcessWOExeList"].append(pinfo['NameWOExeStr']) + except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess): + pass return lResult \ No newline at end of file