/// <summary>
        ///   Kill the process by specifying its ProcessName.
        ///   All the below kill conventions will send the TERM signal to the specified process.
        /// </summary>
        /// <param name="ProcessName"></param>
        public void Abort(string ProcessName)
        {
            ExecItem task = ExecuterContainer.Values.FirstOrDefault(x => x.ProcessName == ProcessName);

            if (task != null && task.execItem != null)
            {
                try
                {
                    task.execItem.getProcess().Kill();
#if DEBUG
                    Console.WriteLine($"Process {ProcessName} is killed by user request");
#endif
                    OnProcessExit(ProcessName, $"Process is killed by user request", "-1");
                }
                catch (Exception ex)
                {
#if DEBUG
                    Console.WriteLine($"Failed Kill Process {ProcessName} ");
#endif
                    OnProcessExit(ProcessName, $"Failed Kill Process {ex.Message}", "-1");
                }
            }
            else
            {
#if DEBUG
                Console.WriteLine($" Process {ProcessName} is not exist");
#endif
                OnProcessExit(ProcessName, $" Process  is not exist", "-1");
            }
        }
 /// <summary>
 ///    Set Current Task Status
 /// </summary>
 /// <param name="ProcessName"></param>
 /// <param name="CurrentStatus"></param>
 public void SetCurrentStatus(string ProcessName, String CurrentStatus)
 {
     if (ExecuterContainer.Count > 0)
     {
         ExecItem item = ExecuterContainer.Values.FirstOrDefault(x => x.ProcessName == ProcessName);
         if (item != null)
         {
             item.CurrentStatus = CurrentStatus;
         }
     }
 }
 /// <summary>
 ///   Get Message from Active Process
 /// </summary>
 /// <param name="ProcessName"></param>
 /// <returns></returns>
 public string GetLatestMessage(string ProcessName)
 {
     if (ExecuterContainer.Count > 0)
     {
         ExecItem item = ExecuterContainer.Values.FirstOrDefault(x => x.ProcessName == ProcessName);
         if (item != null)
         {
             return((item?.execItem?.LatestMessage) ?? "");
         }
     }
     return("");
 }
 /// <summary>
 ///    Get current task status string
 /// </summary>
 /// <param name="ProcessName"></param>
 public string GetCurrentStatus(string ProcessName)
 {
     if (ExecuterContainer.Count > 0)
     {
         ExecItem item = ExecuterContainer.Values.FirstOrDefault(x => x.ProcessName == ProcessName);
         if (item != null)
         {
             return(item.CurrentStatus);
         }
     }
     return("Finished");
 }
 /// <summary>
 ///   Check specific task is completed
 /// </summary>
 /// <param name="name"></param>
 /// <returns></returns>
 public bool IsCompleted(String name)
 {
     try
     {
         if (ExecuterContainer.Count > 0)
         {
             ExecItem item = ExecuterContainer.Values.FirstOrDefault(x => x.ProcessName == name);
             if (item != null)
             {
                 return(false);
             }
         }
     }
     catch { }
     return(true);
 }
        /// <summary>
        ///     Get active process by ID
        /// </summary>
        /// <param name="processID"></param>
        /// <returns></returns>
        public Process GetProcess(string processID)
        {
            ExecItem task = ExecuterContainer.Values.FirstOrDefault(x => x.ProcessName == processID);

            if (task != null && task.execItem != null)
            {
                try
                {
                    return(task.execItem.getProcess());
                }
                catch (Exception ex)
                {
                    Debug.WriteLine($"Failed Kill Process {ex.Message} ");
                    throw;
                }
            }
            else
            {
                throw new InvalidDataException(processID);
            }
        }
        public override bool Equals(Object task)
        {
            if (!(task is ExecItem))
            {
                return(false);
            }
            //if (task == null)
            //{
            //    return false;
            //}
            ExecItem item = task as ExecItem;

            if (item != null)
            {
                return(this.Id == item.Id);
            }
            ExecItem taskItem = task as ExecItem;

            if (taskItem != null)
            {
                return(this.Id == taskItem.Id);
            }
            return(false);
        }
        /// <summary>
        ///    Remove task from container
        /// </summary>
        /// <param name="taskItem"></param>
        /// <returns>TaskItem</returns>
        public String Remove(ExecItem taskItem)
        {
            ExecItem outItem     = null;
            String   ProcessName = null;

            if (taskItem == null)
            {
                return(null);
            }
            try
            {
                if (ExecuterContainer.TryRemove(taskItem.Id, out outItem))
                {
                    if (outItem != null)
                    {
                        ProcessName = outItem.ProcessName;
                    }
                }
            }
            catch (Exception)
            {
            }
            return(ProcessName);
        }
 /// <summary>
 ///   Get task status by task name
 /// </summary>
 /// <param name="ProcessName"></param>
 /// <returns></returns>
 public TaskStatus Status(String ProcessName)
 {
     try
     {
         if (ExecuterContainer.Count > 0)
         {
             List <ExecItem> items = ExecuterContainer.Values.ToList <ExecItem>();
             ExecItem        item  = items.FirstOrDefault(x => x.ProcessName == ProcessName);
             if (item != null)
             {
                 Task task = item.Task_;
                 if (task == null)
                 {
                     return(TaskStatus.RanToCompletion);
                 }
                 return(task.Status);
             }
         }
     }
     catch (Exception)
     {
     }
     return(TaskStatus.RanToCompletion);
 }
        private bool TryAdd(Task task, ExecRunItem executer, String ParamProcessName = null, String description = null, Func <String, String, bool> callBack = null)
        {
            String mProcessName = "";
            String errorMessage = "";

            if (ParamProcessName == null || ParamProcessName == "")
            {
                mProcessName = Guid.NewGuid().ToString();
            }
            else
            {
                mProcessName = ParamProcessName;
            }
            task.ContinueWith(currentTask =>
            {
                ExecItem outTaskItem = null;
                try
                {
                    if (ExecuterContainer.TryGetValue(currentTask.Id, out outTaskItem))
                    {
                        if (outTaskItem.Callback != null)
                        {
                            try
                            {
#if DEBUG
                                Console.WriteLine($"exit {outTaskItem.ProcessName}");
#endif
                                outTaskItem.Callback(outTaskItem.ProcessName, $"Exit:{outTaskItem.ProcessName}"); // callback function for specific task
                            }
                            catch (Exception ex) { errorMessage = ex.Message; }
                        }
                        String Name = Remove(outTaskItem);
                    }
                    if (OnProcessExit != null)
                    {
                        Console.WriteLine($"exit {outTaskItem.ProcessName}");
                        if (errorMessage.Length == 0)
                        {
                            OnProcessExit(outTaskItem.ProcessName, $"Exit", outTaskItem?.execItem?.getExitCode().ToString()); // Callback exit function for all tasks
                        }
                        else
                        {
                            OnProcessExit(outTaskItem.ProcessName, $"error:{errorMessage}", outTaskItem?.execItem?.getExitCode().ToString()); // Callback exit function for all tasks
                        }
                    }
                }
                catch (Exception ex)
                {
                    OnProcessExit(outTaskItem.ProcessName, $"error:{ex.Message}", outTaskItem?.execItem?.getExitCode().ToString()); // Callback exit function for all tasks
                    Remove(outTaskItem);
                }
            });
            String _description = description;
            if (_description == null)
            {
                try
                {
                    var      fieldInfo = typeof(Task).GetField("m_action", BindingFlags.Instance | BindingFlags.NonPublic);
                    Delegate action    = fieldInfo.GetValue(task) as Delegate;
                    if (action != null)
                    {
                        var name = action.Method.Name;
                        var type = action.Method.DeclaringType.FullName;
                        _description = $"Method: {name} Type: {type}";
                    }
                }
                catch (Exception ex)
                {
#if DEBUG
                    Console.WriteLine(ex.Message);
#endif
                    throw;
                }
            }
            var taskItem = new ExecItem
            {
                ProcessName   = mProcessName,
                Id            = task.Id,
                Task_         = task,
                StartTime     = DateTime.Now,
                Description   = _description,
                Callback      = callBack,
                CurrentStatus = "Started",
                execItem      = executer
            };
            List <ExecItem> items = ExecuterContainer.Values.ToList <ExecItem>();
            ExecItem        item  = items.FirstOrDefault(x => x.ProcessName == mProcessName);
            if (!(item is null))
            {
                return(false);
            }
            bool ok = ExecuterContainer.TryAdd(taskItem.Id, taskItem);
            if (ok)
            {
                try
                {
                    task.Start();
                    return(true);
                }
                catch
                {
                    Remove(item);
                    return(false);
                }
            }
            return(false);
        }