/// <summary>
        ///   Adds a Process to the Execute Container if the ProcessID does not already exist
        /// </summary>
        /// <param name="ProcessID">Unigue Process ID</param>
        /// <param name="exec">Execute Task Name</param>
        /// <param name="param">Prameters line</param>
        /// <param name="description">Process description</param>
        /// <param name="callBack">Callback function</param>
        /// <param name="workingDir">Directory</param>
        /// <param name="timeoout"></param>
        /// <returns></returns>
        public String RunExec(String ProcessID, String exec, String param = "",
                              String description = null, Func <String, String, bool> callBack = null, String workingDir = null, int timeoout = 0)
        {
            ExecRunItem executer = null;

            executer = new ExecRunItem();
            String error_Message = "";
            Task   task          = new Task(() =>
            {
                try
                {
                    executer.setSystemEnvironment();
                    String exec1 = exec;
                    if (workingDir == null)
                    {
                        executer.WorkingDirectory = Environment.CurrentDirectory;
                    }
                    else
                    {
                        executer.WorkingDirectory = workingDir;
                        exec1 = workingDir + Path.DirectorySeparatorChar + exec;
                    }
                    executer.RunProcess(ProcessID, exec1, param, callBack, timeoout);
                }
                catch (Exception ex)
                {
                    error_Message = ex.Message;
                }
                executer = null;
            });

            if (!this.TryAdd(task, executer, ProcessID, description, callBack))
            {
                return("Failed to start. (app already running)");
            }
            return(error_Message);
        }
        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);
        }