void m_form_Finished(object sender, System.ComponentModel.CancelEventArgs e) { Wizard_pages.WizardSettingsWrapper wrapper = new Duplicati.GUI.Wizard_pages.WizardSettingsWrapper(m_form.Settings); if (wrapper.PrimayAction == Duplicati.GUI.Wizard_pages.WizardSettingsWrapper.MainAction.Add || wrapper.PrimayAction == Duplicati.GUI.Wizard_pages.WizardSettingsWrapper.MainAction.Edit) { bool scheduleRun = wrapper.RunImmediately; bool autoScheduled = (wrapper.BackupTimeOffset < DateTime.Now) && !string.IsNullOrEmpty(wrapper.RepeatInterval); //Resume Duplicati if the backup is supposed to run if (scheduleRun || autoScheduled) { if (!AskToResumeIfPaused()) { e.Cancel = true; return; } } Schedule schedule; IDataFetcherWithRelations con = new DataFetcherNested(Program.DataConnection); if (wrapper.PrimayAction == Duplicati.GUI.Wizard_pages.WizardSettingsWrapper.MainAction.Add) schedule = con.Add<Schedule>(); else schedule = con.GetObjectById<Schedule>(wrapper.ScheduleID); wrapper.UpdateSchedule(schedule); lock (Program.MainLock) con.CommitAllRecursive(); schedule = Program.DataConnection.GetObjectById<Schedule>(schedule.ID); if (wrapper.UseEncryptionAsDefault) { ApplicationSettings appset = new ApplicationSettings(Program.DataConnection); appset.UseCommonPassword = true; appset.CommonPassword = wrapper.BackupPassword; appset.CommonPasswordEncryptionModule = wrapper.EncryptionModule; Program.DataConnection.Commit(Program.DataConnection.GetObjects<ApplicationSetting>()); } //If the user has selected that the backup should run now // and it is not run automatically, start it now if (scheduleRun && !autoScheduled) Program.WorkThread.AddTask(new IncrementalBackupTask(schedule)); } else if (m_form.CurrentPage is Wizard_pages.Restore.FinishedRestore) { if (!AskToResumeIfPaused()) { e.Cancel = true; return; } Schedule schedule = wrapper.DataConnection.GetObjectById<Schedule>(wrapper.ScheduleID); DateTime when = wrapper.RestoreTime; string target = wrapper.FullRestorePath; string restoreFilter = wrapper.RestoreFilter; if (when.Ticks == 0) Program.WorkThread.AddTask(new RestoreTask(schedule, target, restoreFilter)); else Program.WorkThread.AddTask(new RestoreTask(schedule, target, restoreFilter, when)); Program.DisplayHelper.ShowStatus(); } else if (m_form.CurrentPage is Wizard_pages.RunNow.RunNowFinished) { if (!AskToResumeIfPaused()) { e.Cancel = true; return; } Schedule schedule = wrapper.DataConnection.GetObjectById<Schedule>(wrapper.ScheduleID); if (wrapper.ForceFull) Program.WorkThread.AddTask(new FullBackupTask(schedule)); else Program.WorkThread.AddTask(new IncrementalBackupTask(schedule)); } else if (m_form.CurrentPage is Wizard_pages.Delete_backup.DeleteFinished) { Schedule schedule = wrapper.DataConnection.GetObjectById<Schedule>(wrapper.ScheduleID); if (Program.WorkThread.Active) { try { //TODO: It's not safe to access the values like this, //because the runner thread might interfere if (Program.WorkThread.CurrentTask.Schedule.ID == schedule.ID) { bool paused = Program.LiveControl.State == LiveControls.LiveControlState.Paused; Program.LiveControl.Pause(); if (MessageBox.Show(m_form.Dialog, Strings.WizardHandler.StopRunningBackupQuestion, Application.ProductName, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) != DialogResult.Yes) { e.Cancel = true; if (!paused) Program.LiveControl.Resume(); return; } bool repaused = Program.LiveControl.State == LiveControls.LiveControlState.Paused; Program.LiveControl.Pause(); if (Program.WorkThread.CurrentTask.Schedule.ID == schedule.ID) Program.Runner.Terminate(); Cursor prevCursor = m_form.Dialog.Cursor; try { m_form.Dialog.Cursor = Cursors.WaitCursor; for (int i = 0; i < 10; i++) if (Program.WorkThread.Active) { IDuplicityTask t = Program.WorkThread.CurrentTask; if (t != null && t.Schedule.ID == schedule.ID) System.Threading.Thread.Sleep(1000); else break; } else break; } finally { try { m_form.Dialog.Cursor = prevCursor; } catch { } } if (Program.WorkThread.Active) { IDuplicityTask t = Program.WorkThread.CurrentTask; if (t == null && t.Schedule.ID == schedule.ID) { MessageBox.Show(m_form.Dialog, Strings.WizardHandler.UnableToStopBackupError, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); e.Cancel = true; return; } } if (!paused || !repaused) Program.LiveControl.Resume(); } } catch(Exception ex) { MessageBox.Show(m_form.Dialog, string.Format(Strings.WizardHandler.StopBackupError, ex.Message), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); e.Cancel = true; return; } } //Prior to deleting we need to make sure all relations are loaded Queue<object> unvisited = new Queue<object>(); Dictionary<object, object> visited = new Dictionary<object, object>(); //Set up a transaction we can safely work on System.Data.LightDatamodel.DataFetcherNested con = new DataFetcherNested(Program.DataConnection); //Load the schedule in the transaction context object entryItem = con.GetObjectById<Schedule>(schedule.ID); unvisited.Enqueue(entryItem); visited[entryItem] = null; //Traverse the object relations while (unvisited.Count > 0) { object x = unvisited.Dequeue(); foreach (System.Reflection.PropertyInfo pi in x.GetType().GetProperties()) { if (pi.PropertyType != typeof(string) && (typeof(System.Data.LightDatamodel.IDataClass).IsAssignableFrom(pi.PropertyType) || typeof(System.Collections.IEnumerable).IsAssignableFrom(pi.PropertyType))) try { object tmp = pi.GetValue(x, null); foreach(object i in tmp as System.Collections.IEnumerable ?? new object[] { tmp }) if (i as IDataClass != null && !visited.ContainsKey(i)) { visited[i] = null; unvisited.Enqueue(i); } } catch { //TODO: Perhaps log this? } } } //Remove all entries visited foreach(IDataClass o in visited.Keys) con.DeleteObject(o); //TODO: The worker may schedule the task while we attempt to de-schedule it foreach (IDuplicityTask t in Program.WorkThread.CurrentTasks) if (t != null && t is IncrementalBackupTask && ((IncrementalBackupTask)t).Schedule.ID == schedule.ID) Program.WorkThread.RemoveTask(t); //Persist to database con.CommitAllRecursive(); //We have fiddled with the schedules Program.Scheduler.Reschedule(); } else if (m_form.CurrentPage is Wizard_pages.RestoreSetup.FinishedRestoreSetup) { MessageBox.Show(m_form as Form, Strings.WizardHandler.SetupRestoreSuccess, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information); } }
void m_form_Finished(object sender, System.ComponentModel.CancelEventArgs e) { Wizard_pages.WizardSettingsWrapper wrapper = new Duplicati.GUI.Wizard_pages.WizardSettingsWrapper(m_form.Settings); if (wrapper.PrimayAction == Duplicati.GUI.Wizard_pages.WizardSettingsWrapper.MainAction.Add || wrapper.PrimayAction == Duplicati.GUI.Wizard_pages.WizardSettingsWrapper.MainAction.Edit) { bool scheduleRun = wrapper.RunImmediately; bool autoScheduled = (wrapper.BackupTimeOffset < DateTime.Now) && !string.IsNullOrEmpty(wrapper.RepeatInterval); //Resume Duplicati if the backup is supposed to run if (scheduleRun || autoScheduled) { if (!AskToResumeIfPaused()) { e.Cancel = true; return; } } Schedule schedule; IDataFetcherWithRelations con = new DataFetcherNested(Program.DataConnection); if (wrapper.PrimayAction == Duplicati.GUI.Wizard_pages.WizardSettingsWrapper.MainAction.Add) { schedule = con.Add <Schedule>(); } else { schedule = con.GetObjectById <Schedule>(wrapper.ScheduleID); } wrapper.UpdateSchedule(schedule); lock (Program.MainLock) con.CommitAllRecursive(); schedule = Program.DataConnection.GetObjectById <Schedule>(schedule.ID); if (wrapper.UseEncryptionAsDefault) { ApplicationSettings appset = new ApplicationSettings(Program.DataConnection); appset.UseCommonPassword = true; appset.CommonPassword = wrapper.BackupPassword; appset.CommonPasswordEncryptionModule = wrapper.EncryptionModule; Program.DataConnection.Commit(Program.DataConnection.GetObjects <ApplicationSetting>()); } //If the user has selected that the backup should run now // and it is not run automatically, start it now if (scheduleRun && !autoScheduled) { Program.WorkThread.AddTask(new IncrementalBackupTask(schedule)); } } else if (m_form.CurrentPage is Wizard_pages.Restore.FinishedRestore) { if (!AskToResumeIfPaused()) { e.Cancel = true; return; } Schedule schedule = wrapper.DataConnection.GetObjectById <Schedule>(wrapper.ScheduleID); DateTime when = wrapper.RestoreTime; string target = wrapper.FullRestorePath; string restoreFilter = wrapper.RestoreFilter; if (when.Ticks == 0) { Program.WorkThread.AddTask(new RestoreTask(schedule, target, restoreFilter)); } else { Program.WorkThread.AddTask(new RestoreTask(schedule, target, restoreFilter, when)); } Program.DisplayHelper.ShowStatus(); } else if (m_form.CurrentPage is Wizard_pages.RunNow.RunNowFinished) { if (!AskToResumeIfPaused()) { e.Cancel = true; return; } Schedule schedule = wrapper.DataConnection.GetObjectById <Schedule>(wrapper.ScheduleID); if (wrapper.ForceFull) { Program.WorkThread.AddTask(new FullBackupTask(schedule)); } else { Program.WorkThread.AddTask(new IncrementalBackupTask(schedule)); } } else if (m_form.CurrentPage is Wizard_pages.Delete_backup.DeleteFinished) { Schedule schedule = wrapper.DataConnection.GetObjectById <Schedule>(wrapper.ScheduleID); if (Program.WorkThread.Active) { try { //TODO: It's not safe to access the values like this, //because the runner thread might interfere if (Program.WorkThread.CurrentTask.Schedule.ID == schedule.ID) { bool paused = Program.LiveControl.State == LiveControls.LiveControlState.Paused; Program.LiveControl.Pause(); if (MessageBox.Show(m_form.Dialog, Strings.WizardHandler.StopRunningBackupQuestion, Application.ProductName, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) != DialogResult.Yes) { e.Cancel = true; if (!paused) { Program.LiveControl.Resume(); } return; } bool repaused = Program.LiveControl.State == LiveControls.LiveControlState.Paused; Program.LiveControl.Pause(); if (Program.WorkThread.CurrentTask.Schedule.ID == schedule.ID) { Program.Runner.Terminate(); } Cursor prevCursor = m_form.Dialog.Cursor; try { m_form.Dialog.Cursor = Cursors.WaitCursor; for (int i = 0; i < 10; i++) { if (Program.WorkThread.Active) { IDuplicityTask t = Program.WorkThread.CurrentTask; if (t != null && t.Schedule.ID == schedule.ID) { System.Threading.Thread.Sleep(1000); } else { break; } } else { break; } } } finally { try { m_form.Dialog.Cursor = prevCursor; } catch { } } if (Program.WorkThread.Active) { IDuplicityTask t = Program.WorkThread.CurrentTask; if (t == null && t.Schedule.ID == schedule.ID) { MessageBox.Show(m_form.Dialog, Strings.WizardHandler.UnableToStopBackupError, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); e.Cancel = true; return; } } if (!paused || !repaused) { Program.LiveControl.Resume(); } } } catch (Exception ex) { MessageBox.Show(m_form.Dialog, string.Format(Strings.WizardHandler.StopBackupError, ex.Message), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); e.Cancel = true; return; } } //Prior to deleting we need to make sure all relations are loaded Queue <object> unvisited = new Queue <object>(); Dictionary <object, object> visited = new Dictionary <object, object>(); //Set up a transaction we can safely work on System.Data.LightDatamodel.DataFetcherNested con = new DataFetcherNested(Program.DataConnection); //Load the schedule in the transaction context object entryItem = con.GetObjectById <Schedule>(schedule.ID); unvisited.Enqueue(entryItem); visited[entryItem] = null; //Traverse the object relations while (unvisited.Count > 0) { object x = unvisited.Dequeue(); foreach (System.Reflection.PropertyInfo pi in x.GetType().GetProperties()) { if (pi.PropertyType != typeof(string) && (typeof(System.Data.LightDatamodel.IDataClass).IsAssignableFrom(pi.PropertyType) || typeof(System.Collections.IEnumerable).IsAssignableFrom(pi.PropertyType))) { try { object tmp = pi.GetValue(x, null); foreach (object i in tmp as System.Collections.IEnumerable ?? new object[] { tmp }) { if (i as IDataClass != null && !visited.ContainsKey(i)) { visited[i] = null; unvisited.Enqueue(i); } } } catch { //TODO: Perhaps log this? } } } } //Remove all entries visited foreach (IDataClass o in visited.Keys) { con.DeleteObject(o); } //TODO: The worker may schedule the task while we attempt to de-schedule it foreach (IDuplicityTask t in Program.WorkThread.CurrentTasks) { if (t != null && t is IncrementalBackupTask && ((IncrementalBackupTask)t).Schedule.ID == schedule.ID) { Program.WorkThread.RemoveTask(t); } } //Persist to database con.CommitAllRecursive(); //We have fiddled with the schedules Program.Scheduler.Reschedule(); } else if (m_form.CurrentPage is Wizard_pages.RestoreSetup.FinishedRestoreSetup) { MessageBox.Show(m_form as Form, Strings.WizardHandler.SetupRestoreSuccess, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information); } }