public void Start()
        {
            try
            {
                var args = new CommandLineArguments(Environment.GetCommandLineArgs(), false);

                var doAWC = !args.Contains("runonly") || args.GetStringDefault("runonly", "").ToLower() == "awc";
                var doDPS = !args.Contains("runonly") || args.GetStringDefault("runonly", "").ToLower() == "dips";
                var doTVC = !args.Contains("runonly") || args.GetStringDefault("runonly", "").ToLower() == "tvc";
                var doCSE = !args.Contains("runonly") || args.GetStringDefault("runonly", "").ToLower() == "cse";

                config.load(logger);

                var awc  = new AutoWallChange(logger, config.settings.awc, workingDirectory);
                var dips = new DesktopIconPositionSaver(logger, config.settings.dips, workingDirectory);
                var tvc  = new TextVersionControl(logger, config.settings.tvc, workingDirectory);
                var cse  = new CronScriptExecutor(logger, config.settings.cse, workingDirectory);

                if (doAWC)
                {
                    awc.Init(new ATCTaskProxy("AutoWallChange", "AWC"));
                }
                if (doDPS)
                {
                    dips.Init(new ATCTaskProxy("DesktopIconPositionSaver", "DIPS"));
                }
                if (doTVC)
                {
                    tvc.Init(new ATCTaskProxy("TextVersionControl", "TVC"));
                }
                if (doCSE)
                {
                    cse.Init(new ATCTaskProxy("CronScriptExecutor", "CSE"));
                }

                if (doAWC)
                {
                    awc.Start();
                }
                Thread.Sleep(500);

                if (doDPS)
                {
                    dips.Start();
                }
                Thread.Sleep(500);

                if (doTVC)
                {
                    tvc.Start();
                }
                Thread.Sleep(500);

                if (doCSE)
                {
                    cse.Start();
                }
                Thread.Sleep(500);

                config.save();

#if DEBUG
                System.Console.WriteLine();
                System.Console.WriteLine("Prease any key to quit...");
                System.Console.ReadLine();
#endif
            }
            catch (Exception e)
            {
                logger.Log("ATC", null, "Uncaught Exception: " + e);
                ATCModule.ShowExtMessage("Uncaught Exception in ATC", e.ToString());
            }
            finally
            {
                logger.SaveAll();
            }
        }
        private void ThreadRun()
        {
            _mainTask.Start();

            _mainTask.RegisterRoot();

            var config = new ConfigWrapper(workingDirectory);

            var doAWC = !args.Contains("runonly") || args.GetStringDefault("runonly", "").ToLower() == "awc";
            var doDPS = !args.Contains("runonly") || args.GetStringDefault("runonly", "").ToLower() == "dips";
            var doTVC = !args.Contains("runonly") || args.GetStringDefault("runonly", "").ToLower() == "tvc";
            var doCSE = !args.Contains("runonly") || args.GetStringDefault("runonly", "").ToLower() == "cse";

            config.load(logger);


            var awc  = new AutoWallChange(logger, config.settings.awc, workingDirectory);
            var dips = new DesktopIconPositionSaver(logger, config.settings.dips, workingDirectory);
            var tvc  = new TextVersionControl(logger, config.settings.tvc, workingDirectory);
            var cse  = new CronScriptExecutor(logger, config.settings.cse, workingDirectory);

            // =====================================================================================================

            ATCTaskProxy taskAWC = null;
            ATCTaskProxy taskDPS = null;
            ATCTaskProxy taskTVC = null;
            ATCTaskProxy taskCSE = null;

            var newtasks = new List <ATCTaskProxy>();

            if (doAWC)
            {
                newtasks.Add(taskAWC = new ATCTaskProxy("AutoWallChange", "AWC"));
            }
            if (doDPS)
            {
                newtasks.Add(taskDPS = new ATCTaskProxy("DesktopIconPositionSaver", "DIPS"));
            }
            if (doTVC)
            {
                newtasks.Add(taskTVC = new ATCTaskProxy("TextVersionControl", "TVC"));
            }
            if (doCSE)
            {
                newtasks.Add(taskCSE = new ATCTaskProxy("CronScriptExecutor", "CSE"));
            }

            if (doAWC)
            {
                newtasks.AddRange(awc.Init(taskAWC));
            }
            if (doDPS)
            {
                newtasks.AddRange(dips.Init(taskDPS));
            }
            if (doTVC)
            {
                newtasks.AddRange(tvc.Init(taskTVC));
            }
            if (doCSE)
            {
                newtasks.AddRange(cse.Init(taskCSE));
            }

            foreach (var t in newtasks)
            {
                DispatcherHelper.SmartInvoke(() => { _vm.Tasks.Add(t); });
                Thread.Sleep(25);
            }

            // =====================================================================================================

            if (doAWC)
            {
                taskAWC.Start();
                awc.Start();
                taskAWC.FinishSuccess();
                Thread.Sleep(100);
            }

            if (doDPS)
            {
                taskDPS.Start();
                dips.Start();
                taskDPS.FinishSuccess();
                Thread.Sleep(100);
            }

            if (doTVC)
            {
                taskTVC.Start();
                tvc.Start();
                taskTVC.FinishSuccess();
                Thread.Sleep(100);
            }

            if (doCSE)
            {
                taskCSE.Start();
                cse.Start();
                taskCSE.FinishSuccess();
                Thread.Sleep(100);
            }

            // =====================================================================================================

            config.save();

            _mainTask.FinishSuccess();

            logger.SaveAll();

            if (_vm.Tasks.All(p => p.State == ProxyState.Success))
            {
                _isAutoClosing = true;

                var max = 10 * 1000;

                new Thread(() =>
                {
                    var start = Environment.TickCount;
                    for (; ;)
                    {
                        if (_abortAutoClosing)
                        {
                            DispatcherHelper.SmartInvoke(() => { _vm.CloseProgress = 0; });
                            return;
                        }

                        var delta = Environment.TickCount - start;

                        if (delta > max)
                        {
                            DispatcherHelper.SmartInvoke(() => { App.Current.MainWindow.Close(); });
                            return;
                        }
                        else
                        {
                            var p = ((delta * 100) / max);
                            if (p != _vm.CloseProgress)
                            {
                                DispatcherHelper.SmartInvoke(() => { _vm.CloseProgress = p; });
                            }
                        }

                        Thread.Yield();
                    }
                }).Start();
            }
        }