diff options
41 files changed, 2028 insertions, 57 deletions
diff --git a/Software/DB/Tango.mdf b/Software/DB/Tango.mdf Binary files differindex 9d864e6a7..3e25b6208 100644 --- a/Software/DB/Tango.mdf +++ b/Software/DB/Tango.mdf diff --git a/Software/DB/Tango_log.ldf b/Software/DB/Tango_log.ldf Binary files differindex 1e080784d..a4d8c33d4 100644 --- a/Software/DB/Tango_log.ldf +++ b/Software/DB/Tango_log.ldf diff --git a/Software/Graphics/machine-update.png b/Software/Graphics/machine-update.png Binary files differnew file mode 100644 index 000000000..3e49520dd --- /dev/null +++ b/Software/Graphics/machine-update.png diff --git a/Software/PMR/Messages/Synchronization/CheckForUpdateRequest.proto b/Software/PMR/Messages/Synchronization/CheckForUpdateRequest.proto new file mode 100644 index 000000000..4b1da8764 --- /dev/null +++ b/Software/PMR/Messages/Synchronization/CheckForUpdateRequest.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +package Tango.PMR.Synchronization; +option java_package = "com.twine.tango.pmr.synchronization"; + +message CheckForUpdateRequest +{ + string SerialNumber = 1; + string Version = 2; +}
\ No newline at end of file diff --git a/Software/PMR/Messages/Synchronization/CheckForUpdateResponse.proto b/Software/PMR/Messages/Synchronization/CheckForUpdateResponse.proto new file mode 100644 index 000000000..30e2b6fbb --- /dev/null +++ b/Software/PMR/Messages/Synchronization/CheckForUpdateResponse.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +package Tango.PMR.Synchronization; +option java_package = "com.twine.tango.pmr.synchronization"; + +message CheckForUpdateResponse +{ + bool IsUpdateAvailable = 1; + string Version = 2; +}
\ No newline at end of file diff --git a/Software/PMR/Messages/Synchronization/DownloadUpdateRequest.proto b/Software/PMR/Messages/Synchronization/DownloadUpdateRequest.proto new file mode 100644 index 000000000..98b302f85 --- /dev/null +++ b/Software/PMR/Messages/Synchronization/DownloadUpdateRequest.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +package Tango.PMR.Synchronization; +option java_package = "com.twine.tango.pmr.synchronization"; + +message DownloadUpdateRequest +{ + string SerialNumber = 1; +}
\ No newline at end of file diff --git a/Software/PMR/Messages/Synchronization/DownloadUpdateResponse.proto b/Software/PMR/Messages/Synchronization/DownloadUpdateResponse.proto new file mode 100644 index 000000000..db70e7d92 --- /dev/null +++ b/Software/PMR/Messages/Synchronization/DownloadUpdateResponse.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +package Tango.PMR.Synchronization; +option java_package = "com.twine.tango.pmr.synchronization"; + +message DownloadUpdateResponse +{ + string Version = 1; + + string FtpAddress = 2; + string FtpFilePath = 3; + string FtpUserName = 4; + string FtpPassword = 5; + + string DbAddress = 6; + string DbUserName = 7; + string DbPassword = 8; +}
\ No newline at end of file diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupManager.cs index 8d4d5fa0a..252491669 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupManager.cs @@ -196,8 +196,8 @@ namespace Tango.PPC.Common.MachineSetup LogManager.Log($"Initializing {nameof(ExaminerSequenceConfigurationRunner)}..."); ExaminerSequenceConfigurationRunner runner = new ExaminerSequenceConfigurationRunner( - Path.Combine(_newPackageTempFolder, "Synchronization Scripts", "config.xml"), - Path.Combine(_newPackageTempFolder, "Synchronization Scripts"), + Path.Combine(_newPackageTempFolder, "Provision Scripts", "config.xml"), + Path.Combine(_newPackageTempFolder, "Provision Scripts"), new ExaminerSequenceDataSource() { Address = remote_address, diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/IMachineUpdateManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/IMachineUpdateManager.cs new file mode 100644 index 000000000..fd565b84a --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/IMachineUpdateManager.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.PMR.Synchronization; + +namespace Tango.PPC.Common.MachineUpdate +{ + public interface IMachineUpdateManager + { + /// <summary> + /// Gets the current setup step. + /// </summary> + MachineUpdateSteps CurrentStep { get; } + + /// <summary> + /// Occurs when there is a text log message available. + /// </summary> + event EventHandler<String> ProgressLog; + + /// <summary> + /// Gets the downloading packages step progress. + /// </summary> + double DownloadingPackagesProgress { get; } + + /// <summary> + /// Gets the downloading packages step status. + /// </summary> + String DownloadingPackagesStatus { get; } + + /// <summary> + /// Occurs when the <see cref="CurrentStep"/> has changed. + /// </summary> + event EventHandler<MachineUpdateSteps> ProgressStep; + + /// <summary> + /// Performs a machine update using the specified serial number and machine service address. + /// </summary> + /// <param name="serialNumber">The serial number.</param> + /// <param name="machineServiceAddress">The machine service address.</param> + /// <returns></returns> + Task<MachineUpdateResult> Update(String serialNumber, String machineServiceAddress); + + /// <summary> + /// Checks if any update are available for the specified machine serial number. + /// </summary> + /// <param name="serialNumber">The serial number.</param> + /// <param name="machineServiceAddress">The machine service address.</param> + /// <returns></returns> + Task<CheckForUpdateResponse> CheckForUpdate(String serialNumber, String machineServiceAddress); + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs new file mode 100644 index 000000000..b86fb88d4 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs @@ -0,0 +1,287 @@ +using FluentFTP; +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Tango.Core; +using Tango.Core.DB; +using Tango.Core.Helpers; +using Tango.Core.IO; +using Tango.PMR.Synchronization; +using Tango.PPC.Common.Application; +using Tango.Settings; +using Tango.SQLExaminer; +using Tango.Transport.Web; + +namespace Tango.PPC.Common.MachineUpdate +{ + public class MachineUpdateManager : ExtendedObject, IMachineUpdateManager + { + private IPPCApplicationManager _app_manager; + + #region Events + + /// <summary> + /// Occurs when there is a text log message available. + /// </summary> + public event EventHandler<string> ProgressLog; + + /// <summary> + /// Occurs when the <see cref="CurrentStep" /> has changed. + /// </summary> + public event EventHandler<MachineUpdateSteps> ProgressStep; + + #endregion + + #region Properties + + private MachineUpdateSteps _currentStep; + /// <summary> + /// Gets the current setup step. + /// </summary> + public MachineUpdateSteps CurrentStep + { + get { return _currentStep; } + set + { + if (_currentStep != value) + { + _currentStep = value; + RaisePropertyChangedAuto(); + ProgressStep?.Invoke(this, _currentStep); + LogManager.Log("Machine Setup Manager Step: " + value.ToString()); + } + } + } + + private double _downloadProgress; + /// <summary> + /// Gets the downloading packages step progress. + /// </summary> + public double DownloadingPackagesProgress + { + get { return _downloadProgress; } + private set { _downloadProgress = value; RaisePropertyChangedAuto(); } + } + + private String _updatingPackagesStatus; + /// <summary> + /// Gets the downloading packages step status. + /// </summary> + public String DownloadingPackagesStatus + { + get { return _updatingPackagesStatus; } + set { _updatingPackagesStatus = value; RaisePropertyChangedAuto(); } + } + + #endregion + + /// <summary> + /// Initializes a new instance of the <see cref="MachineUpdateManager"/> class. + /// </summary> + /// <param name="applicationManager">The application manager.</param> + public MachineUpdateManager(IPPCApplicationManager applicationManager) + { + _app_manager = applicationManager; + } + + #region Public Methods + + /// <summary> + /// Performs a machine setup using the specified serial number and machine service address. + /// </summary> + /// <param name="serialNumber">The serial number.</param> + /// <param name="machineServiceAddress">The machine service address.</param> + /// <returns></returns> + public Task<MachineUpdateResult> Update(string serialNumber, string machineServiceAddress) + { + return Task.Factory.StartNew<MachineUpdateResult>(() => + { + + LogManager.Log($"Starting machine update for serial number {serialNumber}..."); + + //Connect to machine service and get matching packages for this machine. + CurrentStep = MachineUpdateSteps.DownloadingPackage; + DownloadingPackagesProgress = 0; + DownloadingPackagesStatus = "Connecting to machine service..."; + + LogManager.Log($"Connecting to machine service on {machineServiceAddress}..."); + + DownloadUpdateRequest request = new DownloadUpdateRequest(); + request.SerialNumber = serialNumber; + + DownloadUpdateResponse update_response = null; + + using (var http = new ProtoWebClient()) + { + update_response = http.Post<DownloadUpdateRequest, DownloadUpdateResponse>(machineServiceAddress + "/api/Synchronization/MachineUpdate", request).Result; + } + + LogManager.Log($"Machine update response received: {Environment.NewLine}{update_response.ToJsonString()}"); + + //Create temporary folders for packages. + var _newPackageTempFolder = TemporaryManager.CreateFolder(); + _newPackageTempFolder.Persist = true; + + LogManager.Log($"Temporary package folder created: {_newPackageTempFolder}."); + + //Download software package. + var tempFile = TemporaryManager.CreateFile(".zip"); + + LogManager.Log($"Temporary package zip file created: {tempFile}."); + + DownloadingPackagesStatus = "Downloading software package..."; + + LogManager.Log("Downloading software package..."); + + int fileSize = 0; + DownloadingPackagesProgress = 0; + + using (FileStreamWrapper fs = new FileStreamWrapper(tempFile.Path, FileMode.Create, (current) => + { + InvokeUINow(() => + { + Thread.Sleep(2); //TODO: this is necessary only for visibility... + DownloadingPackagesProgress = ((double)current / (double)fileSize) * 100d; + }); + })) + { + using (FtpClient ftp = new FtpClient(update_response.FtpAddress, update_response.FtpUserName, update_response.FtpPassword)) + { + LogManager.Log("FTP: Connecting to site: " + update_response.FtpAddress); + ftp.ConnectAsync().Wait(); + LogManager.Log("FTP: Retrieving download size..."); + fileSize = (int)ftp.GetFileSize(update_response.FtpFilePath); + LogManager.Log("FTP: Download size: " + fileSize + " bytes."); + LogManager.Log("FTP: Starting download..."); + ftp.DownloadAsync(fs, update_response.FtpFilePath).Wait(); + } + } + + LogManager.Log("Extracting downloaded zip file..."); + //Extract software package. + ZipFile.ExtractToDirectory(tempFile, _newPackageTempFolder); + + + LogManager.Log("Copying latest updater utility to application path..."); + //Copy new updater utility to app path. + File.Copy(Path.Combine(_newPackageTempFolder, "Tango.PPC.Updater.exe"), Path.Combine(PathHelper.GetStartupPath(), "Tango.PPC.Updater.exe"), true); + + + //Synchronize database + CurrentStep = MachineUpdateSteps.SynchronizingSchema; + + String db_name = "Tango"; + String localAddress = SettingsManager.Default.GetOrCreate<CoreSettings>().DataSource.Address; + String remote_address = update_response.DbAddress; + + LogManager.Log($"Synchronizing database '{remote_address}\\{db_name}' => '{localAddress}\\{db_name}'..."); + + LogManager.Log("Initializing database manager..."); + DbManager db = DbManager.FromAddressAndName(localAddress, db_name); + + LogManager.Log("Checking Tango database exists on the local machine..."); + if (!db.Exists(db_name)) + { + throw new InvalidProgramException("Database tango does not exists."); + } + + LogManager.Log("Disposing database manager."); + db.Dispose(); + + LogManager.Log($"Initializing {nameof(ExaminerSequenceConfigurationRunner)}..."); + + ExaminerSequenceConfigurationRunner runner = new ExaminerSequenceConfigurationRunner( + Path.Combine(_newPackageTempFolder, "Update Scripts", "config.xml"), + Path.Combine(_newPackageTempFolder, "Update Scripts"), + new ExaminerSequenceDataSource() + { + Address = remote_address, + DataBaseName = db_name, + IntegratedSecurity = false, + UserName = update_response.DbUserName, + Password = update_response.DbPassword, + }, + new ExaminerSequenceDataSource() + { + Address = localAddress, + DataBaseName = db_name, + IntegratedSecurity = true, + }, serialNumber); + + runner.Log += (x, msg) => + { + LogManager.Log(msg); + ProgressLog?.Invoke(this, msg); + }; + + runner.ScriptExecuting += (x, item) => + { + LogManager.Log($"Executing script {item.ToString()}..."); + + if (item.Type == ExaminerSequenceItemType.Data && item.RequiresSerialNumber) + { + CurrentStep = MachineUpdateSteps.SynchronizingMachineConfiguration; + } + else if (item.Type == ExaminerSequenceItemType.Data) + { + CurrentStep = MachineUpdateSteps.SynchronizingData; + } + }; + + LogManager.Log("Starting synchronization process..."); + + try + { + runner.Run().Wait(); + LogManager.Log("Synchronization completed successfully!"); + } + catch (Exception ex) + { + throw LogManager.Log(ex, "Setup manager error while trying to synchronize database."); + } + + return new MachineUpdateResult() + { + UpdatePackagePath = _newPackageTempFolder, + }; + }); + } + + /// <summary> + /// Checks if any update are available for the specified machine serial number. + /// </summary> + /// <param name="serialNumber">The serial number.</param> + /// <param name="machineServiceAddress">The machine service address.</param> + /// <returns></returns> + public Task<CheckForUpdateResponse> CheckForUpdate(string serialNumber, string machineServiceAddress) + { + return Task.Factory.StartNew<CheckForUpdateResponse>(() => + { + LogManager.Log($"Connecting to machine service on {machineServiceAddress}..."); + LogManager.Log($"Checking if updates available..."); + + CheckForUpdateRequest request = new CheckForUpdateRequest(); + request.SerialNumber = serialNumber; + request.Version = _app_manager.Version.ToString(); + + CheckForUpdateResponse update_response = null; + + using (var http = new ProtoWebClient()) + { + update_response = http.Post<CheckForUpdateRequest, CheckForUpdateResponse>(machineServiceAddress + "/api/Synchronization/CheckForUpdate", request).Result; + } + + LogManager.Log($"Check for update response received: {Environment.NewLine}{update_response.ToJsonString()}"); + + return update_response; + }); + } + + #endregion + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateResult.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateResult.cs new file mode 100644 index 000000000..17ae394ee --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateResult.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.PPC.Common.MachineUpdate +{ + public class MachineUpdateResult + { + /// <summary> + /// Gets or sets the temporary update package path from which to get the last downloaded software version. + /// </summary> + public String UpdatePackagePath { get; set; } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateSteps.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateSteps.cs new file mode 100644 index 000000000..3d8208e4b --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateSteps.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.PPC.Common.MachineUpdate +{ + public enum MachineUpdateSteps + { + [Description("Downloading Package")] + DownloadingPackage, + [Description("Synchronizing Schema")] + SynchronizingSchema, + [Description("Synchronizing Data")] + SynchronizingData, + [Description("Updating Configuration")] + SynchronizingMachineConfiguration + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Navigation/NavigationView.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Navigation/NavigationView.cs index 3c6d91502..ef8f1c2ad 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Navigation/NavigationView.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Navigation/NavigationView.cs @@ -15,6 +15,7 @@ namespace Tango.PPC.Common.Navigation LayoutView, LoginView, MachineSetupView, + MachineUpdateView, ExternalBridgeView, HomeModule, ShutdownView, diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj b/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj index 0fbfb635e..35a79d497 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj @@ -126,6 +126,10 @@ <Compile Include="MachineSetup\MachineSetupManager.cs" /> <Compile Include="MachineSetup\MachineSetupResult.cs" /> <Compile Include="MachineSetup\MachineSetupSteps.cs" /> + <Compile Include="MachineUpdate\IMachineUpdateManager.cs" /> + <Compile Include="MachineUpdate\MachineUpdateManager.cs" /> + <Compile Include="MachineUpdate\MachineUpdateResult.cs" /> + <Compile Include="MachineUpdate\MachineUpdateSteps.cs" /> <Compile Include="Messages\JobRemovedMessage.cs" /> <Compile Include="Messages\JobSavedMessage.cs" /> <Compile Include="Messages\MachineSettingsSavedMessage.cs" /> @@ -299,7 +303,7 @@ </Target> <ProjectExtensions> <VisualStudio> - <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" /> + <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" /> </VisualStudio> </ProjectExtensions> </Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Publisher/MainWindow.xaml b/Software/Visual_Studio/PPC/Tango.PPC.Publisher/MainWindow.xaml index d1921b0a8..8e9b31dff 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Publisher/MainWindow.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.Publisher/MainWindow.xaml @@ -8,7 +8,7 @@ xmlns:examiner="clr-namespace:Tango.SQLExaminer;assembly=Tango.SQLExaminer" xmlns:local="clr-namespace:Tango.PPC.Publisher" mc:Ignorable="d" - Title="Tango PPC Publisher" Height="800" Width="500" d:DataContext="{d:DesignInstance Type=local:MainWindowVM, IsDesignTimeCreatable=False}"> + Title="Tango PPC Publisher" Height="980" Width="500" d:DataContext="{d:DesignInstance Type=local:MainWindowVM, IsDesignTimeCreatable=False}"> <Window.Resources> <converters:EnumToItemsSourceConverter x:Key="EnumToItemsSourceConverter" /> @@ -53,9 +53,22 @@ </TextBlock> </TextBlock> - <TextBlock Margin="0 20 0 0">Examiner Sequence Items</TextBlock> + <TextBlock Margin="0 20 0 0">Examiner Provision Sequence Items</TextBlock> - <DataGrid Height="200" SelectionMode="Single" SelectionUnit="FullRow" HorizontalScrollBarVisibility="Disabled" AutoGenerateColumns="False" ItemsSource="{Binding SequenceItems}" CanUserAddRows="True" CanUserReorderColumns="False" CanUserDeleteRows="True" CanUserSortColumns="False" AddingNewItem="DataGrid_AddingNewItem"> + <DataGrid Height="170" SelectionMode="Single" SelectionUnit="FullRow" HorizontalScrollBarVisibility="Disabled" AutoGenerateColumns="False" ItemsSource="{Binding ProvisionSequenceItemsView}" CanUserAddRows="True" CanUserReorderColumns="False" CanUserDeleteRows="True" CanUserSortColumns="False" AddingNewItem="DataGrid_AddingNewItem"> + <DataGrid.Columns> + <DataGridTextColumn IsReadOnly="True" Width="100" Header="File Name" Binding="{Binding FileName}" /> + <DataGridComboBoxColumn Width="75" Header="Type" ItemsSource="{Binding Source={x:Type examiner:ExaminerSequenceItemType},Converter={StaticResource EnumToItemsSourceConverter}}" SelectedValueBinding="{Binding Type}" SelectedValuePath="Value" DisplayMemberPath="DisplayName" /> + <DataGridComboBoxColumn Width="90" Header="Direction" ItemsSource="{Binding Source={x:Type examiner:ExaminerSequenceItemDirection},Converter={StaticResource EnumToItemsSourceConverter}}" SelectedValueBinding="{Binding Direction}" SelectedValuePath="Value" DisplayMemberPath="DisplayName" /> + <DataGridCheckBoxColumn Width="35" Header="S/N" Binding="{Binding RequiresSerialNumber}" /> + <DataGridTextColumn Header="Name" Width="1*" Binding="{Binding Name}" /> + <DataGridTextColumn Header="Index" Width="40" Binding="{Binding Index}" /> + </DataGrid.Columns> + </DataGrid> + + <TextBlock Margin="0 20 0 0">Examiner Update Sequence Items</TextBlock> + + <DataGrid Height="170" SelectionMode="Single" SelectionUnit="FullRow" HorizontalScrollBarVisibility="Disabled" AutoGenerateColumns="False" ItemsSource="{Binding UpdateSequenceItemsView}" CanUserAddRows="True" CanUserReorderColumns="False" CanUserDeleteRows="True" CanUserSortColumns="False" AddingNewItem="DataGrid_AddingNewItem_1"> <DataGrid.Columns> <DataGridTextColumn IsReadOnly="True" Width="100" Header="File Name" Binding="{Binding FileName}" /> <DataGridComboBoxColumn Width="75" Header="Type" ItemsSource="{Binding Source={x:Type examiner:ExaminerSequenceItemType},Converter={StaticResource EnumToItemsSourceConverter}}" SelectedValueBinding="{Binding Type}" SelectedValuePath="Value" DisplayMemberPath="DisplayName" /> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Publisher/MainWindow.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.Publisher/MainWindow.xaml.cs index 64e7e8740..610eb40a8 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Publisher/MainWindow.xaml.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Publisher/MainWindow.xaml.cs @@ -1,6 +1,7 @@ using Microsoft.Win32; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -13,6 +14,7 @@ using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; +using Tango.SQLExaminer; namespace Tango.PPC.Publisher { @@ -35,9 +37,54 @@ namespace Tango.PPC.Publisher { SequenceItem item = new SequenceItem(); - if ((DataContext as MainWindowVM).SequenceItems.Count > 0) + var config = ExaminerConfiguration.FromFile(dlg.FileName); + + if (config.Maker == "SQL Examiner") + { + item.Type = ExaminerSequenceItemType.Schema; + } + else + { + item.Type = ExaminerSequenceItemType.Data; + } + + item.RequiresSerialNumber = File.ReadAllText(dlg.FileName).Contains("'@'"); + + if ((DataContext as MainWindowVM).ProvisionSequenceItems.Count > 0) + { + item.Index = (DataContext as MainWindowVM).ProvisionSequenceItems.Max(x => x.Index + 1); + } + item.FilePath = dlg.FileName; + item.Name = System.IO.Path.GetFileNameWithoutExtension(dlg.FileName); + + e.NewItem = item; + } + } + + private void DataGrid_AddingNewItem_1(object sender, AddingNewItemEventArgs e) + { + OpenFileDialog dlg = new OpenFileDialog(); + dlg.Filter = "SQL Examiner Configuration|*.xml"; + if (dlg.ShowDialog().Value) + { + SequenceItem item = new SequenceItem(); + + var config = ExaminerConfiguration.FromFile(dlg.FileName); + + if (config.Maker == "SQL Examiner") + { + item.Type = ExaminerSequenceItemType.Schema; + } + else + { + item.Type = ExaminerSequenceItemType.Data; + } + + item.RequiresSerialNumber = File.ReadAllText(dlg.FileName).Contains("'@'"); + + if ((DataContext as MainWindowVM).UpdateSequenceItems.Count > 0) { - item.Index = (DataContext as MainWindowVM).SequenceItems.Max(x => x.Index + 1); + item.Index = (DataContext as MainWindowVM).UpdateSequenceItems.Max(x => x.Index + 1); } item.FilePath = dlg.FileName; item.Name = System.IO.Path.GetFileNameWithoutExtension(dlg.FileName); diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Publisher/MainWindowVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.Publisher/MainWindowVM.cs index 48e4fdf01..4828879e1 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Publisher/MainWindowVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Publisher/MainWindowVM.cs @@ -66,27 +66,35 @@ namespace Tango.PPC.Publisher set { _currentVersion = value; RaisePropertyChangedAuto(); } } - private ObservableCollection<SequenceItem> _sequenceItems; - public ObservableCollection<SequenceItem> SequenceItems + private ObservableCollection<SequenceItem> _provisionSequenceItems; + public ObservableCollection<SequenceItem> ProvisionSequenceItems { - get { return _sequenceItems; } - set { _sequenceItems = value; RaisePropertyChangedAuto(); } + get { return _provisionSequenceItems; } + set { _provisionSequenceItems = value; RaisePropertyChangedAuto(); } } - private ICollectionView _sequenceItemsView; - public ICollectionView SequenceItemsView + private ICollectionView _provisionSequenceItemsView; + public ICollectionView ProvisionSequenceItemsView { - get { return _sequenceItemsView; } - set { _sequenceItemsView = value; RaisePropertyChangedAuto(); } + get { return _provisionSequenceItemsView; } + set { _provisionSequenceItemsView = value; RaisePropertyChangedAuto(); } } - private SequenceItem _selectedSequenceItem; - public SequenceItem SelectedSequenceItem + private ObservableCollection<SequenceItem> _updateSequenceItems; + public ObservableCollection<SequenceItem> UpdateSequenceItems { - get { return _selectedSequenceItem; } - set { _selectedSequenceItem = value; RaisePropertyChangedAuto(); } + get { return _updateSequenceItems; } + set { _updateSequenceItems = value; RaisePropertyChangedAuto(); } } + private ICollectionView _updateSequenceItemsView; + public ICollectionView UpdateSequenceItemsView + { + get { return _updateSequenceItemsView; } + set { _updateSequenceItemsView = value; RaisePropertyChangedAuto(); } + } + + private String _email; public String Email { @@ -137,10 +145,13 @@ namespace Tango.PPC.Publisher _hashGenerator = new BasicHashGenerator(); - SequenceItems = new ObservableCollection<SequenceItem>(); - SequenceItemsView = CollectionViewSource.GetDefaultView(SequenceItems); + ProvisionSequenceItems = new ObservableCollection<SequenceItem>(); + ProvisionSequenceItemsView = CollectionViewSource.GetDefaultView(ProvisionSequenceItems); + ProvisionSequenceItemsView.SortDescriptions.Add(new SortDescription(nameof(SequenceItem.Index), ListSortDirection.Ascending)); - SequenceItemsView.SortDescriptions.Add(new SortDescription(nameof(SequenceItem.Index), ListSortDirection.Ascending)); + UpdateSequenceItems = new ObservableCollection<SequenceItem>(); + UpdateSequenceItemsView = CollectionViewSource.GetDefaultView(UpdateSequenceItems); + UpdateSequenceItemsView.SortDescriptions.Add(new SortDescription(nameof(SequenceItem.Index), ListSortDirection.Ascending)); using (ObservablesContext db = ObservablesContext.CreateDefault("twine01\\SQLTWINE_TEST")) { @@ -196,15 +207,44 @@ namespace Tango.PPC.Publisher using (ZipFile zip = new ZipFile()) { - String sync_dir = "Synchronization Scripts"; + String provision_dir = "Provision Scripts"; + + zip.AddDirectoryByName(provision_dir); + + ExaminerSequenceConfiguration provision_config = new ExaminerSequenceConfiguration(); + + foreach (var item in ProvisionSequenceItems) + { + provision_config.Items.Add(new ExaminerSequenceItem() + { + Direction = item.Direction, + FileName = item.FileName, + Index = item.Index, + Name = item.Name, + Type = item.Type, + RequiresSerialNumber = item.RequiresSerialNumber + }); + + zip.AddFile(item.FilePath, provision_dir); + } + + String provision_config_file = TemporaryManager.Default.CreateFile(".zip"); + provision_config.ToFile(provision_config_file); + + var cf = zip.AddFile(provision_config_file, provision_dir); + cf.FileName = provision_dir + "\\config.xml"; + + + + String update_dir = "Update Scripts"; - zip.AddDirectoryByName(sync_dir); + zip.AddDirectoryByName(update_dir); - ExaminerSequenceConfiguration config = new ExaminerSequenceConfiguration(); + ExaminerSequenceConfiguration update_config = new ExaminerSequenceConfiguration(); - foreach (var item in SequenceItems) + foreach (var item in UpdateSequenceItems) { - config.Items.Add(new ExaminerSequenceItem() + update_config.Items.Add(new ExaminerSequenceItem() { Direction = item.Direction, FileName = item.FileName, @@ -214,14 +254,14 @@ namespace Tango.PPC.Publisher RequiresSerialNumber = item.RequiresSerialNumber }); - zip.AddFile(item.FilePath, sync_dir); + zip.AddFile(item.FilePath, update_dir); } - String config_file = TemporaryManager.Default.CreateFile(".zip"); - config.ToFile(config_file); + String update_config_file = TemporaryManager.Default.CreateFile(".zip"); + update_config.ToFile(update_config_file); - var cf = zip.AddFile(config_file, sync_dir); - cf.FileName = sync_dir + "\\config.xml"; + var cuf = zip.AddFile(update_config_file, update_dir); + cuf.FileName = update_dir + "\\config.xml"; foreach (var file in Directory.GetFiles(_appPath, "*.*", SearchOption.TopDirectoryOnly)) { diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/machine-update.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/machine-update.png Binary files differnew file mode 100644 index 000000000..3e49520dd --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/machine-update.png diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/right-arrow-64.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/right-arrow-64.png Binary files differnew file mode 100644 index 000000000..b23d81f3c --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/right-arrow-64.png diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs index e43f37e5f..714b83dfa 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs @@ -71,7 +71,6 @@ namespace Tango.PPC.UI.PPCApplication /// <summary> /// Gets the application version. /// </summary> - /// <exception cref="NotImplementedException"></exception> public Version Version { get diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs index 648ddbb59..a4ffefec8 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs @@ -7,5 +7,5 @@ using System.Windows; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("Tango Panel PC Application")] +[assembly: AssemblyTitle("Tango PPC Application")] [assembly: AssemblyVersion("2.0.7.1119")] diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj b/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj index 2b2752a24..fc4c94eb0 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj @@ -134,8 +134,10 @@ <Compile Include="ViewModels\LoginViewVM.cs" /> <Compile Include="ViewModels\MachineSetupViewVM.cs" /> <Compile Include="ViewModels\MainViewVM.cs" /> + <Compile Include="ViewModels\MachineUpdateViewVM.cs" /> <Compile Include="ViewsContracts\ILayoutView.cs" /> <Compile Include="ViewsContracts\IMachineSetupView.cs" /> + <Compile Include="ViewsContracts\IMachineUpdateView.cs" /> <Compile Include="Views\ExternalBridgeView.xaml.cs"> <DependentUpon>ExternalBridgeView.xaml</DependentUpon> </Compile> @@ -154,6 +156,9 @@ <Compile Include="Views\MainView.xaml.cs"> <DependentUpon>MainView.xaml</DependentUpon> </Compile> + <Compile Include="Views\MachineUpdateView.xaml.cs"> + <DependentUpon>MachineUpdateView.xaml</DependentUpon> + </Compile> <Page Include="Connectivity\WiFiAuthenticationView.xaml"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> @@ -206,6 +211,10 @@ <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> + <Page Include="Views\MachineUpdateView.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> </ItemGroup> <ItemGroup> <Compile Include="Properties\AssemblyInfo.cs"> @@ -356,6 +365,8 @@ <Link>Tango.ColorLib.dll</Link> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> + <Resource Include="Images\right-arrow-64.png" /> + <Resource Include="Images\machine-update.png" /> <Resource Include="Images\home.png" /> </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> @@ -421,7 +432,7 @@ copy /Y "$(SolutionDir)Referenced Assemblies\vcruntime140d.dll" "$(TargetDir)"</ </PropertyGroup> <ProjectExtensions> <VisualStudio> - <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" /> + <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" /> </VisualStudio> </ProjectExtensions> </Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs index bec1d2b48..57fae7791 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs @@ -11,6 +11,7 @@ using Tango.PPC.Common.Diagnostics; using Tango.PPC.Common.EventLogging; using Tango.PPC.Common.ExternalBridge; using Tango.PPC.Common.MachineSetup; +using Tango.PPC.Common.MachineUpdate; using Tango.PPC.Common.Modules; using Tango.PPC.Common.Navigation; using Tango.PPC.Common.Notifications; @@ -55,6 +56,7 @@ namespace Tango.PPC.UI TangoIOC.Default.Unregister<ITeamFoundationServiceClient>(); TangoIOC.Default.Unregister<IPPCExternalBridgeService>(); TangoIOC.Default.Unregister<IMachineSetupManager>(); + TangoIOC.Default.Unregister<IMachineUpdateManager>(); TangoIOC.Default.Unregister<IPrintingManager>(); TangoIOC.Default.Unregister<IConnectivityProvider>(); @@ -70,6 +72,7 @@ namespace Tango.PPC.UI TangoIOC.Default.Register<IEventLogger, DefaultEventLogger>(); TangoIOC.Default.Register<IPPCExternalBridgeService, PPCExternalBridgeService>(); TangoIOC.Default.Register<IMachineSetupManager, MachineSetupManager>(); + TangoIOC.Default.Register<IMachineUpdateManager, MachineUpdateManager>(); TangoIOC.Default.Register<IPrintingManager, DefaultPrintingManager>(); TangoIOC.Default.Register<IConnectivityProvider, DefaultConnectivityProvider>(); @@ -81,12 +84,14 @@ namespace Tango.PPC.UI TangoIOC.Default.Register<LayoutViewVM>(); TangoIOC.Default.Register<ExternalBridgeViewVM>(); TangoIOC.Default.Register<MachineSetupViewVM>(); + TangoIOC.Default.Register<MachineUpdateViewVM>(); TangoIOC.Default.GetInstance<IPPCApplicationManager>().ContentRendered += (_, __) => { TangoIOC.Default.Register<ILayoutView, LayoutView>(LayoutView.Instance); TangoIOC.Default.Register<IMachineSetupView, MachineSetupView>(MachineSetupView.Instance); + TangoIOC.Default.Register<IMachineUpdateView, MachineUpdateView>(MachineUpdateView.Instance); }; //TangoIOC.Default.Register<LoadingViewVM>(); @@ -145,5 +150,13 @@ namespace Tango.PPC.UI return TangoIOC.Default.GetInstance<MachineSetupViewVM>(); } } + + public static MachineUpdateViewVM MachineUpdateViewVM + { + get + { + return TangoIOC.Default.GetInstance<MachineUpdateViewVM>(); + } + } } }
\ No newline at end of file diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LayoutViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LayoutViewVM.cs index 28692cdfa..fd36d0d13 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LayoutViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LayoutViewVM.cs @@ -84,6 +84,10 @@ namespace Tango.PPC.UI.ViewModels /// </summary> public RelayCommand SignOutCommand { get; set; } + /// <summary> + /// Gets or sets the update command. + /// </summary> + public RelayCommand UpdateCommand { get; set; } #endregion #region Constructors @@ -100,6 +104,11 @@ namespace Tango.PPC.UI.ViewModels StopPrintingCommand = new RelayCommand(StopPrinting); SignOutCommand = new RelayCommand(SignOut); + UpdateCommand = new RelayCommand(() => + { + NavigationManager.NavigateTo(NavigationView.MachineUpdateView); + TangoIOC.Default.GetInstance<MachineUpdateViewVM>().CheckForUpdates(); + }); } #endregion diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineSetupViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineSetupViewVM.cs index 0f66b6fc8..f3cb83ffe 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineSetupViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineSetupViewVM.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Data.SqlClient; using System.Diagnostics; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -227,11 +228,11 @@ namespace Tango.PPC.UI.ViewModels /// </summary> private void CompleteSetup() { - String updater_exe = AssemblyHelper.GetCurrentAssemblyFolder() + "\\Tango.PPC.Updater.exe"; + String updater_exe = Path.Combine(_setup_result.UpdatePackagePath, "Tango.PPC.Updater.exe"); LogManager.Log("Completing machine setup..."); - LogManager.Log($"Executing '{updater_exe}' with arguments '{_setup_result.UpdatePackagePath}'..."); - Process.Start(updater_exe, _setup_result.UpdatePackagePath); + LogManager.Log($"Executing '{updater_exe}' with arguments '{PathHelper.GetStartupPath()}'..."); + Process.Start(updater_exe, PathHelper.GetStartupPath()); LogManager.Log("Terminating application process!"); Environment.Exit(0); } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs new file mode 100644 index 000000000..84e65e516 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs @@ -0,0 +1,170 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.Commands; +using Tango.Core.Helpers; +using Tango.PPC.Common; +using Tango.PPC.Common.MachineUpdate; +using Tango.PPC.UI.ViewsContracts; + +namespace Tango.PPC.UI.ViewModels +{ + public class MachineUpdateViewVM : PPCViewModel<IMachineUpdateView> + { + public enum MachineUpdateView + { + + UpdateCheckView, + UpdateCheckErrorView, + UpdateAvailableView, + UpToDateView, + UpdateProgressView, + UpdateCompletedView, + UpdateFailedView, + } + + private MachineUpdateResult _update_result; + + #region Properties + + /// <summary> + /// Gets or sets the machine update manager. + /// </summary> + public IMachineUpdateManager MachineUpdateManager { get; set; } + + private String _latestVersion; + /// <summary> + /// Gets or sets the latest version. + /// </summary> + public String LatestVersion + { + get { return _latestVersion; } + set { _latestVersion = value; RaisePropertyChangedAuto(); } + } + + #endregion + + #region Commands + + /// <summary> + /// Gets or sets the complete command. + /// </summary> + public RelayCommand CompleteCommand { get; set; } + + /// <summary> + /// Gets or sets the install command. + /// </summary> + public RelayCommand UpdateCommand { get; set; } + + /// <summary> + /// Gets or sets the restart command. + /// </summary> + public RelayCommand RestartCommand { get; set; } + + /// <summary> + /// Gets or sets the close command. + /// </summary> + public RelayCommand CloseCommand { get; set; } + + #endregion + + #region Constructors + + public MachineUpdateViewVM(IMachineUpdateManager machineUpdateManager) + { + MachineUpdateManager = machineUpdateManager; + + CompleteCommand = new RelayCommand(CompleteUpdate); + UpdateCommand = new RelayCommand(Update); + RestartCommand = new RelayCommand(CheckForUpdates); + CloseCommand = new RelayCommand(() => + { + NavigationManager.NavigateTo(Common.Navigation.NavigationView.HomeModule); + NavigateTo(MachineUpdateView.UpdateCheckView); + }); + } + + #endregion + + #region Update + + public async void CheckForUpdates() + { + await NavigateTo(MachineUpdateView.UpdateCheckView); + + try + { + var response = await MachineUpdateManager.CheckForUpdate(MachineProvider.Machine.SerialNumber, "http://localhost:51581/"); + + if (response.IsUpdateAvailable) + { + LatestVersion = response.Version; + await NavigateTo(MachineUpdateView.UpdateAvailableView); + } + else + { + await NavigateTo(MachineUpdateView.UpToDateView); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error while trying to check for updates."); + await NavigateTo(MachineUpdateView.UpdateFailedView); + } + } + + private async void Update() + { + await NavigateTo(MachineUpdateView.UpdateProgressView); + + LogManager.Log("Starting machine update..."); + + try + { + _update_result = await MachineUpdateManager.Update(MachineProvider.Machine.SerialNumber, "http://localhost:51581/"); + LogManager.Log("Machine update completed."); + await NavigateTo(MachineUpdateView.UpdateCompletedView); + } + catch (Exception ex) + { + LogManager.Log(ex, "Machine update failed."); + await NavigateTo(MachineUpdateView.UpdateFailedView); + } + } + + #endregion + + #region Complete + + private void CompleteUpdate() + { + String updater_exe = Path.Combine(_update_result.UpdatePackagePath, "Tango.PPC.Updater.exe"); + + LogManager.Log("Completing machine setup..."); + LogManager.Log($"Executing '{updater_exe}' with arguments '{PathHelper.GetStartupPath()}'..."); + Process.Start(updater_exe, PathHelper.GetStartupPath()); + LogManager.Log("Terminating application process!"); + Environment.Exit(0); + } + + #endregion + + public override void OnApplicationStarted() + { + + } + + /// <summary> + /// Navigates to the specified view. + /// </summary> + /// <param name="view">The view.</param> + private Task NavigateTo(MachineUpdateView view) + { + return View.NavigateTo(view); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml index 19f2caa59..2db5f12b6 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml @@ -60,6 +60,15 @@ </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> + + <StackPanel Margin="0 5 0 0"> + <touch:TouchButton Style="{StaticResource TangoFlatButton}" Padding="30" Foreground="{StaticResource TangoDarkForegroundBrush}" Command="{Binding UpdateCommand}" FontSize="{StaticResource TangoHeaderFontSize}"> + <StackPanel Orientation="Horizontal" HorizontalAlignment="Left"> + <Image Source="/Images/right-arrow-64.png" VerticalAlignment="Center" Width="48" Height="48"></Image> + <TextBlock VerticalAlignment="Center" Margin="20 0 0 0">Update</TextBlock> + </StackPanel> + </touch:TouchButton> + </StackPanel> </StackPanel> <!--<StackPanel DockPanel.Dock="Bottom"> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml new file mode 100644 index 000000000..ce1cee424 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml @@ -0,0 +1,129 @@ +<UserControl x:Class="Tango.PPC.UI.Views.MachineUpdateView" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:global="clr-namespace:Tango.PPC.UI" + xmlns:update="clr-namespace:Tango.PPC.Common.MachineUpdate;assembly=Tango.PPC.Common" + xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" + xmlns:connectivity="clr-namespace:Tango.PPC.Common.Connectivity;assembly=Tango.PPC.Common" + xmlns:touch="clr-namespace:Tango.Touch.Controls;assembly=Tango.Touch" + xmlns:vm="clr-namespace:Tango.PPC.UI.ViewModels" + xmlns:local="clr-namespace:Tango.PPC.UI.Views" + mc:Ignorable="d" + d:DesignHeight="1280" d:DesignWidth="800" Background="{StaticResource TangoPrimaryBackgroundBrush}" d:DataContext="{d:DesignInstance Type=vm:MachineUpdateViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MachineUpdateViewVM}"> + <Grid> + <DockPanel> + + <StackPanel DockPanel.Dock="Top" HorizontalAlignment="Center" Margin="0 10 0 0"> + <Image Source="/Images/machine-update.png" Stretch="None" /> + </StackPanel> + + <controls:NavigationControl x:Name="navigationControl" TransitionType="Slide" KeepElementsAttached="True" Margin="0 20 0 0" SelectedIndex="0"> + + <Grid controls:NavigationControl.NavigationName="UpdateCheckView"> + <StackPanel HorizontalAlignment="Center" Margin="0 200 0 0"> + <touch:TouchBusyIndicator Width="250" Height="250" IsIndeterminate="{Binding IsVisible}" /> + <TextBlock DockPanel.Dock="Top" Margin="0 100" FontSize="{StaticResource TangoHeaderFontSize}" HorizontalAlignment="Center" TextWrapping="Wrap" TextAlignment="Center"> + Checking for updates, please wait... + </TextBlock> + </StackPanel> + </Grid> + + <Grid controls:NavigationControl.NavigationName="UpdateAvailableView"> + <StackPanel HorizontalAlignment="Center" Margin="0 40 0 0"> + <TextBlock FontSize="{StaticResource TangoHeaderFontSize}"> + <Run>Version</Run> + <Run Foreground="{StaticResource TangoPrimaryAccentBrush}" Text="{Binding LatestVersion}"></Run> + <Run>is available</Run> + </TextBlock> + + <TextBlock FontSize="{StaticResource TangoTitleFontSize}" Margin="0 40 0 0"> + Updating you machine can improve the following: + </TextBlock> + + <StackPanel Margin="0 40 0 0"> + <StackPanel Orientation="Horizontal" TextElement.FontSize="{StaticResource TangoTitleFontSize}"> + <touch:TouchIcon Width="24" Height="24" Icon="Check" Foreground="{StaticResource TangoPrimaryAccentBrush}" /> + <TextBlock Margin="10 0 0 0" VerticalAlignment="Center">Support for new media</TextBlock> + </StackPanel> + + <StackPanel Orientation="Horizontal" Margin="0 10 0 0" TextElement.FontSize="{StaticResource TangoTitleFontSize}"> + <touch:TouchIcon Width="24" Height="24" Icon="Check" Foreground="{StaticResource TangoPrimaryAccentBrush}" /> + <TextBlock Margin="10 0 0 0" VerticalAlignment="Center">Refined color conversion and calibration algorithms</TextBlock> + </StackPanel> + + <StackPanel Orientation="Horizontal" Margin="0 10 0 0" TextElement.FontSize="{StaticResource TangoTitleFontSize}"> + <touch:TouchIcon Width="24" Height="24" Icon="Check" Foreground="{StaticResource TangoPrimaryAccentBrush}" /> + <TextBlock Margin="10 0 0 0" VerticalAlignment="Center">Software fixes and improvements</TextBlock> + </StackPanel> + + <StackPanel Orientation="Horizontal" Margin="0 10 0 0" TextElement.FontSize="{StaticResource TangoTitleFontSize}"> + <touch:TouchIcon Width="24" Height="24" Icon="Check" Foreground="{StaticResource TangoPrimaryAccentBrush}" /> + <TextBlock Margin="10 0 0 0" VerticalAlignment="Center">Firmware upgrade</TextBlock> + </StackPanel> + </StackPanel> + + <TextBlock Margin="0 60 0 0" FontSize="{StaticResource TangoTitleFontSize}"> + Tap 'UPDATE' to start updating now. + </TextBlock> + + <touch:TouchButton Margin="0 200 0 0" Padding="20" Width="300" CornerRadius="35" Command="{Binding UpdateCommand}">UPDATE</touch:TouchButton> + </StackPanel> + </Grid> + + <Grid controls:NavigationControl.NavigationName="UpToDateView"> + <StackPanel HorizontalAlignment="Center" Margin="0 50 0 0"> + <touch:TouchIcon Icon="Check" Foreground="{StaticResource TangoPrimaryAccentBrush}" Width="70" Height="70" /> + <TextBlock VerticalAlignment="Center" Margin="0 10 0 0" Foreground="{StaticResource TangoPrimaryAccentBrush}" FontSize="{StaticResource TangoHeaderFontSize}">Your machine is up to date!</TextBlock> + + <touch:TouchButton Margin="0 200 0 0" Padding="20" Width="300" CornerRadius="35" Command="{Binding CloseCommand}">CLOSE</touch:TouchButton> + </StackPanel> + </Grid> + + <Grid controls:NavigationControl.NavigationName="UpdateCheckErrorView"> + <StackPanel HorizontalAlignment="Center" Margin="0 50 0 0"> + <touch:TouchIcon Icon="AlertOctagon" Foreground="{StaticResource TangoErrorBrush}" Width="70" Height="70" /> + <TextBlock VerticalAlignment="Center" Width="600" TextWrapping="Wrap" TextAlignment="Center" Margin="0 10 0 0" Foreground="{StaticResource TangoErrorBrush}" FontSize="{StaticResource TangoTitleFontSize}">An error occurred while trying to check for updates. Please check your internet connection and try again.</TextBlock> + + <touch:TouchButton Margin="0 200 0 0" Padding="20" Width="300" CornerRadius="35" Command="{Binding RestartCommand}">TRY AGAIN</touch:TouchButton> + </StackPanel> + </Grid> + + <Grid controls:NavigationControl.NavigationName="UpdateProgressView"> + <StackPanel> + <TextBlock HorizontalAlignment="Center" Margin="0 40 0 0" FontSize="{StaticResource TangoHeaderFontSize}">Updating your machine</TextBlock> + <TextBlock Margin="0 10 0 0" TextAlignment="Center" FontSize="{StaticResource TangoTitleFontSize}" Foreground="{StaticResource TangoGrayBrush}">Do not turn off the machine</TextBlock> + + <touch:TouchBusyIndicator Width="100" Height="100" Margin="0 80 0 0" IsIndeterminate="{Binding IsVisible}"></touch:TouchBusyIndicator> + <touch:TouchStepProgressBar FontSize="10" Width="720" Height="50" Margin="0 100 0 0" ItemsSource="{Binding Source={x:Type update:MachineUpdateSteps},Converter={StaticResource EnumToItemsSourceConverter}}" SelectedValue="{Binding MachineUpdateManager.CurrentStep}" SelectedValuePath="Value" DisplayMemberPath="DisplayName" /> + + <StackPanel Margin="100 100 100 0" Visibility="{Binding MachineUpdateManager.CurrentStep,Converter={StaticResource EnumToVisibilityConverter},ConverterParameter='DownloadingPackage'}"> + <TextBlock Text="{Binding MachineUpdateManager.DownloadingPackagesStatus,Mode=OneWay}"></TextBlock> + <touch:TouchProgressBar Margin="0 10 0 0" Height="10" Maximum="100" Value="{Binding MachineUpdateManager.DownloadingPackagesProgress,Mode=OneWay}" /> + </StackPanel> + </StackPanel> + </Grid> + + <Grid controls:NavigationControl.NavigationName="UpdateCompletedView"> + <StackPanel HorizontalAlignment="Center" Margin="0 50 0 0"> + <touch:TouchIcon Icon="Check" Foreground="{StaticResource TangoPrimaryAccentBrush}" Width="70" Height="70" /> + <TextBlock VerticalAlignment="Center" Margin="0 10 0 0" Foreground="{StaticResource TangoPrimaryAccentBrush}" FontSize="{StaticResource TangoHeaderFontSize}">Update completed successfully !</TextBlock> + + <touch:TouchButton Margin="0 200 0 0" Padding="20" Width="300" CornerRadius="35" Command="{Binding CompleteCommand}">RESTART</touch:TouchButton> + </StackPanel> + </Grid> + + <Grid controls:NavigationControl.NavigationName="UpdateFailedView"> + <StackPanel HorizontalAlignment="Center" Margin="0 50 0 0"> + <touch:TouchIcon Icon="AlertOctagon" Foreground="{StaticResource TangoErrorBrush}" Width="70" Height="70" /> + <TextBlock VerticalAlignment="Center" Margin="0 10 0 0" Foreground="{StaticResource TangoErrorBrush}" FontSize="{StaticResource TangoTitleFontSize}">An error occurred while trying to update the machine.</TextBlock> + + <touch:TouchButton Margin="0 200 0 0" Padding="20" Width="300" CornerRadius="35" Command="{Binding RestartCommand}">TRY AGAIN</touch:TouchButton> + </StackPanel> + </Grid> + + </controls:NavigationControl> + </DockPanel> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml.cs new file mode 100644 index 000000000..f63899932 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using Tango.PPC.UI.ViewModels; +using Tango.PPC.UI.ViewsContracts; + +namespace Tango.PPC.UI.Views +{ + /// <summary> + /// Interaction logic for UpdateView.xaml + /// </summary> + public partial class MachineUpdateView : UserControl, IMachineUpdateView + { + public MachineUpdateView() + { + InitializeComponent(); + + Instance = this; + } + + public static MachineUpdateView Instance { get; internal set; } + + public Task NavigateTo(MachineUpdateViewVM.MachineUpdateView view) + { + TaskCompletionSource<object> source = new TaskCompletionSource<object>(); + + navigationControl.NavigateTo(view.ToString(), () => + { + source.SetResult(new object()); + }); + + return source.Task; + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MainView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MainView.xaml index 9e47bfcdb..8e54f0990 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MainView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MainView.xaml @@ -45,6 +45,7 @@ <local:LayoutView></local:LayoutView> <local:ExternalBridgeView></local:ExternalBridgeView> <local:MachineSetupView></local:MachineSetupView> + <local:MachineUpdateView></local:MachineUpdateView> </controls:NavigationControl> </touch:TouchPanel> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewsContracts/IMachineUpdateView.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewsContracts/IMachineUpdateView.cs new file mode 100644 index 000000000..d71822b11 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewsContracts/IMachineUpdateView.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.PPC.Common; +using static Tango.PPC.UI.ViewModels.MachineUpdateViewVM; + +namespace Tango.PPC.UI.ViewsContracts +{ + public interface IMachineUpdateView : IPPCView + { + /// <summary> + /// Navigates to the specified machine setup view. + /// </summary> + /// <param name="view">The view.</param> + Task NavigateTo(MachineUpdateView view); + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Updater/MainWindow.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.Updater/MainWindow.xaml.cs index 394d3292f..55c60058b 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Updater/MainWindow.xaml.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Updater/MainWindow.xaml.cs @@ -23,9 +23,9 @@ namespace Tango.PPC.Updater /// </summary> public partial class MainWindow : Window { - private String _appPath = AppDomain.CurrentDomain.BaseDirectory; + private String _sourceFolder = AppDomain.CurrentDomain.BaseDirectory; private String _msProcessName = "Tango.PPC.UI"; - private String _sourceFolder = App.StartupArgs.FirstOrDefault(); + private String _appPath = String.Join(" ", App.StartupArgs); public MainWindow() { @@ -37,7 +37,7 @@ namespace Tango.PPC.Updater // } //#endif - if (!Directory.Exists(_sourceFolder)) + if (!Directory.Exists(_appPath)) { ShowError("This update utility can only be executed by the main Tango."); Environment.Exit(0); @@ -88,6 +88,7 @@ namespace Tango.PPC.Updater private void Update() { EnsureTangoIsDown(); + RemoveOldDLLFiles(); ReplaceFiles(); StartTango(); Environment.Exit(0); @@ -114,7 +115,14 @@ namespace Tango.PPC.Updater foreach (string dirPath in Directory.GetDirectories(_sourceFolder, "*", SearchOption.AllDirectories)) { - Directory.CreateDirectory(dirPath.Replace(_sourceFolder, _appPath)); + try + { + Directory.CreateDirectory(dirPath.Replace(_sourceFolder, _appPath)); + } + catch (Exception ex) + { + ShowError("Could not create directory " + Path.GetFileName(dirPath) + Environment.NewLine + ex.Message); + } } foreach (string newPath in Directory.GetFiles(_sourceFolder, "*.*", SearchOption.AllDirectories)) @@ -136,18 +144,26 @@ namespace Tango.PPC.Updater { if (!newPath.ToLower().Contains("updater.exe")) { - throw ex; + ShowError("Could not create file " + Path.GetFileName(newPath) + Environment.NewLine + ex.Message); } } } + } - try - { - Directory.Delete(_sourceFolder, true); - } - catch (Exception ex) + private void RemoveOldDLLFiles() + { + foreach (string dll in Directory.GetFiles(_appPath, "*.dll")) { - Debug.WriteLine(ex.ToString()); + try + { + File.Delete(dll); + } + catch + { + ShowError($"The file '{Path.GetFileName(dll)}' could not be removed. Please close all instances of Tango and press OK."); + RemoveOldDLLFiles(); + return; + } } } @@ -160,11 +176,23 @@ namespace Tango.PPC.Updater do { appProcess = Process.GetProcessesByName(_msProcessName).FirstOrDefault(); + Process p = new Process(); + p.StartInfo.CreateNoWindow = true; + p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; + p.StartInfo.FileName = "wmic"; + p.StartInfo.Arguments = String.Format("process where name='{0}' delete", _msProcessName); if (appProcess != null) { tries++; appProcess.Kill(); + + try + { + p.Start(); + } + catch { } + Thread.Sleep(1000); } diff --git a/Software/Visual_Studio/Tango.Logging/ConsoleWindow.xaml b/Software/Visual_Studio/Tango.Logging/ConsoleWindow.xaml index e73ccf415..df1f0da25 100644 --- a/Software/Visual_Studio/Tango.Logging/ConsoleWindow.xaml +++ b/Software/Visual_Studio/Tango.Logging/ConsoleWindow.xaml @@ -5,7 +5,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Tango.Logging" mc:Ignorable="d" - Height="500" Width="800" Background="Black" FontSize="13" Topmost="True" Foreground="Gainsboro" FontFamily="Lucida Console" Title="Console Emulator" RenderOptions.EdgeMode="Aliased"> + Height="500" Width="800" Background="Black" FontSize="11" Topmost="True" Foreground="Gainsboro" Title="Console Emulator" RenderOptions.EdgeMode="Aliased"> <Grid> <RichTextBox x:Name="txtLog" Background="Black" BorderThickness="0" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Visible"></RichTextBox> </Grid> diff --git a/Software/Visual_Studio/Tango.Logging/ConsoleWindow.xaml.cs b/Software/Visual_Studio/Tango.Logging/ConsoleWindow.xaml.cs index 04e5ab2fa..161c786d3 100644 --- a/Software/Visual_Studio/Tango.Logging/ConsoleWindow.xaml.cs +++ b/Software/Visual_Studio/Tango.Logging/ConsoleWindow.xaml.cs @@ -33,7 +33,7 @@ namespace Tango.Logging { InitializeComponent(); - txtLog.Document.LineHeight = 15; + txtLog.Document.LineHeight = 12; txtLog.Document.PageWidth = 4000; _currentBrush = Brushes.Gainsboro; diff --git a/Software/Visual_Studio/Tango.PMR/Synchronization/CheckForUpdateRequest.cs b/Software/Visual_Studio/Tango.PMR/Synchronization/CheckForUpdateRequest.cs new file mode 100644 index 000000000..c873c62a5 --- /dev/null +++ b/Software/Visual_Studio/Tango.PMR/Synchronization/CheckForUpdateRequest.cs @@ -0,0 +1,188 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: CheckForUpdateRequest.proto +#pragma warning disable 1591, 0612, 3021 +#region Designer generated code + +using pb = global::Google.Protobuf; +using pbc = global::Google.Protobuf.Collections; +using pbr = global::Google.Protobuf.Reflection; +using scg = global::System.Collections.Generic; +namespace Tango.PMR.Synchronization { + + /// <summary>Holder for reflection information generated from CheckForUpdateRequest.proto</summary> + public static partial class CheckForUpdateRequestReflection { + + #region Descriptor + /// <summary>File descriptor for CheckForUpdateRequest.proto</summary> + public static pbr::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbr::FileDescriptor descriptor; + + static CheckForUpdateRequestReflection() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "ChtDaGVja0ZvclVwZGF0ZVJlcXVlc3QucHJvdG8SGVRhbmdvLlBNUi5TeW5j", + "aHJvbml6YXRpb24iPgoVQ2hlY2tGb3JVcGRhdGVSZXF1ZXN0EhQKDFNlcmlh", + "bE51bWJlchgBIAEoCRIPCgdWZXJzaW9uGAIgASgJQiUKI2NvbS50d2luZS50", + "YW5nby5wbXIuc3luY2hyb25pemF0aW9uYgZwcm90bzM=")); + descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, + new pbr::FileDescriptor[] { }, + new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Synchronization.CheckForUpdateRequest), global::Tango.PMR.Synchronization.CheckForUpdateRequest.Parser, new[]{ "SerialNumber", "Version" }, null, null, null) + })); + } + #endregion + + } + #region Messages + public sealed partial class CheckForUpdateRequest : pb::IMessage<CheckForUpdateRequest> { + private static readonly pb::MessageParser<CheckForUpdateRequest> _parser = new pb::MessageParser<CheckForUpdateRequest>(() => new CheckForUpdateRequest()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser<CheckForUpdateRequest> Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::Tango.PMR.Synchronization.CheckForUpdateRequestReflection.Descriptor.MessageTypes[0]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public CheckForUpdateRequest() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public CheckForUpdateRequest(CheckForUpdateRequest other) : this() { + serialNumber_ = other.serialNumber_; + version_ = other.version_; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public CheckForUpdateRequest Clone() { + return new CheckForUpdateRequest(this); + } + + /// <summary>Field number for the "SerialNumber" field.</summary> + public const int SerialNumberFieldNumber = 1; + private string serialNumber_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string SerialNumber { + get { return serialNumber_; } + set { + serialNumber_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// <summary>Field number for the "Version" field.</summary> + public const int VersionFieldNumber = 2; + private string version_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string Version { + get { return version_; } + set { + version_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as CheckForUpdateRequest); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(CheckForUpdateRequest other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (SerialNumber != other.SerialNumber) return false; + if (Version != other.Version) return false; + return true; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (SerialNumber.Length != 0) hash ^= SerialNumber.GetHashCode(); + if (Version.Length != 0) hash ^= Version.GetHashCode(); + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + if (SerialNumber.Length != 0) { + output.WriteRawTag(10); + output.WriteString(SerialNumber); + } + if (Version.Length != 0) { + output.WriteRawTag(18); + output.WriteString(Version); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (SerialNumber.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(SerialNumber); + } + if (Version.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Version); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(CheckForUpdateRequest other) { + if (other == null) { + return; + } + if (other.SerialNumber.Length != 0) { + SerialNumber = other.SerialNumber; + } + if (other.Version.Length != 0) { + Version = other.Version; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + input.SkipLastField(); + break; + case 10: { + SerialNumber = input.ReadString(); + break; + } + case 18: { + Version = input.ReadString(); + break; + } + } + } + } + + } + + #endregion + +} + +#endregion Designer generated code diff --git a/Software/Visual_Studio/Tango.PMR/Synchronization/CheckForUpdateResponse.cs b/Software/Visual_Studio/Tango.PMR/Synchronization/CheckForUpdateResponse.cs new file mode 100644 index 000000000..736c653e5 --- /dev/null +++ b/Software/Visual_Studio/Tango.PMR/Synchronization/CheckForUpdateResponse.cs @@ -0,0 +1,188 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: CheckForUpdateResponse.proto +#pragma warning disable 1591, 0612, 3021 +#region Designer generated code + +using pb = global::Google.Protobuf; +using pbc = global::Google.Protobuf.Collections; +using pbr = global::Google.Protobuf.Reflection; +using scg = global::System.Collections.Generic; +namespace Tango.PMR.Synchronization { + + /// <summary>Holder for reflection information generated from CheckForUpdateResponse.proto</summary> + public static partial class CheckForUpdateResponseReflection { + + #region Descriptor + /// <summary>File descriptor for CheckForUpdateResponse.proto</summary> + public static pbr::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbr::FileDescriptor descriptor; + + static CheckForUpdateResponseReflection() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "ChxDaGVja0ZvclVwZGF0ZVJlc3BvbnNlLnByb3RvEhlUYW5nby5QTVIuU3lu", + "Y2hyb25pemF0aW9uIkQKFkNoZWNrRm9yVXBkYXRlUmVzcG9uc2USGQoRSXNV", + "cGRhdGVBdmFpbGFibGUYASABKAgSDwoHVmVyc2lvbhgCIAEoCUIlCiNjb20u", + "dHdpbmUudGFuZ28ucG1yLnN5bmNocm9uaXphdGlvbmIGcHJvdG8z")); + descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, + new pbr::FileDescriptor[] { }, + new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Synchronization.CheckForUpdateResponse), global::Tango.PMR.Synchronization.CheckForUpdateResponse.Parser, new[]{ "IsUpdateAvailable", "Version" }, null, null, null) + })); + } + #endregion + + } + #region Messages + public sealed partial class CheckForUpdateResponse : pb::IMessage<CheckForUpdateResponse> { + private static readonly pb::MessageParser<CheckForUpdateResponse> _parser = new pb::MessageParser<CheckForUpdateResponse>(() => new CheckForUpdateResponse()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser<CheckForUpdateResponse> Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::Tango.PMR.Synchronization.CheckForUpdateResponseReflection.Descriptor.MessageTypes[0]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public CheckForUpdateResponse() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public CheckForUpdateResponse(CheckForUpdateResponse other) : this() { + isUpdateAvailable_ = other.isUpdateAvailable_; + version_ = other.version_; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public CheckForUpdateResponse Clone() { + return new CheckForUpdateResponse(this); + } + + /// <summary>Field number for the "IsUpdateAvailable" field.</summary> + public const int IsUpdateAvailableFieldNumber = 1; + private bool isUpdateAvailable_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool IsUpdateAvailable { + get { return isUpdateAvailable_; } + set { + isUpdateAvailable_ = value; + } + } + + /// <summary>Field number for the "Version" field.</summary> + public const int VersionFieldNumber = 2; + private string version_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string Version { + get { return version_; } + set { + version_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as CheckForUpdateResponse); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(CheckForUpdateResponse other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (IsUpdateAvailable != other.IsUpdateAvailable) return false; + if (Version != other.Version) return false; + return true; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (IsUpdateAvailable != false) hash ^= IsUpdateAvailable.GetHashCode(); + if (Version.Length != 0) hash ^= Version.GetHashCode(); + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + if (IsUpdateAvailable != false) { + output.WriteRawTag(8); + output.WriteBool(IsUpdateAvailable); + } + if (Version.Length != 0) { + output.WriteRawTag(18); + output.WriteString(Version); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (IsUpdateAvailable != false) { + size += 1 + 1; + } + if (Version.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Version); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(CheckForUpdateResponse other) { + if (other == null) { + return; + } + if (other.IsUpdateAvailable != false) { + IsUpdateAvailable = other.IsUpdateAvailable; + } + if (other.Version.Length != 0) { + Version = other.Version; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + input.SkipLastField(); + break; + case 8: { + IsUpdateAvailable = input.ReadBool(); + break; + } + case 18: { + Version = input.ReadString(); + break; + } + } + } + } + + } + + #endregion + +} + +#endregion Designer generated code diff --git a/Software/Visual_Studio/Tango.PMR/Synchronization/DownloadUpdateRequest.cs b/Software/Visual_Studio/Tango.PMR/Synchronization/DownloadUpdateRequest.cs new file mode 100644 index 000000000..26a0eb8ff --- /dev/null +++ b/Software/Visual_Studio/Tango.PMR/Synchronization/DownloadUpdateRequest.cs @@ -0,0 +1,160 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: DownloadUpdateRequest.proto +#pragma warning disable 1591, 0612, 3021 +#region Designer generated code + +using pb = global::Google.Protobuf; +using pbc = global::Google.Protobuf.Collections; +using pbr = global::Google.Protobuf.Reflection; +using scg = global::System.Collections.Generic; +namespace Tango.PMR.Synchronization { + + /// <summary>Holder for reflection information generated from DownloadUpdateRequest.proto</summary> + public static partial class DownloadUpdateRequestReflection { + + #region Descriptor + /// <summary>File descriptor for DownloadUpdateRequest.proto</summary> + public static pbr::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbr::FileDescriptor descriptor; + + static DownloadUpdateRequestReflection() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "ChtEb3dubG9hZFVwZGF0ZVJlcXVlc3QucHJvdG8SGVRhbmdvLlBNUi5TeW5j", + "aHJvbml6YXRpb24iLQoVRG93bmxvYWRVcGRhdGVSZXF1ZXN0EhQKDFNlcmlh", + "bE51bWJlchgBIAEoCUIlCiNjb20udHdpbmUudGFuZ28ucG1yLnN5bmNocm9u", + "aXphdGlvbmIGcHJvdG8z")); + descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, + new pbr::FileDescriptor[] { }, + new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Synchronization.DownloadUpdateRequest), global::Tango.PMR.Synchronization.DownloadUpdateRequest.Parser, new[]{ "SerialNumber" }, null, null, null) + })); + } + #endregion + + } + #region Messages + public sealed partial class DownloadUpdateRequest : pb::IMessage<DownloadUpdateRequest> { + private static readonly pb::MessageParser<DownloadUpdateRequest> _parser = new pb::MessageParser<DownloadUpdateRequest>(() => new DownloadUpdateRequest()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser<DownloadUpdateRequest> Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::Tango.PMR.Synchronization.DownloadUpdateRequestReflection.Descriptor.MessageTypes[0]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public DownloadUpdateRequest() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public DownloadUpdateRequest(DownloadUpdateRequest other) : this() { + serialNumber_ = other.serialNumber_; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public DownloadUpdateRequest Clone() { + return new DownloadUpdateRequest(this); + } + + /// <summary>Field number for the "SerialNumber" field.</summary> + public const int SerialNumberFieldNumber = 1; + private string serialNumber_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string SerialNumber { + get { return serialNumber_; } + set { + serialNumber_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as DownloadUpdateRequest); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(DownloadUpdateRequest other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (SerialNumber != other.SerialNumber) return false; + return true; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (SerialNumber.Length != 0) hash ^= SerialNumber.GetHashCode(); + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + if (SerialNumber.Length != 0) { + output.WriteRawTag(10); + output.WriteString(SerialNumber); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (SerialNumber.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(SerialNumber); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(DownloadUpdateRequest other) { + if (other == null) { + return; + } + if (other.SerialNumber.Length != 0) { + SerialNumber = other.SerialNumber; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + input.SkipLastField(); + break; + case 10: { + SerialNumber = input.ReadString(); + break; + } + } + } + } + + } + + #endregion + +} + +#endregion Designer generated code diff --git a/Software/Visual_Studio/Tango.PMR/Synchronization/DownloadUpdateResponse.cs b/Software/Visual_Studio/Tango.PMR/Synchronization/DownloadUpdateResponse.cs new file mode 100644 index 000000000..373f68b5d --- /dev/null +++ b/Software/Visual_Studio/Tango.PMR/Synchronization/DownloadUpdateResponse.cs @@ -0,0 +1,359 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: DownloadUpdateResponse.proto +#pragma warning disable 1591, 0612, 3021 +#region Designer generated code + +using pb = global::Google.Protobuf; +using pbc = global::Google.Protobuf.Collections; +using pbr = global::Google.Protobuf.Reflection; +using scg = global::System.Collections.Generic; +namespace Tango.PMR.Synchronization { + + /// <summary>Holder for reflection information generated from DownloadUpdateResponse.proto</summary> + public static partial class DownloadUpdateResponseReflection { + + #region Descriptor + /// <summary>File descriptor for DownloadUpdateResponse.proto</summary> + public static pbr::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbr::FileDescriptor descriptor; + + static DownloadUpdateResponseReflection() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "ChxEb3dubG9hZFVwZGF0ZVJlc3BvbnNlLnByb3RvEhlUYW5nby5QTVIuU3lu", + "Y2hyb25pemF0aW9uIrcBChZEb3dubG9hZFVwZGF0ZVJlc3BvbnNlEg8KB1Zl", + "cnNpb24YASABKAkSEgoKRnRwQWRkcmVzcxgCIAEoCRITCgtGdHBGaWxlUGF0", + "aBgDIAEoCRITCgtGdHBVc2VyTmFtZRgEIAEoCRITCgtGdHBQYXNzd29yZBgF", + "IAEoCRIRCglEYkFkZHJlc3MYBiABKAkSEgoKRGJVc2VyTmFtZRgHIAEoCRIS", + "CgpEYlBhc3N3b3JkGAggASgJQiUKI2NvbS50d2luZS50YW5nby5wbXIuc3lu", + "Y2hyb25pemF0aW9uYgZwcm90bzM=")); + descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, + new pbr::FileDescriptor[] { }, + new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Synchronization.DownloadUpdateResponse), global::Tango.PMR.Synchronization.DownloadUpdateResponse.Parser, new[]{ "Version", "FtpAddress", "FtpFilePath", "FtpUserName", "FtpPassword", "DbAddress", "DbUserName", "DbPassword" }, null, null, null) + })); + } + #endregion + + } + #region Messages + public sealed partial class DownloadUpdateResponse : pb::IMessage<DownloadUpdateResponse> { + private static readonly pb::MessageParser<DownloadUpdateResponse> _parser = new pb::MessageParser<DownloadUpdateResponse>(() => new DownloadUpdateResponse()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser<DownloadUpdateResponse> Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::Tango.PMR.Synchronization.DownloadUpdateResponseReflection.Descriptor.MessageTypes[0]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public DownloadUpdateResponse() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public DownloadUpdateResponse(DownloadUpdateResponse other) : this() { + version_ = other.version_; + ftpAddress_ = other.ftpAddress_; + ftpFilePath_ = other.ftpFilePath_; + ftpUserName_ = other.ftpUserName_; + ftpPassword_ = other.ftpPassword_; + dbAddress_ = other.dbAddress_; + dbUserName_ = other.dbUserName_; + dbPassword_ = other.dbPassword_; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public DownloadUpdateResponse Clone() { + return new DownloadUpdateResponse(this); + } + + /// <summary>Field number for the "Version" field.</summary> + public const int VersionFieldNumber = 1; + private string version_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string Version { + get { return version_; } + set { + version_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// <summary>Field number for the "FtpAddress" field.</summary> + public const int FtpAddressFieldNumber = 2; + private string ftpAddress_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string FtpAddress { + get { return ftpAddress_; } + set { + ftpAddress_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// <summary>Field number for the "FtpFilePath" field.</summary> + public const int FtpFilePathFieldNumber = 3; + private string ftpFilePath_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string FtpFilePath { + get { return ftpFilePath_; } + set { + ftpFilePath_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// <summary>Field number for the "FtpUserName" field.</summary> + public const int FtpUserNameFieldNumber = 4; + private string ftpUserName_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string FtpUserName { + get { return ftpUserName_; } + set { + ftpUserName_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// <summary>Field number for the "FtpPassword" field.</summary> + public const int FtpPasswordFieldNumber = 5; + private string ftpPassword_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string FtpPassword { + get { return ftpPassword_; } + set { + ftpPassword_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// <summary>Field number for the "DbAddress" field.</summary> + public const int DbAddressFieldNumber = 6; + private string dbAddress_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string DbAddress { + get { return dbAddress_; } + set { + dbAddress_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// <summary>Field number for the "DbUserName" field.</summary> + public const int DbUserNameFieldNumber = 7; + private string dbUserName_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string DbUserName { + get { return dbUserName_; } + set { + dbUserName_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// <summary>Field number for the "DbPassword" field.</summary> + public const int DbPasswordFieldNumber = 8; + private string dbPassword_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string DbPassword { + get { return dbPassword_; } + set { + dbPassword_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as DownloadUpdateResponse); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(DownloadUpdateResponse other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Version != other.Version) return false; + if (FtpAddress != other.FtpAddress) return false; + if (FtpFilePath != other.FtpFilePath) return false; + if (FtpUserName != other.FtpUserName) return false; + if (FtpPassword != other.FtpPassword) return false; + if (DbAddress != other.DbAddress) return false; + if (DbUserName != other.DbUserName) return false; + if (DbPassword != other.DbPassword) return false; + return true; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (Version.Length != 0) hash ^= Version.GetHashCode(); + if (FtpAddress.Length != 0) hash ^= FtpAddress.GetHashCode(); + if (FtpFilePath.Length != 0) hash ^= FtpFilePath.GetHashCode(); + if (FtpUserName.Length != 0) hash ^= FtpUserName.GetHashCode(); + if (FtpPassword.Length != 0) hash ^= FtpPassword.GetHashCode(); + if (DbAddress.Length != 0) hash ^= DbAddress.GetHashCode(); + if (DbUserName.Length != 0) hash ^= DbUserName.GetHashCode(); + if (DbPassword.Length != 0) hash ^= DbPassword.GetHashCode(); + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + if (Version.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Version); + } + if (FtpAddress.Length != 0) { + output.WriteRawTag(18); + output.WriteString(FtpAddress); + } + if (FtpFilePath.Length != 0) { + output.WriteRawTag(26); + output.WriteString(FtpFilePath); + } + if (FtpUserName.Length != 0) { + output.WriteRawTag(34); + output.WriteString(FtpUserName); + } + if (FtpPassword.Length != 0) { + output.WriteRawTag(42); + output.WriteString(FtpPassword); + } + if (DbAddress.Length != 0) { + output.WriteRawTag(50); + output.WriteString(DbAddress); + } + if (DbUserName.Length != 0) { + output.WriteRawTag(58); + output.WriteString(DbUserName); + } + if (DbPassword.Length != 0) { + output.WriteRawTag(66); + output.WriteString(DbPassword); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (Version.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Version); + } + if (FtpAddress.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(FtpAddress); + } + if (FtpFilePath.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(FtpFilePath); + } + if (FtpUserName.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(FtpUserName); + } + if (FtpPassword.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(FtpPassword); + } + if (DbAddress.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(DbAddress); + } + if (DbUserName.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(DbUserName); + } + if (DbPassword.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(DbPassword); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(DownloadUpdateResponse other) { + if (other == null) { + return; + } + if (other.Version.Length != 0) { + Version = other.Version; + } + if (other.FtpAddress.Length != 0) { + FtpAddress = other.FtpAddress; + } + if (other.FtpFilePath.Length != 0) { + FtpFilePath = other.FtpFilePath; + } + if (other.FtpUserName.Length != 0) { + FtpUserName = other.FtpUserName; + } + if (other.FtpPassword.Length != 0) { + FtpPassword = other.FtpPassword; + } + if (other.DbAddress.Length != 0) { + DbAddress = other.DbAddress; + } + if (other.DbUserName.Length != 0) { + DbUserName = other.DbUserName; + } + if (other.DbPassword.Length != 0) { + DbPassword = other.DbPassword; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + input.SkipLastField(); + break; + case 10: { + Version = input.ReadString(); + break; + } + case 18: { + FtpAddress = input.ReadString(); + break; + } + case 26: { + FtpFilePath = input.ReadString(); + break; + } + case 34: { + FtpUserName = input.ReadString(); + break; + } + case 42: { + FtpPassword = input.ReadString(); + break; + } + case 50: { + DbAddress = input.ReadString(); + break; + } + case 58: { + DbUserName = input.ReadString(); + break; + } + case 66: { + DbPassword = input.ReadString(); + break; + } + } + } + } + + } + + #endregion + +} + +#endregion Designer generated code diff --git a/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj b/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj index 4090031e9..d2ea08115 100644 --- a/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj +++ b/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj @@ -191,7 +191,14 @@ <Compile Include="Common\MessageContainer.cs" /> <Compile Include="Common\MessageType.cs" /> <Compile Include="Stubs\*.cs" /> - <Compile Include="Synchronization\*.cs" /> + <Compile Include="Synchronization\MachineSetupRequest.cs" /> + <Compile Include="Synchronization\MachineSetupResponse.cs" /> + <Compile Include="Synchronization\SynchronizeDBRequest.cs" /> + <Compile Include="Synchronization\SynchronizeDBResponse.cs" /> + <Compile Include="Synchronization\CheckForUpdateRequest.cs" /> + <Compile Include="Synchronization\CheckForUpdateResponse.cs" /> + <Compile Include="Synchronization\DownloadUpdateRequest.cs" /> + <Compile Include="Synchronization\DownloadUpdateResponse.cs" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\Utilities\Tango.Protobuf.CLI\Tango.Protobuf.CLI.csproj"> @@ -208,7 +215,7 @@ </PropertyGroup> <ProjectExtensions> <VisualStudio> - <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" /> + <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" /> </VisualStudio> </ProjectExtensions> </Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/Tango.SharedUI/Controls/NavigationControl.cs b/Software/Visual_Studio/Tango.SharedUI/Controls/NavigationControl.cs index d21a562fd..d7af7200e 100644 --- a/Software/Visual_Studio/Tango.SharedUI/Controls/NavigationControl.cs +++ b/Software/Visual_Studio/Tango.SharedUI/Controls/NavigationControl.cs @@ -356,8 +356,10 @@ namespace Tango.SharedUI.Controls private void Navigate(NavigationElement fromElement, NavigationElement toElement) { - if (toElement == null) return; - if (toElement == fromElement) return; + if (toElement == null || toElement == fromElement) + { + _onCompleted?.Invoke(); + } if (fromElement != null) { @@ -516,7 +518,14 @@ namespace Tango.SharedUI.Controls if (element != null) { - SelectedElement = element; + if (SelectedElement == element) + { + _onCompleted?.Invoke(); + } + else + { + SelectedElement = element; + } } return element; diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/SynchronizationController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/SynchronizationController.cs index 8054aae8c..e4e01e7d1 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/SynchronizationController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/SynchronizationController.cs @@ -125,6 +125,102 @@ namespace Tango.MachineService.Controllers return response; } + [HttpPost] + public DownloadUpdateResponse MachineUpdate(DownloadUpdateRequest request) + { + DownloadUpdateResponse response = new DownloadUpdateResponse(); + + try + { + using (ObservablesContext db = ObservablesContext.CreateDefault(GetLocalServerAddress())) + { + db.Configuration.LazyLoadingEnabled = false; + String serial_number = request.SerialNumber; + + var machine = db.Machines.SingleOrDefault(x => x.SerialNumber == serial_number); + + if (machine == null) + { + OnError(HttpStatusCode.NotFound, "The specified serial number could not be found."); + } + + var machine_version = db.MachineVersions.SingleOrDefault(x => x.Guid == machine.MachineVersionGuid); + + var latest_machine_version = db.TangoVersions.Where(x => x.MachineVersionGuid == machine_version.Guid).ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); + + response.Version = latest_machine_version.Version; + + response.FtpAddress = GetFtpAddress(); + response.FtpFilePath = latest_machine_version.FtpFilePath; + response.FtpUserName = GetFtpUserName(); + response.FtpPassword = GetFtpPassword(); + + DbCredentials credentials = new DbCredentials(); + + using (DbManager manager = DbManager.FromAddressAndName(GetDbAddress(), "Tango")) + { + credentials = manager.CreateRandomLoginAndUser("Tango"); + + Task.Delay(TimeSpan.FromMinutes(10)).ContinueWith((x) => + { + using (DbManager m = DbManager.FromAddressAndName(GetDbAddress(), "Tango")) + { + m.DeleteLoginAndUser(credentials.UserName, "Tango"); + } + }); + } + + response.DbAddress = GetDbAddress(); + response.DbUserName = credentials.UserName; + response.DbPassword = credentials.Password; + } + } + catch (Exception ex) + { + OnError(HttpStatusCode.InternalServerError, ex.Message); + } + + return response; + } + + [HttpPost] + public CheckForUpdateResponse CheckForUpdate(CheckForUpdateRequest request) + { + CheckForUpdateResponse response = new CheckForUpdateResponse(); + + try + { + using (ObservablesContext db = ObservablesContext.CreateDefault(GetLocalServerAddress())) + { + db.Configuration.LazyLoadingEnabled = false; + + var machine = db.Machines.SingleOrDefault(x => x.SerialNumber == request.SerialNumber); + + if (machine == null) + { + OnError(HttpStatusCode.NotFound, "The specified serial number could not be found."); + } + + var machine_version = db.MachineVersions.SingleOrDefault(x => x.Guid == machine.MachineVersionGuid); + + var latest_machine_version = db.TangoVersions.Where(x => x.MachineVersionGuid == machine_version.Guid).ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); + + if (Version.Parse(latest_machine_version.Version) > Version.Parse(request.Version)) + { + response.IsUpdateAvailable = true; + } + + response.Version = latest_machine_version.Version; + } + } + catch (Exception ex) + { + OnError(HttpStatusCode.InternalServerError, ex.Message); + } + + return response; + } + #region Helpers private void OnError(HttpStatusCode code, String message) |
