예제 #1
0
        public UpdateResult ExecuteUpdate(UpdateEntry UpdateEntry)
        {
            //1 - Rodar linha de comando antes da atualização
            //2 - Fazer backup do diretório antigo com prefixo da versão
            //3 - Criar novo diretório
            //4 - Descompactar os arquivos
            //5 - Valida os arquivos e diretórios que devem permanecer e faço a copia para o novo diretório após a atualização
            //6 - Rodar linha de comano pós update
            //7 - Validando a versão após a atualização para verificar se está correta.

            var updateResultReturn = new UpdateResult()
            {
                IsSuccess           = false,
                ID                  = Guid.NewGuid(),
                UpdateInstructionID = UpdateEntry.UpdateInstruction.ID
            };
            Stopwatch stopWatchTimer = Stopwatch.StartNew();

            try
            {
                updateResultReturn.AddMessage("Starting the update process", UpdateResultMessage.eMessageType.INFORMATION);
                var comandLineBeforeResult = Shell.ExecuteTerminalCommand(UpdateEntry.UpdateInstruction.GetCommandLineBeforeUpdateWithReplacedParams());
                if (comandLineBeforeResult.code > 0)
                {
                    throw new Exception($"Cannot run Commandline before update, see details.\r\nStdOut: {comandLineBeforeResult.stdout} \r\nStdErr: {comandLineBeforeResult.stderr}");
                }

                updateResultReturn.AddMessage($"Command line 'CommandLineBeforeUpdate' executed.\r\nOutput code: {comandLineBeforeResult.code}\r\nStdOut: {comandLineBeforeResult.stdout} \r\nStdErr: {comandLineBeforeResult.stderr}", UpdateResultMessage.eMessageType.SUCCESS);

                //Executando backup da pasta atual
                string workingFolderBackup = this.GenerateBackupFolderFullPathName(UpdateEntry.UpdateInstruction.ID, updateResultReturn.ID, UpdateEntry.UpdateInstruction.WorkingDirectory, UpdateEntry.CurrentVersion);
                //string BackupSufix = $"{ DateTime.Now.ToString("yyyy-dd-M_HH-mm-ss") }_{ UpdateEntry.CurrentVersion}";
                //string workingFolderBackup = $"{UpdateEntry.UpdateInstruction.WorkingDirectory}_{BackupSufix}";
                bool backupDone = DirectoryManager.RenameDirectory(UpdateEntry.UpdateInstruction.WorkingDirectory, workingFolderBackup);
                if (!backupDone)
                {
                    throw new Exception($"Cannot create backup folder.");
                }
                updateResultReturn.AddMessage($"Backup the current version was succeeded. Folder created is {workingFolderBackup}", UpdateResultMessage.eMessageType.SUCCESS);

                // Criando diretório após mover o anterior
                Directory.CreateDirectory(UpdateEntry.UpdateInstruction.WorkingDirectory);
                updateResultReturn.AddMessage($"Creation of new folder for update was succeeded. Folder created is {UpdateEntry.UpdateInstruction.WorkingDirectory}", UpdateResultMessage.eMessageType.SUCCESS);

                //Descompactando os arquivos para a pasta nova
                string ZipUpdateFilePathOrUrl = UpdateEntry.PathOrURLToFileUpdate;
                bool   decompressed           = ZipFileManger.Decompress(ZipUpdateFilePathOrUrl, UpdateEntry.UpdateInstruction.WorkingDirectory);
                if (!decompressed)
                {
                    throw new Exception($"Cannot decompress file '{ZipUpdateFilePathOrUrl}' into folder '{UpdateEntry.UpdateInstruction.WorkingDirectory}'");
                }
                updateResultReturn.AddMessage($"Unzip update file was succeeded. Update file of path is {ZipUpdateFilePathOrUrl}, its decompressed at folder {UpdateEntry.UpdateInstruction.WorkingDirectory}", UpdateResultMessage.eMessageType.SUCCESS);

                //Valida os arquivos e diretórios que devem permanecer e faço a copia para o novo diretório após a atualização
                updateResultReturn.AddMessage($"Preparing to start copy of 'FilesAndPathToKeep'. The number of files and path to keep is {UpdateEntry.FilesAndPathToKeep.Length}", UpdateResultMessage.eMessageType.INFORMATION);
                foreach (var FileOrFolder in UpdateEntry.FilesAndPathToKeep)
                {
                    string SourcelFile     = Path.Combine($"{workingFolderBackup}", $"{FileOrFolder}");
                    string DestinationFile = Path.Combine($"{UpdateEntry.UpdateInstruction.WorkingDirectory}", $"{FileOrFolder}");

                    try
                    {
                        bool copyResult = DirectoryManager.CopyFilesOrFolder(SourcelFile, DestinationFile);
                        updateResultReturn.AddMessage($"File/Folder copy from '{SourcelFile}' to '{DestinationFile}' " + (copyResult ? " succeeded" : " does not succeeded"),
                                                      copyResult ? UpdateResultMessage.eMessageType.SUCCESS : UpdateResultMessage.eMessageType.ERROR);
                    }
                    catch (Exception ex)
                    {
                        updateResultReturn.AddMessage($"File/Folder copy from '{SourcelFile}' to '{DestinationFile}' error.\r\nDetalis: " + ex.ToString(), UpdateResultMessage.eMessageType.ERROR);
                    }
                }


                var comandLineAfterResult = Shell.ExecuteTerminalCommand(UpdateEntry.UpdateInstruction.GetCommandLineAfterUpdateWithReplacedParams());
                if (comandLineAfterResult.code > 0)
                {
                    throw new Exception($"Cannot run Commandline after update, see details.\r\nStdOut: {comandLineAfterResult.stdout} \r\nStdErr: {comandLineAfterResult.stderr}");
                }

                updateResultReturn.AddMessage($"Command line 'CommandLineBeforeUpdate' executed.\r\nOutput code: {comandLineAfterResult.code}\r\nStdOut:{comandLineAfterResult.stdout} \r\nStdErr: {comandLineAfterResult.stderr}", UpdateResultMessage.eMessageType.SUCCESS);

                //Validando a versão após todo o processo para garantir que a versão está correta.
                if (UpdateEntry.UpdateInstruction.CheckVersionAfterUpdate)
                {
                    System.Version CurrentVersion = AssemblyManager.GetAssemblyVersion(UpdateEntry.UpdateInstruction.MainAssembly);
                    bool           IsNewerVersion = AssemblyManager.IsNewerVersion(CurrentVersion, UpdateEntry.NewVersion);
                    if (UpdateEntry.NewVersion != CurrentVersion)
                    {
                        throw new Exception($"Version validation  after update does not pass. Expected version is '{ UpdateEntry.NewVersion }' but found '{CurrentVersion}'");
                    }
                    updateResultReturn.AddMessage($"Version validation after update passed", UpdateResultMessage.eMessageType.SUCCESS);
                }
                else
                {
                    updateResultReturn.AddMessage($"Version validation is not executed. CheckVersionAfterUpdate is false", UpdateResultMessage.eMessageType.INFORMATION);
                }


                updateResultReturn.IsSuccess = true;

                stopWatchTimer.Stop();
                updateResultReturn.TimeSpentMilliseconds = stopWatchTimer.ElapsedMilliseconds;

                string alepsedTime = string.Format("{0:D2}h:{1:D2}m:{2:D2}s:{3:D3}ms",
                                                   stopWatchTimer.Elapsed.Hours,
                                                   stopWatchTimer.Elapsed.Minutes,
                                                   stopWatchTimer.Elapsed.Seconds,
                                                   stopWatchTimer.Elapsed.Milliseconds);


                updateResultReturn
                .AddMessage($"Updated '{UpdateEntry.UpdateInstruction.Name}' from '{UpdateEntry.CurrentVersion}' to '{UpdateEntry.NewVersion}'. Alepsed time: {this.ConvertMillisecondsToTimeString(updateResultReturn.TimeSpentMilliseconds)}",
                            updateResultReturn.IsSuccess ?
                            (updateResultReturn.Messages.Where(x => x.Type == UpdateResultMessage.eMessageType.ERROR).Count() <= 0 ? UpdateResultMessage.eMessageType.SUCCESS : UpdateResultMessage.eMessageType.WARNING) : UpdateResultMessage.eMessageType.ERROR);
            }
            catch (Exception ex)
            {
                stopWatchTimer.Stop();
                updateResultReturn.TimeSpentMilliseconds = stopWatchTimer.ElapsedMilliseconds;

                updateResultReturn
                .AddMessage($"Error updating '{UpdateEntry.UpdateInstruction.Name}' from '{UpdateEntry.CurrentVersion}' to '{UpdateEntry.NewVersion}' see details.\r\nDetails: " + ex.ToString(), UpdateResultMessage.eMessageType.ERROR);
                updateResultReturn.IsSuccess = false;
            }
            finally
            {
                this._UpdateRepository.WriteUpdateInstructionResult(updateResultReturn);
            }


            return(updateResultReturn);
        }