public async Task DeployAsync()
        {
            try
            {
                await Task.Run(() => SaveConfigToXml());

                if (configuration.CopyToUpdate)
                {
                    await data.ForEachAsync(CopyAssembly);
                }

                if (configuration.CopyToBin)
                {
                    await Data.ForEachAsync(CopyBin);
                }

                if (configuration.CopyToSmart)
                {
                    await Data.ForEachAsync(CopySmart);
                }
            }
            catch (Exception ex)
            {
                OutputService.WriteOutputWithContext($"Error: {ex.Message}");
            }
        }
        private void CopySmart(ProjectData project)
        {
            if (!project.Include)
            {
                return;
            }
            OutputService.WriteOutputWithContext($"Start copy to Smart: {project.Name}");
            var smartDirectory = new DirectoryInfo(SmartDirectory);

            if (!smartDirectory.Exists)
            {
                OutputService.WriteOutputWithContext($"Copy to Smart failed: Path does not Exists -> {smartDirectory.FullName}");
            }
            else
            {
                var assembly       = new FileInfo(project.FullAssemblyPath);
                var targetAssembly = new FileInfo(Path.Combine(smartDirectory.FullName, assembly.Name));

                assembly.CopyTo(targetAssembly.FullName, true);

                if (assembly.ToFileHash() != targetAssembly.ToFileHash())
                {
                    OutputService.WriteOutputWithContext($"Error: the File {assembly.Name} doesn't match the Source.");
                    OutputService.WriteOutputWithContext(
                        $"Hash: Source {assembly.ToFileHash()} <> Target {targetAssembly.ToFileHash()}");
                }
            }

            OutputService.WriteOutputWithContext($"Finished copy to Smart: {project.Name}");
        }
        private void LoadLatestVersion()
        {
            if (!configuration.DoCheckout)
            {
                return;
            }
            try
            {
                var solution     = service.Solution;
                var solutionFile = solution.FullName;

                solution.Close(true);

                OutputService.WriteOutputWithContext($"<TFS>Get latest Version of: {solutionPath.DirectoryName}");
                tfsServer.UpdateProject(solutionPath.DirectoryName);

                if (tfsServer.Failures?.Length > 0)
                {
                    OutputService.WriteOutputWithContext($"<TFS>Sync failed: {solutionPath.DirectoryName}");

                    foreach (var fail in tfsServer.Failures)
                    {
                        OutputService.WriteOutputWithContext($"<TFS>{fail.GetFormattedMessage()}");
                    }
                }

                solution.Open(solutionFile);
            }
            catch (Exception ex)
            {
                logger.Error(ex, ex.Message);
                OutputService.WriteOutputWithContext($"Error: {ex.Message}");
            }
        }
        private void CopyAssembly(ProjectData project)
        {
            try
            {
                if (!project.Include)
                {
                    return;
                }
                OutputService.WriteOutputWithContext($"Start copy to Update: {project.Name}");
                var dynamicPart = project.HasToRegister ? TargetRegDir : TargetAppDir;

                var assembly       = new FileInfo(project.FullAssemblyPath);
                var targetPath     = new DirectoryInfo(Path.Combine(configuration.FullDeployPath, dynamicPart));
                var targetAssembly = new FileInfo(Path.Combine(targetPath.FullName, assembly.Name));

                if (assembly.Exists && targetPath.Exists)
                {
                    assembly.CopyTo(targetAssembly.FullName, true);

                    if (assembly.ToFileHash() == targetAssembly.ToFileHash())
                    {
                        return;
                    }

                    OutputService.WriteOutputWithContext($"Error: the File {assembly.Name} doesn't match the Source.");
                    OutputService.WriteOutputWithContext(
                        $"Hash: Source {assembly.ToFileHash()} <> Target {targetAssembly.ToFileHash()}");
                }
                else
                {
                    if (!assembly.Exists)
                    {
                        OutputService.WriteOutputWithContext($"Build is missing: {assembly.FullName}");
                    }
                    if (!targetPath.Exists)
                    {
                        OutputService.WriteOutputWithContext($"targetPath is missing: {targetPath.FullName}");
                    }
                }

                OutputService.WriteOutputWithContext($"Finished copy to Update: {project.Name}");
            }
            catch (Exception ex)
            {
                OutputService.WriteOutputWithContext($"Error: {ex.Message}");
            }
        }
        private void SaveConfigToXml()
        {
            OutputService.WriteOutputWithContext("Start: Saving Config to Xml.");

            if (solutionPath?.DirectoryName != null)
            {
                var xmlFile = Path.Combine(solutionPath.DirectoryName,
                                           solutionPath.Name.Replace(solutionPath.Extension, string.Empty));

                OutputService.WriteOutputWithContext($"Prossesing: Saving Config to Xml => {xmlFile}");

                SerializationService.ToXml($"{xmlFile}ConfigData.xml", Configuration);
                SerializationService.ToXml($"{xmlFile}ProjectData.xml", Data);
            }

            OutputService.WriteOutputWithContext("Finished: Saving Config to Xml.");
        }
        public async Task LoadAsync()
        {
            try
            {
                WorkingStart();

                OutputService.WriteOutputWithContext("Start load Projectinformation.");

                solutionPath = new FileInfo(service.Solution.FullName);

                if (solutionPath?.DirectoryName != null)
                {
                    var xmlFile = Path.Combine(solutionPath.DirectoryName,
                                               solutionPath.Name.Replace(solutionPath.Extension, string.Empty));

                    Configuration = SerializationService.FromXml <ConfigData>($"{xmlFile}ConfigData.xml");
                    Data          = SerializationService.FromXml <ObservableCollection <ProjectData> >($"{xmlFile}ProjectData.xml");
                }

                if (solutionPath.FullName.Contains("Dev-Feature"))
                {
                    Configuration.IsFeature = true;
                }

                var task = Task.Run(() => Load());

                await task;

                var result = task.Result;

                Data =
                    new ObservableCollection <ProjectData>(
                        Data.Concat(result.Select(item => item).Where(item => !Data.Contains(item))));

                OutputService.WriteOutputWithContext("Finshed load Projectinformation.");
            }
            catch (Exception exception)
            {
                OutputService.WriteOutputWithContext($"Error: {exception.Message}");
                logger.Error(exception, exception.Message);
            }
            finally
            {
                WorkingStop();
            }
        }
        public void _BuildDone(vsBuildScope scope, vsBuildAction action)
        {
            try
            {
                if (scope != vsBuildScope.vsBuildScopeSolution)
                {
                    return;
                }
                switch (action)
                {
                case vsBuildAction.vsBuildActionBuild:

                    OutputService.WriteOutputWithContext("StartDeploy");
                    Task.Run(DeployAsync);

                    break;

                case vsBuildAction.vsBuildActionRebuildAll:
                    break;

                case vsBuildAction.vsBuildActionClean:
                    break;

                case vsBuildAction.vsBuildActionDeploy:
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(action), action, null);
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex, ex.Message);
                OutputService.WriteOutputWithContext($"Error: {ex.Message}");
            }
            finally
            {
                WorkingStop();
                service.Events.BuildEvents.OnBuildDone -= _BuildDone;
            }
        }
        private ObservableCollection <ProjectData> Load()
        {
            OutputService.WriteOutputWithContext("Start: Load");

            var result   = new ObservableCollection <ProjectData>();
            var projects = service.Solution.Projects;

            solutionPath = new FileInfo(service.Solution.FullName);

            for (var i = 1; i <= projects.Count; i++)
            {
                var project = projects.Item(i);

                if (project?.Properties != null && !project.Name.ToLower().Contains(".test") && Data.FirstOrDefault(x => x.Name == project.Name) == null)
                {
                    var queryProperties = from projectProperty in project.Properties.ToDictionary().AsEnumerable()
                                          where usedProperties.Contains(projectProperty.Key)
                                          select projectProperty;

                    var dictionaryProperties = queryProperties.ToDictionary(x => x.Key, x => x.Value);

                    var queryBuildConfig =
                        from projectBuildConfig in
                        project.ConfigurationManager.ActiveConfiguration.Properties.ToDictionary().AsEnumerable()
                        where projectBuildConfig.Key == CodeAnalysisInputAssembly
                        select projectBuildConfig;

                    var dictionaryBuildConfig = queryBuildConfig.ToDictionary(x => x.Key, x => x.Value);

                    if (dictionaryBuildConfig.Count == 0 || dictionaryProperties.Count == 0)
                    {
                        continue;
                    }
                    var assemblyVersionTemp = dictionaryProperties[AssemblyVersion].Split('.');
                    var dateiVersionTemp    = dictionaryProperties[AssemblyFileVersion].Split('.');

                    var currentProject = new ProjectData
                    {
                        Name         = projects.Item(i).Name,
                        AssemblyPath = dictionaryBuildConfig[CodeAnalysisInputAssembly],
                        AssemblyName = dictionaryProperties[AssemblyName],
                        FullPath     = dictionaryProperties[FullPath],
                        AssemblyInfo = new AssemblyData
                        {
                            Titel           = dictionaryProperties[Title],
                            Beschreibung    = dictionaryProperties[Description],
                            Firma           = dictionaryProperties[Company],
                            Produkt         = dictionaryProperties[Product],
                            Copyright       = dictionaryProperties[Copyright],
                            Marke           = dictionaryProperties[Trademark],
                            AssemblyVersion =
                                new VersionData(assemblyVersionTemp[0], assemblyVersionTemp[1],
                                                assemblyVersionTemp[2],
                                                assemblyVersionTemp[3]),
                            Dateiversion =
                                new VersionData(dateiVersionTemp[0], dateiVersionTemp[1], dateiVersionTemp[2],
                                                dateiVersionTemp[3])
                        }
                    };

                    result.Add(currentProject);
                }
            }

            OutputService.WriteOutputWithContext("Finished: Load");

            return(new ObservableCollection <ProjectData>(result.Distinct()));
        }