Esempio n. 1
0
        /// <summary>
        ///     Runs the updating process. This method does not block the calling thread.
        /// </summary>
        private void RunUpdateAsync()
        {
            string parentPath = Directory.GetParent(Program.PackageFilePaths.First()).FullName;

            /* Extract and count for the progress */
            foreach (var packageFilePath in Program.PackageFilePaths)
            {
                var    version = new UpdateVersion(Path.GetFileNameWithoutExtension(packageFilePath));
                string extractedDirectoryPath =
                    Path.Combine(parentPath, version.ToString());
                Directory.CreateDirectory(extractedDirectoryPath);
                using (var zf = ZipFile.Read(packageFilePath))
                {
                    zf.ParallelDeflateThreshold = -1;
                    try
                    {
                        foreach (var entry in zf)
                        {
                            entry.Extract(extractedDirectoryPath);
                        }
                    }
                    catch (Exception ex)
                    {
                        _progressReporter.Fail(ex);
                        CleanUp();
                        _progressReporter.Terminate();
                        if (!Program.IsHostApplicationClosed)
                        {
                            return;
                        }

                        var process = new Process
                        {
                            StartInfo =
                            {
                                UseShellExecute = true,
                                FileName        = Program.ApplicationExecutablePath,
                                Arguments       =
                                    String.Join("|",
                                                Program.Arguments.Where(
                                                    item =>
                                                    item.ExecutionOptions ==
                                                    UpdateArgumentExecutionOptions.OnlyOnFaulted).Select(item => item.Argument))
                            }
                        };
                        process.Start();
                        return;
                    }

                    _totalTaskCount += new DirectoryInfo(extractedDirectoryPath).GetDirectories().Sum(
                        directory => Directory.GetFiles(directory.FullName, "*.*", SearchOption.AllDirectories).Length);
                }
            }

            foreach (var operationEnumerable in Program.Operations.Select(item => item.Value))
            {
                _totalTaskCount +=
                    operationEnumerable.Count(
                        item => item.Area != OperationArea.Registry && item.Method != OperationMethod.Delete);
            }

            foreach (
                var array in
                Program.Operations.Select(entry => entry.Value)
                .Select(operationEnumerable => operationEnumerable.Where(
                            item =>
                            item.Area == OperationArea.Registry && item.Method != OperationMethod.SetValue)
                        .Select(registryOperation => registryOperation.Value2)
                        .OfType <JArray>()).SelectMany(entries =>
            {
                var entryEnumerable = entries as JArray[] ?? entries.ToArray();
                return(entryEnumerable);
            }))
            {
                _totalTaskCount += array.ToObject <IEnumerable <string> >().Count();
            }

            foreach (
                var array in
                Program.Operations.Select(entry => entry.Value)
                .Select(operationEnumerable => operationEnumerable.Where(
                            item => item.Area == OperationArea.Files && item.Method == OperationMethod.Delete)
                        .Select(registryOperation => registryOperation.Value2)
                        .OfType <JArray>()).SelectMany(entries =>
            {
                var entryEnumerable = entries as JArray[] ?? entries.ToArray();
                return(entryEnumerable);
            }))
            {
                _totalTaskCount += array.ToObject <IEnumerable <string> >().Count();
            }

            foreach (
                var array in
                Program.Operations.Select(entry => entry.Value)
                .Select(operationEnumerable => operationEnumerable.Where(
                            item =>
                            item.Area == OperationArea.Registry && item.Method == OperationMethod.SetValue)
                        .Select(registryOperation => registryOperation.Value2)
                        .OfType <JArray>()).SelectMany(entries =>
            {
                var entryEnumerable = entries as JArray[] ?? entries.ToArray();
                return(entryEnumerable);
            }))
            {
                _totalTaskCount += array.ToObject <IEnumerable <string> >().Count();
            }

            foreach (
                var packageFilePath in
                Program.PackageFilePaths.OrderBy(item => new UpdateVersion(Path.GetFileNameWithoutExtension(item))))
            {
                var    version = new UpdateVersion(Path.GetFileNameWithoutExtension(packageFilePath));
                string extractedDirectoryPath =
                    Path.Combine(parentPath, version.ToString());
                foreach (var directory in new DirectoryInfo(extractedDirectoryPath).GetDirectories())
                {
                    switch (directory.Name)
                    {
                    case "Program":
                        CopyDirectoryRecursively(directory.FullName, Program.AimFolder);
                        break;

                    case "AppData":
                        CopyDirectoryRecursively(directory.FullName,
                                                 Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
                        break;

                    case "Temp":
                        CopyDirectoryRecursively(directory.FullName, Path.GetTempPath());
                        break;

                    case "Desktop":
                        CopyDirectoryRecursively(directory.FullName,
                                                 Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory));
                        break;
                    }
                }

                try
                {
                    IEnumerable <Operation> currentVersionOperations =
                        Program.Operations.Any(item => new UpdateVersion(item.Key) == version)
                            ? Program.Operations.First(item => new UpdateVersion(item.Key) == version).Value
                            : Enumerable.Empty <Operation>();
                    foreach (var operation in currentVersionOperations)
                    {
                        float  percentage;
                        JArray secondValueAsArray;
                        switch (operation.Area)
                        {
                        case OperationArea.Files:
                            switch (operation.Method)
                            {
                            case OperationMethod.Delete:
                                var deleteFilePathParts = operation.Value.Split('\\');
                                var deleteFileFullPath  = Path.Combine(
                                    Operation.GetDirectory(deleteFilePathParts[0]),
                                    String.Join("\\",
                                                deleteFilePathParts.Where(item => item != deleteFilePathParts[0])));
                                secondValueAsArray = operation.Value2 as JArray;
                                if (secondValueAsArray != null)
                                {
                                    foreach (
                                        var fileToDelete in secondValueAsArray.ToObject <IEnumerable <string> >())
                                    {
                                        string path = Path.Combine(deleteFileFullPath, fileToDelete);
                                        if (File.Exists(path))
                                        {
                                            File.Delete(path);
                                        }

                                        _doneTaskAmount += 1;
                                        percentage       = ((float)_doneTaskAmount / _totalTaskCount) * 100f;
                                        _progressReporter.ReportOperationProgress(percentage,
                                                                                  String.Format(Program.FileDeletingOperationText, fileToDelete));
                                    }
                                }
                                break;

                            case OperationMethod.Rename:
                                var renameFilePathParts = operation.Value.Split('\\');
                                var renameFileFullPath  = Path.Combine(
                                    Operation.GetDirectory(renameFilePathParts[0]),
                                    String.Join("\\",
                                                renameFilePathParts.Where(item => item != renameFilePathParts[0])));
                                if (File.Exists(renameFileFullPath))
                                {
                                    File.Move(renameFileFullPath,
                                              Path.Combine(Directory.GetParent(renameFileFullPath).FullName,
                                                           operation.Value2.ToString()));
                                }

                                _doneTaskAmount += 1;
                                percentage       = ((float)_doneTaskAmount / _totalTaskCount) * 100f;
                                _progressReporter.ReportOperationProgress(percentage,
                                                                          String.Format(Program.FileRenamingOperationText,
                                                                                        Path.GetFileName(operation.Value),
                                                                                        operation.Value2));
                                break;
                            }
                            break;

                        case OperationArea.Registry:
                            switch (operation.Method)
                            {
                            case OperationMethod.Create:
                                secondValueAsArray = operation.Value2 as JArray;
                                if (secondValueAsArray != null)
                                {
                                    foreach (
                                        var registryKey in secondValueAsArray.ToObject <IEnumerable <string> >())
                                    {
                                        RegistryManager.CreateSubKey(operation.Value, registryKey);

                                        _doneTaskAmount += 1;
                                        percentage       = ((float)_doneTaskAmount / _totalTaskCount) * 100f;
                                        _progressReporter.ReportOperationProgress(percentage,
                                                                                  String.Format(Program.RegistrySubKeyCreateOperationText, registryKey));
                                    }
                                }
                                break;

                            case OperationMethod.Delete:
                                secondValueAsArray = operation.Value2 as JArray;
                                if (secondValueAsArray != null)
                                {
                                    foreach (
                                        var registryKey in secondValueAsArray.ToObject <IEnumerable <string> >())
                                    {
                                        RegistryManager.DeleteSubKey(operation.Value, registryKey);

                                        _doneTaskAmount += 1;
                                        percentage       = ((float)_doneTaskAmount / _totalTaskCount) * 100f;
                                        _progressReporter.ReportOperationProgress(percentage,
                                                                                  String.Format(Program.RegistrySubKeyDeleteOperationText, registryKey));
                                    }
                                }
                                break;

                            case OperationMethod.SetValue:
                                secondValueAsArray = operation.Value2 as JArray;
                                if (secondValueAsArray != null)
                                {
                                    foreach (
                                        var nameValuePair in
                                        secondValueAsArray
                                        .ToObject <IEnumerable <Tuple <string, object, RegistryValueKind> > >
                                            ())
                                    {
                                        RegistryManager.SetValue(operation.Value, nameValuePair.Item1,
                                                                 nameValuePair.Item2, nameValuePair.Item3);

                                        _doneTaskAmount += 1;
                                        percentage       = ((float)_doneTaskAmount / _totalTaskCount) * 100f;
                                        _progressReporter.ReportOperationProgress(percentage,
                                                                                  String.Format(Program.RegistryNameValuePairSetValueOperationText,
                                                                                                nameValuePair.Item1, nameValuePair.Item2));
                                    }
                                }
                                break;

                            case OperationMethod.DeleteValue:
                                secondValueAsArray = operation.Value2 as JArray;
                                if (secondValueAsArray != null)
                                {
                                    foreach (var valueName in secondValueAsArray.ToObject <IEnumerable <string> >()
                                             )
                                    {
                                        RegistryManager.DeleteValue(operation.Value, valueName);

                                        _doneTaskAmount += 1;
                                        percentage       = ((float)_doneTaskAmount / _totalTaskCount) * 100f;
                                        _progressReporter.ReportOperationProgress(percentage,
                                                                                  String.Format(Program.RegistryNameValuePairSetValueOperationText,
                                                                                                valueName));
                                    }
                                }
                                break;
                            }
                            break;

                        case OperationArea.Processes:
                            switch (operation.Method)
                            {
                            case OperationMethod.Start:
                                var processFilePathParts = operation.Value.Split('\\');
                                var processFileFullPath  =
                                    Path.Combine(Operation.GetDirectory(processFilePathParts[0]),
                                                 String.Join("\\",
                                                             processFilePathParts.Where(item => item != processFilePathParts[0])));

                                var process = new Process
                                {
                                    StartInfo =
                                    {
                                        FileName  = processFileFullPath,
                                        Arguments = operation.Value2.ToString()
                                    }
                                };
                                try
                                {
                                    process.Start();
                                }
                                catch (Win32Exception ex)
                                {
                                    if (ex.NativeErrorCode != 1223)
                                    {
                                        throw;
                                    }
                                }

                                _doneTaskAmount += 1;
                                percentage       = ((float)_doneTaskAmount / _totalTaskCount) * 100f;
                                _progressReporter.ReportOperationProgress(percentage,
                                                                          String.Format(Program.ProcessStartOperationText, operation.Value));
                                break;

                            case OperationMethod.Stop:
                                var processes = Process.GetProcessesByName(operation.Value);
                                foreach (var foundProcess in processes)
                                {
                                    foundProcess.Kill();
                                }

                                _doneTaskAmount += 1;
                                percentage       = ((float)_doneTaskAmount / _totalTaskCount) * 100f;
                                _progressReporter.ReportOperationProgress(percentage,
                                                                          String.Format(Program.ProcessStopOperationText, operation.Value));
                                break;
                            }
                            break;

                        case OperationArea.Services:
                            switch (operation.Method)
                            {
                            case OperationMethod.Start:
                                ServiceManager.StartService(operation.Value, (string[])operation.Value2);

                                _doneTaskAmount += 1;
                                percentage       = ((float)_doneTaskAmount / _totalTaskCount) * 100f;
                                _progressReporter.ReportOperationProgress(percentage,
                                                                          String.Format(Program.ServiceStartOperationText, operation.Value));
                                break;

                            case OperationMethod.Stop:
                                ServiceManager.StopService(operation.Value);

                                _doneTaskAmount += 1;
                                percentage       = ((float)_doneTaskAmount / _totalTaskCount) * 100f;
                                _progressReporter.ReportOperationProgress(percentage,
                                                                          String.Format(Program.ServiceStopOperationText, operation.Value));
                                break;
                            }
                            break;

                        case OperationArea.Scripts:
                            switch (operation.Method)
                            {
                            case OperationMethod.Execute:
                                var helper = new CodeDomHelper();
                                helper.ExecuteScript(operation.Value);
                                break;
                            }
                            break;
                        }
                    }
                }
                catch (Exception ex)
                {
                    _progressReporter.Fail(ex);
                    CleanUp();
                    _progressReporter.Terminate();
                    if (!Program.IsHostApplicationClosed)
                    {
                        return;
                    }

                    var process = new Process
                    {
                        StartInfo =
                        {
                            UseShellExecute = true,
                            FileName        = Program.ApplicationExecutablePath,
                            Arguments       =
                                String.Join("|",
                                            Program.Arguments.Where(
                                                item =>
                                                item.ExecutionOptions ==
                                                UpdateArgumentExecutionOptions.OnlyOnFaulted).Select(item => item.Argument))
                        }
                    };
                    process.Start();
                    return;
                }
            }

            CleanUp();
            if (Program.IsHostApplicationClosed)
            {
                var p = new Process
                {
                    StartInfo =
                    {
                        UseShellExecute = true,
                        FileName        = Program.ApplicationExecutablePath,
                        Arguments       =
                            String.Join("|",
                                        Program.Arguments.Where(
                                            item =>
                                            item.ExecutionOptions == UpdateArgumentExecutionOptions.OnlyOnSucceeded)
                                        .Select(item => item.Argument))
                    }
                };
                p.Start();
            }
            _progressReporter.Terminate();
        }