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;
                    }
                }
            }
        }
Пример #2
0
        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;
                }
            }
        }