diff options
Diffstat (limited to 'Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels')
3 files changed, 183 insertions, 8 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MachineConnectionViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MachineConnectionViewVM.cs index 60447f37a..51b7168ed 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MachineConnectionViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MachineConnectionViewVM.cs @@ -4,8 +4,11 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.Core.Commands; +using Tango.Emulations.ExternalBridge; using Tango.Integration.ExternalBridge; +using Tango.MachineStudio.Common; using Tango.MachineStudio.Common.Notifications; +using Tango.Settings; using Tango.SharedUI; namespace Tango.MachineStudio.UI.ViewModels @@ -16,6 +19,8 @@ namespace Tango.MachineStudio.UI.ViewModels /// <seealso cref="Tango.MachineStudio.Common.Notifications.DialogViewVM" /> public class MachineConnectionViewVM : DialogViewVM { + private EmulatorExternalBridge _emulator; + private ExternalBridgeScanner _scanner; /// <summary> /// Gets or sets the machine scanner. @@ -63,6 +68,9 @@ namespace Tango.MachineStudio.UI.ViewModels } } + /// <summary> + /// Invokes the <see cref="E:Tango.SharedUI.DialogViewVM.Canceled" /> event. + /// </summary> protected override void Cancel() { Scanner.Stop(); @@ -76,6 +84,17 @@ namespace Tango.MachineStudio.UI.ViewModels { base.OnShow(); Scanner.AvailableMachines.Clear(); + + if (SettingsManager.Default.GetOrCreate<MachineStudioSettings>().UseExternalBridgeEmulator) + { + if (_emulator != null) + { + _emulator.Disconnect(); + } + _emulator = new EmulatorExternalBridge(); + } + + Scanner.AvailableMachines.Add(_emulator); Scanner.Start(); } } diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs index ee4435832..31b2181ea 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs @@ -388,7 +388,7 @@ namespace Tango.MachineStudio.UI.ViewModels InvalidateRelayCommands(); String serial = ApplicationManager.ConnectedMachine.SerialNumber; await ApplicationManager.ConnectedMachine.Disconnect(); - ApplicationManager.ConnectedMachine = null; + ApplicationManager.SetConnectedMachine(null); _eventLogger.Log("Disconnected from machine " + serial); PostMessage(new MachineConnectionChangedMessage() { Machine = null }); @@ -459,13 +459,13 @@ namespace Tango.MachineStudio.UI.ViewModels Intent = PMR.Integration.ExternalBridgeLoginIntent.Override, }); - ApplicationManager.ConnectedMachine = x.SelectedMachine; + ApplicationManager.SetConnectedMachine(x.SelectedMachine); (x.SelectedMachine as IExternalBridgeSecureClient).SessionClosed += (_, __) => { InvokeUI(() => { _notificationProvider.ShowError("The remote machine has closed the current session. Machine disconnected."); - ApplicationManager.ConnectedMachine = null; + ApplicationManager.SetConnectedMachine(null); }); }; PostMessage(new MachineConnectionChangedMessage() { Machine = x.SelectedMachine }); @@ -506,7 +506,7 @@ namespace Tango.MachineStudio.UI.ViewModels await x.SelectedMachine.Connect(); x.SelectedMachine.SerialNumber = vm.SelectedMachine.SerialNumber; - ApplicationManager.ConnectedMachine = x.SelectedMachine; + ApplicationManager.SetConnectedMachine(x.SelectedMachine); PostMessage(new MachineConnectionChangedMessage() { Machine = x.SelectedMachine }); _eventLogger.Log(String.Format("Successfully connected to machine {0} via USB", x.SelectedMachine.SerialNumber)); @@ -556,8 +556,8 @@ namespace Tango.MachineStudio.UI.ViewModels { using (ObservablesContext db = ObservablesContext.CreateDefault()) { - var config = db.Adapter.GetConfiguration(s => s.Guid == ApplicationManager.ConnectedMachine.Machine.ConfigurationGuid); - var hw = db.Adapter.GetHardwareVersionByMachine(ApplicationManager.ConnectedMachine.Machine.Guid); + var config = db.Adapter.GetConfiguration(s => s.Guid == ApplicationManager.Machine.ConfigurationGuid); + var hw = db.Adapter.GetHardwareVersionByMachine(ApplicationManager.Machine.Guid); await ApplicationManager.ConnectedMachine.UploadHardwareConfiguration(hw, config); } diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/UpdateViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/UpdateViewVM.cs index c5831f701..55f585626 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/UpdateViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/UpdateViewVM.cs @@ -35,6 +35,9 @@ namespace Tango.MachineStudio.UI.ViewModels Updating, UpdateCompleted, Error, + RollingBack, + RollbackCompleted, + RollbackError, } public class UpdateViewVM : ViewModel @@ -48,6 +51,7 @@ namespace Tango.MachineStudio.UI.ViewModels private IAuthenticationProvider _authentication; private CheckForUpdatesResponse _updateInfo; private TemporaryFolder _newPackageTempFolder; + private TemporaryFolder _previousPackageTempFolder; private bool _forcedUpdate; public bool ForcedUpdate @@ -88,6 +92,14 @@ namespace Tango.MachineStudio.UI.ViewModels set { _downloadProgress = value; RaisePropertyChangedAuto(); } } + private double _rollbackProgress; + + public double RollbackProgress + { + get { return _rollbackProgress; } + set { _rollbackProgress = value; RaisePropertyChangedAuto(); } + } + private double _updateProgress; public double UpdateProgress @@ -104,6 +116,14 @@ namespace Tango.MachineStudio.UI.ViewModels set { _currentUpdateFile = value; RaisePropertyChanged(nameof(CurrentUpdateFile)); } } + private bool _isRollbackAvailable; + + public bool IsRollbackAvailable + { + get { return _isRollbackAvailable; } + set { _isRollbackAvailable = value; RaisePropertyChangedAuto(); } + } + public RelayCommand UpdateCommand { get; set; } public RelayCommand BackCommand { get; set; } @@ -112,6 +132,10 @@ namespace Tango.MachineStudio.UI.ViewModels public RelayCommand TryAgainCommand { get; set; } + public RelayCommand RollbackCommand { get; set; } + + public RelayCommand TryRollbackAgainCommand { get; set; } + public UpdateViewVM(INotificationProvider notification, IAuthenticationProvider authentication, INavigationManager navigation, IStudioApplicationManager application) { _notification = notification; @@ -123,8 +147,12 @@ namespace Tango.MachineStudio.UI.ViewModels Status = UpdateStatus.CheckingForUpdate; UpdateCommand = new RelayCommand(StartUpdate, () => Status == UpdateStatus.UpdateAvailable); BackCommand = new RelayCommand(BackToApplication, () => Status != UpdateStatus.Updating && !ForcedUpdate); - RestartCommand = new RelayCommand(RestartApplication, () => Status == UpdateStatus.UpdateCompleted); + RestartCommand = new RelayCommand(RestartApplication, () => Status == UpdateStatus.UpdateCompleted || Status == UpdateStatus.RollbackCompleted); TryAgainCommand = new RelayCommand(TryAgain, () => Status == UpdateStatus.Error); + RollbackCommand = new RelayCommand(Rollback, () => Status != UpdateStatus.RollingBack && !ForcedUpdate); + TryRollbackAgainCommand = new RelayCommand(TryRollbackAgain, () => Status == UpdateStatus.RollbackError); + + IsRollbackAvailable = File.Exists(GetRollbackFile()); TangoMessenger.Default.Register<Messages.ForcedUpdateMessage>(HandleForcedUpdateMessage); } @@ -294,6 +322,41 @@ namespace Tango.MachineStudio.UI.ViewModels } } + try + { + LogManager.Log("Backing up current version..."); + CurrentUpdateFile = "Backing up current version..."; + + String rollbackFolder = GetRollbackFolder(); + Directory.CreateDirectory(rollbackFolder); + + String backFile = GetRollbackFile(); + + if (File.Exists(backFile)) + { + File.Delete(backFile); + } + + using (ZipFile backZip = new ZipFile(backFile)) + { + int currentEntry = 0; + + backZip.SaveProgress += (_, e) => + { + UpdateProgress = ((double)(currentEntry++) / (double)backZip.Entries.Count) * 100d; + }; + + backZip.Password = "Aa123456"; + backZip.AddDirectory(_appPath); + backZip.Save(); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Could not construct rollback."); + _notification.ShowWarning("Update center has failed to construct a rollback point for the current version. Version rollback will not be available."); + } + TangoIOC.Default.GetInstance<MainViewVM>().DisableCheckForUpdates = true; Status = UpdateStatus.UpdateCompleted; } @@ -319,7 +382,16 @@ namespace Tango.MachineStudio.UI.ViewModels try { Process p = new Process(); - p.StartInfo.FileName = _newPackageTempFolder + "\\Tango.MachineStudio.Updater.exe"; + + if (Status == UpdateStatus.UpdateCompleted) + { + p.StartInfo.FileName = _newPackageTempFolder + "\\Tango.MachineStudio.Updater.exe"; + } + else if (Status == UpdateStatus.RollbackCompleted) + { + p.StartInfo.FileName = _previousPackageTempFolder + "\\Tango.MachineStudio.Updater.exe"; + } + p.StartInfo.UseShellExecute = true; p.StartInfo.Arguments = _appPath; p.Start(); @@ -335,6 +407,90 @@ namespace Tango.MachineStudio.UI.ViewModels Environment.Exit(0); } + private void Rollback() + { + if (_notification.ShowQuestion("Are you sure you want to restore the previous version?")) + { + Status = UpdateStatus.RollingBack; + + try + { + Task.Factory.StartNew(() => + { + _previousPackageTempFolder = TemporaryManager.CreateFolder(); + _previousPackageTempFolder.Persist = true; + + using (ZipFile zip = new ZipFile(GetRollbackFile())) + { + zip.Password = "Aa123456"; + + int currentEntry = 0; + + zip.ExtractProgress += (x, args) => + { + if (args.EventType == ZipProgressEventType.Extracting_AfterExtractEntry) + { + logManager.Log("Extracting " + Path.GetFileName(args.CurrentEntry.FileName)); + RollbackProgress = ((double)(currentEntry++) / (double)zip.Entries.Count) * 100d; + } + }; + + foreach (ZipEntry entry in zip) + { + Thread.Sleep(10); + + string newPath = Path.Combine(_previousPackageTempFolder.Path, entry.FileName); + + try + { + if (entry.IsDirectory) + { + Directory.CreateDirectory(newPath); + } + else + { + entry.Extract(_previousPackageTempFolder.Path, ExtractExistingFileAction.OverwriteSilently); + } + } + catch + { + logManager.Log("Could not extract file " + entry.FileName); + } + } + + } + + File.Delete(GetRollbackFile()); + + Status = UpdateStatus.RollbackCompleted; + }); + } + catch (Exception ex) + { + Status = UpdateStatus.Error; + LogManager.Log(ex, "Error while trying to restore version."); + _notification.ShowError("An error occurred while trying to restore the previous version."); + } + } + } + + private void TryRollbackAgain() + { + CheckForUpdates(); + } + + private String GetRollbackFolder() + { + String rollbackFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Twine", "Tango", "Rollback"); + return rollbackFolder; + } + + private String GetRollbackFile() + { + String backFile = Path.Combine(GetRollbackFolder(), Path.GetFileNameWithoutExtension(AppDomain.CurrentDomain.FriendlyName) + ".rollback"); + return backFile; + } + protected override void RaisePropertyChangedAuto([CallerMemberName] string caller = null) { base.RaisePropertyChangedAuto(caller); |
