public void ExecuteCommand(ScriptAction command) { //get command ScriptCommand parentCommand = command.ScriptCommand; if (parentCommand.CommandName == "RunTaskCommand") { parentCommand.CurrentScriptBuilder = TasktEngineUI.CallBackForm; } //set LastCommadExecuted LastExecutedCommand = command.ScriptCommand; //update execution line numbers LineNumberChanged(parentCommand.LineNumber); //handle pause request if (parentCommand.PauseBeforeExecution && TasktEngineUI.IsDebugMode && !ChildScriptFailed) { ReportProgress("Pausing Before Execution"); _isScriptPaused = true; TasktEngineUI.IsHiddenTaskEngine = false; } //handle pause bool isFirstWait = true; while (_isScriptPaused) { //only show pause first loop if (isFirstWait) { _currentStatus = EngineStatus.Paused; ReportProgress("Paused on Line " + parentCommand.LineNumber + ": " + (parentCommand.v_IsPrivate ? _privateCommandLog : parentCommand.GetDisplayValue())); ReportProgress("[Please select 'Resume' when ready]"); isFirstWait = false; } if (_isScriptSteppedInto && parentCommand.CommandName == "RunTaskCommand") { parentCommand.IsSteppedInto = true; parentCommand.CurrentScriptBuilder = TasktEngineUI.CallBackForm; _isScriptSteppedInto = false; TasktEngineUI.IsHiddenTaskEngine = true; break; } else if (_isScriptSteppedOver || _isScriptSteppedInto) { _isScriptSteppedOver = false; _isScriptSteppedInto = false; break; } //wait Thread.Sleep(1000); } _currentStatus = EngineStatus.Running; //handle if cancellation was requested if (IsCancellationPending) { return; } //If Child Script Failed and Child Script Error not Caught, next command should not be executed if (ChildScriptFailed && !ChildScriptErrorCaught) { throw new Exception("Child Script Failed"); } //bypass comments if (parentCommand.CommandName == "AddCodeCommentCommand" || parentCommand.IsCommented) { ReportProgress($"Skipping Line {parentCommand.LineNumber}: {(parentCommand.v_IsPrivate ? _privateCommandLog : parentCommand.GetDisplayValue().ConvertUserVariableToString(this))}", parentCommand.LogLevel); return; } //report intended execution if (parentCommand.CommandName != "LogMessageCommand") { ReportProgress($"Running Line {parentCommand.LineNumber}: {(parentCommand.v_IsPrivate ? _privateCommandLog : parentCommand.GetDisplayValue())}", parentCommand.LogLevel); } //handle any errors try { //determine type of command if ((parentCommand.CommandName == "LoopNumberOfTimesCommand") || (parentCommand.CommandName == "LoopContinuouslyCommand") || (parentCommand.CommandName == "LoopCollectionCommand") || (parentCommand.CommandName == "BeginIfCommand") || (parentCommand.CommandName == "BeginMultiIfCommand") || (parentCommand.CommandName == "BeginTryCommand") || (parentCommand.CommandName == "BeginLoopCommand") || (parentCommand.CommandName == "BeginMultiLoopCommand") || (parentCommand.CommandName == "BeginRetryCommand" || (parentCommand.CommandName == "BeginSwitchCommand"))) { //run the command and pass bgw/command as this command will recursively call this method for sub commands command.IsExceptionIgnored = true; parentCommand.RunCommand(this, command); } else if (parentCommand.CommandName == "SequenceCommand") { command.IsExceptionIgnored = true; parentCommand.RunCommand(this, command); } else if (parentCommand.CommandName == "StopCurrentTaskCommand") { IsCancellationPending = true; return; } else if (parentCommand.CommandName == "ExitLoopCommand") { CurrentLoopCancelled = true; } else if (parentCommand.CommandName == "NextLoopCommand") { CurrentLoopContinuing = true; } else if (parentCommand.CommandName == "SetEngineDelayCommand") { //get property value var engineDelay = parentCommand.PropertyValues["v_EngineSpeed"].ToString(); //var setEngineCommand = (SetEngineDelayCommand)parentCommand; //var engineDelay = setEngineCommand.v_EngineSpeed.ConvertToUserVariable(this); var delay = int.Parse(engineDelay); //update delay setting EngineSettings.DelayBetweenCommands = delay; } else { //sleep required time Thread.Sleep(EngineSettings.DelayBetweenCommands); //run the command parentCommand.RunCommand(this); if (parentCommand.CommandName == "LogMessageCommand") { string displayValue = parentCommand.GetDisplayValue().Replace("Log Message ['", "").Replace("']", ""); string logMessage = displayValue.Split('-').Last().ConvertUserVariableToString(this); displayValue = displayValue.Replace(displayValue.Split('-').Last(), logMessage); ReportProgress($"Logging Line {parentCommand.LineNumber}: {(parentCommand.v_IsPrivate ? _privateCommandLog : displayValue)}", parentCommand.LogLevel); } } } catch (Exception ex) { if (!(LastExecutedCommand.CommandName == "RethrowCommand")) { if (ChildScriptFailed) { ChildScriptFailed = false; ErrorsOccured.Clear(); } ErrorsOccured.Add(new ScriptError() { SourceFile = FileName, LineNumber = parentCommand.LineNumber, StackTrace = ex.ToString(), ErrorType = ex.GetType().Name, ErrorMessage = ex.Message }); } var error = ErrorsOccured.OrderByDescending(x => x.LineNumber).FirstOrDefault(); string errorMessage = $"Source: {error.SourceFile}, Line: {error.LineNumber} {parentCommand.GetDisplayValue()}, " + $"Exception Type: {error.ErrorType}, Exception Message: {error.ErrorMessage}"; //error occuured so decide what user selected if (ErrorHandlingAction != string.Empty) { switch (ErrorHandlingAction) { case "Continue Processing": ReportProgress("Error Occured at Line " + parentCommand.LineNumber + ":" + ex.ToString(), LogEventLevel.Error); ReportProgress("Continuing Per Error Handling"); break; default: throw ex; } } else { if (!command.IsExceptionIgnored && TasktEngineUI.IsDebugMode) { //load error form if exception is not handled TasktEngineUI.CallBackForm.IsUnhandledException = true; TasktEngineUI.AddStatus("Pausing Before Exception"); DialogResult result = TasktEngineUI.CallBackForm.LoadErrorForm(errorMessage); ReportProgress("Error Occured at Line " + parentCommand.LineNumber + ":" + ex.ToString(), LogEventLevel.Error); TasktEngineUI.CallBackForm.IsUnhandledException = false; if (result == DialogResult.OK) { ReportProgress("Ignoring Per User Choice"); ErrorsOccured.Clear(); if (_isScriptSteppedIntoBeforeException) { TasktEngineUI.CallBackForm.IsScriptSteppedInto = true; _isScriptSteppedIntoBeforeException = false; } else if (_isScriptSteppedOverBeforeException) { TasktEngineUI.CallBackForm.IsScriptSteppedOver = true; _isScriptSteppedOverBeforeException = false; } TasktEngineUI.uiBtnPause_Click(null, null); } else if (result == DialogResult.Abort || result == DialogResult.Cancel) { ReportProgress("Continuing Per User Choice"); TasktEngineUI.CallBackForm.RemoveDebugTab(); TasktEngineUI.uiBtnPause_Click(null, null); throw ex; } //TODO: Add Break Option } else { throw ex; } } } }
public async Task ExecuteCommand(ScriptAction command) { //get command ScriptCommand parentCommand = command.ScriptCommand; if (parentCommand == null) { return; } //in RunFromThisCommand exection, determine if/while logic. If logic returns true, skip until reaching the selected command if (!parentCommand.ScopeStartCommand && parentCommand.LineNumber < EngineContext.StartFromLineNumber) { return; } //if the selected command is within a while/retry, reset starting line number so that previous commands within the scope run in the following iteration else if (!parentCommand.ScopeStartCommand && parentCommand.LineNumber == EngineContext.StartFromLineNumber) { EngineContext.StartFromLineNumber = 1; } if (EngineContext.ScriptEngine != null && (parentCommand.CommandName == "RunTaskCommand" || parentCommand.CommandName == "ShowMessageCommand")) { parentCommand.CurrentScriptBuilder = EngineContext.ScriptEngine.EngineContext.ScriptBuilder; } //set LastCommandExecuted LastExecutedCommand = command.ScriptCommand; //update execution line numbers LineNumberChanged(parentCommand.LineNumber); //handle pause request if (EngineContext.ScriptEngine != null && parentCommand.PauseBeforeExecution && EngineContext.IsDebugMode && !ChildScriptFailed) { ReportProgress("Pausing Before Execution"); _isScriptPaused = true; EngineContext.ScriptEngine.IsHiddenTaskEngine = false; } //handle pause bool isFirstWait = true; while (_isScriptPaused) { //only show pause first loop if (isFirstWait) { EngineContext.CurrentEngineStatus = EngineStatus.Paused; ReportProgress("Paused on Line " + parentCommand.LineNumber + ": " + (parentCommand.v_IsPrivate ? PrivateCommandLog : parentCommand.GetDisplayValue())); ReportProgress("[Please select 'Resume' when ready]"); isFirstWait = false; } if (_isScriptSteppedInto && parentCommand.CommandName == "RunTaskCommand") { parentCommand.IsSteppedInto = true; parentCommand.CurrentScriptBuilder = EngineContext.ScriptEngine.EngineContext.ScriptBuilder; _isScriptSteppedInto = false; EngineContext.ScriptEngine.IsHiddenTaskEngine = true; break; } else if (_isScriptSteppedOver || _isScriptSteppedInto) { _isScriptSteppedOver = false; _isScriptSteppedInto = false; break; } if (((Form)EngineContext.ScriptEngine).IsDisposed) { IsCancellationPending = true; break; } //wait Thread.Sleep(1000); } EngineContext.CurrentEngineStatus = EngineStatus.Running; //handle if cancellation was requested if (IsCancellationPending) { return; } //If Child Script Failed and Child Script Error not Caught, next command should not be executed if (ChildScriptFailed && !ChildScriptErrorCaught) { throw new Exception("Child Script Failed"); } //bypass comments if (parentCommand.CommandName == "AddCodeCommentCommand" || parentCommand.CommandName == "BrokenCodeCommentCommand" || parentCommand.IsCommented) { return; } //report intended execution if (parentCommand.CommandName != "LogMessageCommand") { ReportProgress($"Running Line {parentCommand.LineNumber}: {(parentCommand.v_IsPrivate ? PrivateCommandLog : parentCommand.GetDisplayValue())}"); } //handle any errors try { //determine type of command if ((parentCommand.CommandName == "LoopNumberOfTimesCommand") || (parentCommand.CommandName == "LoopContinuouslyCommand") || (parentCommand.CommandName == "BeginForEachCommand") || (parentCommand.CommandName == "BeginIfCommand") || (parentCommand.CommandName == "BeginMultiIfCommand") || (parentCommand.CommandName == "BeginTryCommand") || (parentCommand.CommandName == "BeginWhileCommand") || (parentCommand.CommandName == "BeginMultiWhileCommand") || (parentCommand.CommandName == "BeginDoWhileCommand") || (parentCommand.CommandName == "BeginRetryCommand") || (parentCommand.CommandName == "BeginSwitchCommand")) { //run the command and pass bgw/command as this command will recursively call this method for sub commands //TODO: Make sure that removing these lines doesn't create any other issues //command.IsExceptionIgnored = true; await parentCommand.RunCommand(this, command); } else if (parentCommand.CommandName == "SequenceCommand") { //command.IsExceptionIgnored = true; await parentCommand.RunCommand(this, command); } else if (parentCommand.CommandName == "StopCurrentTaskCommand") { if (EngineContext.ScriptEngine != null && EngineContext.ScriptEngine.EngineContext.ScriptBuilder != null) { EngineContext.ScriptEngine.EngineContext.ScriptBuilder.IsScriptRunning = false; } IsCancellationPending = true; return; } else if (parentCommand.CommandName == "BreakCommand") { CurrentLoopCancelled = true; } else if (parentCommand.CommandName == "ContinueCommand") { CurrentLoopContinuing = true; } else { //sleep required time Thread.Sleep(EngineContext.EngineSettings.DelayBetweenCommands); if (!parentCommand.v_ErrorHandling.Equals("None")) { ErrorHandlingAction = parentCommand.v_ErrorHandling; } else { ErrorHandlingAction = string.Empty; } //run the command try { await parentCommand.RunCommand(this); } catch (Exception ex) { switch (ErrorHandlingAction) { case "Ignore Error": ReportProgress("Error Occured at Line " + parentCommand.LineNumber + ":" + ex.ToString(), Enum.GetName(typeof(LogEventLevel), LogEventLevel.Error)); ReportProgress("Ignoring Per Error Handling"); break; case "Report Error": ReportProgress("Error Occured at Line " + parentCommand.LineNumber + ":" + ex.ToString(), Enum.GetName(typeof(LogEventLevel), LogEventLevel.Error)); ReportProgress("Handling Error and Attempting to Continue"); throw ex; default: throw ex; } } } } catch (Exception ex) { if (!(LastExecutedCommand.CommandName == "RethrowCommand")) { if (ChildScriptFailed) { ChildScriptFailed = false; ErrorsOccured.Clear(); } ErrorsOccured.Add(new ScriptError() { SourceFile = EngineContext.FilePath, LineNumber = parentCommand.LineNumber, StackTrace = ex.ToString(), ErrorType = ex.GetType().Name, ErrorMessage = ex.Message }); } var error = ErrorsOccured.OrderByDescending(x => x.LineNumber).FirstOrDefault(); string errorMessage = $"Source: {error.SourceFile}, Line: {error.LineNumber} {parentCommand.GetDisplayValue()}, " + $"Exception Type: {error.ErrorType}, Exception Message: {error.ErrorMessage}"; if (EngineContext.ScriptEngine != null && !command.IsExceptionIgnored && EngineContext.IsDebugMode) { //load error form if exception is not handled EngineContext.ScriptEngine.EngineContext.ScriptBuilder.IsUnhandledException = true; EngineContext.ScriptEngine.AddStatus("Pausing Before Exception"); DialogResult result = DialogResult.OK; if (ErrorHandlingAction != "Ignore Error") { result = EngineContext.ScriptEngine.EngineContext.ScriptBuilder.LoadErrorForm(errorMessage); } ReportProgress("Error Occured at Line " + parentCommand.LineNumber + ":" + ex.ToString(), Enum.GetName(typeof(LogEventLevel), LogEventLevel.Debug)); EngineContext.ScriptEngine.EngineContext.ScriptBuilder.IsUnhandledException = false; if (result == DialogResult.OK) { ReportProgress("Ignoring Per User Choice"); ErrorsOccured.Clear(); if (_isScriptSteppedIntoBeforeException) { EngineContext.ScriptEngine.EngineContext.ScriptBuilder.IsScriptSteppedInto = true; _isScriptSteppedIntoBeforeException = false; } else if (_isScriptSteppedOverBeforeException) { EngineContext.ScriptEngine.EngineContext.ScriptBuilder.IsScriptSteppedOver = true; _isScriptSteppedOverBeforeException = false; } EngineContext.ScriptEngine.uiBtnPause_Click(null, null); } else if (result == DialogResult.Abort || result == DialogResult.Cancel) { ReportProgress("Continuing Per User Choice"); EngineContext.ScriptEngine.EngineContext.ScriptBuilder.RemoveDebugTab(); EngineContext.ScriptEngine.uiBtnPause_Click(null, null); throw ex; } } else { throw ex; } } }