public void ApplyUpdate(AppInfo appInfo, UpdateInfo info, UpdateHost updateInfoSource) { string lockFile = InstallationSettings.InstallationFolder + "/Updater.lock"; if (File.Exists(lockFile)) { throw new Exception("Could not update: the application folder is already locked by another updater instance."); } else { File.Create(lockFile).Close(); } TriggerProgressEvent(0, "Calculating updater tasks"); FileIndex index = FileIndex.Deserialize(InstallationSettings.InstallationFolder + "/UpdateIndex.dat"); UpdateTask[] tasks = GetUpdaterTasks(appInfo, info, updateInfoSource, index); List <UpdateTask> failedTasks = RunTasks(tasks, true, 10); TriggerProgressEvent(percentageDone, "Retrying failed tasks"); for (int i = 0; i < failedTasks.Count; i++) { UpdateTask task = failedTasks[i]; try { task.Run(); } catch (WebException ex) { if (MessageBox.Show("Updater could not download file: " + ex.Message + "\r\n(" + ex.Data["Target"] + ")", "Failed to download file", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error).Equals(DialogResult.Retry)) { i--; //Retry } else { Application.Exit(); } } catch (UnauthorizedAccessException ex) { if (MessageBox.Show("Updater could access file or folder: " + ex.Message + "\r\n(" + ex.Data["Target"] + ")", "Failed to download file", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error).Equals(DialogResult.Retry)) { i--; //Retry } else { Application.Exit(); } } } TriggerProgressEvent(98, "Updating local file index"); index = new FileIndex(index.appID); index.applicationVersion = info.version; index.files.AddRange(info.fileChecksums.Keys); index.Serialize(InstallationSettings.InstallationFolder + "/UpdateIndex.dat"); File.Delete(lockFile); }
public async Task Run_ReturnsNoContentOnSuccess() { var handler = new Mock <ICommandHander <UpdateTaskCommand> >(); var container = new Container(); var task = new TaskDTO(); var listId = Guid.NewGuid().ToString(); var taskId = Guid.NewGuid().ToString(); handler.Setup(h => h.Execute(It.IsAny <UpdateTaskCommand>())).Returns(Task.CompletedTask); container.RegisterInstance(handler.Object); container.RegisterInstance(_telemetryClient); UpdateTask.Container = container; var result = await UpdateTask.Run(task, listId, taskId) as NoContentResult; Assert.IsNotNull(result); }
public async Task Run_ReturnsServerErrorOnServerError() { var handler = new Mock <ICommandHander <UpdateTaskCommand> >(); var container = new Container(); var task = new TaskDTO(); var listId = Guid.NewGuid().ToString(); var taskId = Guid.NewGuid().ToString(); handler.Setup(h => h.Execute(It.IsAny <UpdateTaskCommand>())) .ThrowsAsync(new Exception()); container.RegisterInstance(handler.Object); container.RegisterInstance(_telemetryClient); UpdateTask.Container = container; var result = await UpdateTask.Run(task, listId, taskId) as InternalServerErrorResult; Assert.IsNotNull(result); }
private List <UpdateTask> RunTasks(UpdateTask[] tasks, bool multithreadedTaskRunning, int maxParallelTasks) { List <UpdateTask> failedTasks = new List <UpdateTask>(); List <string> filesToDelete = new List <string>(); using (ManualResetEvent resetEvent = new ManualResetEvent(false)) { int tasksToRun = tasks.Length; int tasksActive = 0; for (int i = 0; i < tasks.Length; i++) { UpdateTask curTask = tasks[i]; if (multithreadedTaskRunning) { if (tasksActive == maxParallelTasks) { Thread.Sleep(10); i--; continue; } bool queued = false; while (!queued) { queued = ThreadPool.QueueUserWorkItem( new WaitCallback( task => { try { int tasksDone = tasks.Length - tasksToRun; percentageDone = Convert.ToInt32(((double)(tasksDone - failedTasks.Count) / (double)tasks.Length) * 100d); TriggerProgressEvent(percentageDone, curTask.ToString()); ((UpdateTask)task).Run(); } catch (Exception) { failedTasks.Add(curTask); } finally { if (Interlocked.Decrement(ref tasksToRun) == 0) { resetEvent.Set(); } Interlocked.Decrement(ref tasksActive); filesToDelete.AddRange(((UpdateTask)curTask).filesToDeleteOnExit); } } ), curTask ); if (!queued) { Thread.Sleep(10); } else { Interlocked.Increment(ref tasksActive); } } } else { percentageDone = Convert.ToInt32(((double)(i - failedTasks.Count) / (double)tasks.Length) * 100d); TriggerProgressEvent(percentageDone, curTask.ToString()); try { curTask.Run(); } catch (Exception ex) { failedTasks.Add(curTask); } finally { filesToDelete.AddRange(((UpdateTask)curTask).filesToDeleteOnExit); resetEvent.Set(); } } } resetEvent.WaitOne(); foreach (string curFile in filesToDelete) { try { File.Delete(curFile); }catch (Exception) { Console.WriteLine("Failed to delete " + curFile); } } } return(failedTasks); }