From e29d962c5602fc9fc3a54fa4da8957609de7eea4 Mon Sep 17 00:00:00 2001 From: Roy Ben-Shabat Date: Sun, 17 Feb 2019 15:52:11 +0200 Subject: Completed PPC watchdog ! --- .../ViewModels/FirmwareUpgradeViewVM.cs | 1 - .../PPC/Tango.PPC.Common/PPCSettings.cs | 6 + .../Tango.PPC.Common/WatchDog/WatchDogClient.cs | 87 ++++++++++- .../Tango.PPC.Common/WatchDog/WatchDogServer.cs | 108 ++++++++++++-- .../Visual_Studio/PPC/Tango.PPC.UI/App.xaml.cs | 1 + .../PPC/Tango.PPC.UI/MainWindow.xaml.cs | 2 +- .../PPCApplication/DefaultPPCApplicationManager.cs | 44 +++++- .../Tango.PPC.UI/ViewModels/MachineSetupViewVM.cs | 4 +- .../Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs | 2 +- .../PPC/Tango.PPC.UI/ViewModels/MainViewVM.cs | 1 + .../PPC/Tango.PPC.WatchDog/App.xaml.cs | 12 ++ .../PPC/Tango.PPC.WatchDog/MainWindow.xaml | 37 +++-- .../PPC/Tango.PPC.WatchDog/MainWindow.xaml.cs | 44 ++++++ .../PPC/Tango.PPC.WatchDog/MainWindowVM.cs | 107 ++++++++++++++ .../Tango.PPC.WatchDog/Tango.PPC.WatchDog.csproj | 16 +- .../Visual_Studio/PPC/Tango.PPC.WatchDog/cat24.ico | Bin 0 -> 105237 bytes .../Visual_Studio/PPC/Tango.PPC.WatchDog/close.png | Bin 651 -> 0 bytes .../Tango.SharedUI/Components/TextController.cs | 163 +++++++++++++++++++++ .../Tango.SharedUI/Tango.SharedUI.csproj | 3 +- 19 files changed, 598 insertions(+), 40 deletions(-) create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.WatchDog/cat24.ico delete mode 100644 Software/Visual_Studio/PPC/Tango.PPC.WatchDog/close.png create mode 100644 Software/Visual_Studio/Tango.SharedUI/Components/TextController.cs (limited to 'Software/Visual_Studio') diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/FirmwareUpgradeViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/FirmwareUpgradeViewVM.cs index e3726f1dd..e54c28e17 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/FirmwareUpgradeViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/FirmwareUpgradeViewVM.cs @@ -89,7 +89,6 @@ namespace Tango.MachineStudio.UI.ViewModels public FirmwareUpgradeViewVM(IMachineOperator machineOperator, INotificationProvider notificationProvider) : base() { DFU = true; - UploadTFP = true; _notification = notificationProvider; _operator = machineOperator; SelectCommand = new RelayCommand(BrowseForFile); diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/PPCSettings.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/PPCSettings.cs index 7b617ddaa..409dd1cfc 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/PPCSettings.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/PPCSettings.cs @@ -71,6 +71,11 @@ namespace Tango.PPC.Common /// public DeploymentSlot DeploymentSlot { get; set; } + /// + /// Gets or sets a value indicating whether to enable the watch dog process. + /// + public bool EnableWatchDog { get; set; } + /// /// Gets the machine service address. /// @@ -91,6 +96,7 @@ namespace Tango.PPC.Common ExternalBridgePassword = "Aa123456"; HotSpotPassword = "Aa123456"; DeploymentSlot = DeploymentSlot.TEST; + EnableWatchDog = true; } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/WatchDog/WatchDogClient.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/WatchDog/WatchDogClient.cs index 47a24ea85..bbdfbf7e2 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/WatchDog/WatchDogClient.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/WatchDog/WatchDogClient.cs @@ -1,12 +1,97 @@ using System; using System.Collections.Generic; +using System.IO; +using System.IO.Pipes; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; +using Tango.Core; namespace Tango.PPC.Common.WatchDog { - public class WatchDogClient + public class WatchDogClient : ExtendedObject { + public event EventHandler ServerNotResponding; + + private NamedPipeClientStream _client; + private StreamReader _reader; + private StreamWriter _writer; + private Thread _thread; + + public bool IsStarted { get; private set; } + + public TimeSpan Interval { get; set; } + + public WatchDogClient() + { + Interval = TimeSpan.FromSeconds(5); + } + + public void Start() + { + if (!IsStarted) + { + LogManager.Log("Starting watchdog client..."); + + IsStarted = true; + + _thread = new Thread(ThreadMethod); + _thread.IsBackground = true; + _thread.Start(); + } + } + + private void ThreadMethod() + { + try + { + LogManager.Log("Watchdog client started."); + + while (IsStarted) + { + _client = new NamedPipeClientStream("Tango_Watch_Dog_Pipe"); + _client.Connect(5000); + + _reader = new StreamReader(_client); + _writer = new StreamWriter(_client); + + _writer.WriteLine("ping"); + _writer.Flush(); + + var line = _reader.ReadLine(); + + if (line != "ping") + { + LogManager.Log("Watchdog server not found. Raising notification..."); + try + { + IsStarted = false; + _client.Dispose(); + } + catch { } + + ServerNotResponding?.Invoke(this, new EventArgs()); + return; + } + + _client.Dispose(); + + Thread.Sleep(Interval); + } + } + catch (Exception ex) + { + IsStarted = false; + LogManager.Log(ex, "Error in watchdog client."); + ServerNotResponding?.Invoke(this, new EventArgs()); + } + } + + public void Stop() + { + IsStarted = false; + _client.Dispose(); + } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/WatchDog/WatchDogServer.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/WatchDog/WatchDogServer.cs index 77bca2e30..84ff68d08 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/WatchDog/WatchDogServer.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/WatchDog/WatchDogServer.cs @@ -1,26 +1,60 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.IO.Pipes; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; +using System.Windows.Threading; +using Tango.Core; +using Tango.Core.Helpers; namespace Tango.PPC.Common.WatchDog { - public class WatchDogServer + public class WatchDogServer : ExtendedObject, IDisposable { private NamedPipeServerStream _server; + private StreamReader _reader; + private StreamWriter _writer; private Thread _thread; + private Dispatcher _dispatcher; + private String _watchdogAppPath; + private Process _watchdogProcess; public bool IsStarted { get; private set; } + public WatchDogServer(Dispatcher uiDispatcher) + { + _watchdogAppPath = Path.Combine(AssemblyHelper.GetCurrentAssemblyFolder(), "Tango.PPC.WatchDog.exe"); + + _dispatcher = uiDispatcher; + } + public void Start() { - _thread = new Thread(ThreadMethod); - _thread.IsBackground = true; - _thread.Start(); + LogManager.Log("Starting watchdog server..."); + + try + { + _watchdogProcess = Process.GetProcessesByName("Tango.PPC.WatchDog").FirstOrDefault(); + + _server = new NamedPipeServerStream("Tango_Watch_Dog_Pipe"); + _reader = new StreamReader(_server); + _writer = new StreamWriter(_server); + + IsStarted = true; + _thread = new Thread(ThreadMethod); + _thread.IsBackground = true; + _thread.Start(); + + LogManager.Log("Watchdog server started."); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error starting watchdog server!"); + } } private void ThreadMethod() @@ -29,27 +63,73 @@ namespace Tango.PPC.Common.WatchDog try { - _server = new NamedPipeServerStream("Tango_Watch_Dog_Pipe"); - _server.WaitForConnection(); - StreamReader reader = new StreamReader(_server); - StreamWriter writer = new StreamWriter(_server); - while (IsStarted) { - var line = reader.ReadLine(); - writer.WriteLine(line); - writer.Flush(); + if (_watchdogProcess == null) + { + LogManager.Log($"Starting watchdog process at '{_watchdogAppPath}'..."); + + try + { + _watchdogProcess = Process.Start(_watchdogAppPath); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error starting watchdog process!"); + return; + } + } + + _server.WaitForConnection(); + + var line = _reader.ReadLine(); + + _dispatcher.Invoke(() => + { + _writer.WriteLine(line); + _writer.Flush(); + }); + + _server.Disconnect(); } } - catch + catch (Exception ex) { + LogManager.Log(ex, "Error in watchdog server. Restarting watchdog..."); IsStarted = false; + + try + { + _server.Dispose(); + } + catch { } + + Start(); + return; } } public void Stop() { - _server.Dispose(); + if (IsStarted) + { + try + { + _watchdogProcess.Kill(); + _watchdogProcess = null; + } + catch (Exception ex) + { + LogManager.Log(ex, "Error killing watchdog process!"); + } + IsStarted = false; + _server.Dispose(); + } + } + + public void Dispose() + { + Stop(); } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/App.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/App.xaml.cs index 98ed016ae..0eb982d08 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/App.xaml.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/App.xaml.cs @@ -12,6 +12,7 @@ using Tango.Core; using Tango.Core.Helpers; using Tango.Logging; using Tango.PPC.Common; +using Tango.PPC.Common.WatchDog; using Tango.Settings; namespace Tango.PPC.UI diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/MainWindow.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/MainWindow.xaml.cs index 4ca4a1fb7..edc7cce52 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/MainWindow.xaml.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/MainWindow.xaml.cs @@ -89,7 +89,7 @@ namespace Tango.PPC.UI private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) { - Environment.Exit(0); + TangoIOC.Default.GetInstance().ShutDown(); } protected override void OnPreviewKeyDown(System.Windows.Input.KeyEventArgs e) 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 39ce8cd30..43b0cc047 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs @@ -27,6 +27,7 @@ using System.Diagnostics; using Tango.PPC.Common.EventLogging; using Tango.BL.Enumerations; using Tango.PPC.Common.Notifications; +using Tango.PPC.Common.WatchDog; namespace Tango.PPC.UI.PPCApplication { @@ -44,6 +45,7 @@ namespace Tango.PPC.UI.PPCApplication private IEventLogger _eventLogger; private IPPCModuleLoader _moduleLoader; private INotificationProvider _notificationProvider; + private WatchDogServer _watchdogServer; /// /// Occurs when a system restart is required. @@ -157,6 +159,14 @@ namespace Tango.PPC.UI.PPCApplication LogManager.Log(settings.ToJsonString()); + //Start watchdog + _watchdogServer = new WatchDogServer(Application.Current.Dispatcher); + + if (settings.EnableWatchDog) + { + _watchdogServer.Start(); + } + LogManager.Log("Reading Core settings..."); var coreSettings = SettingsManager.Default.GetOrCreate(); @@ -323,16 +333,23 @@ namespace Tango.PPC.UI.PPCApplication /// public void ShutDown() { - //TODO: Needs some work on logging and shutdown procedures! Do I really need this? - - LogManager.Log("Shutting down application..."); + if (IsShuttingDown) return; IsShuttingDown = true; - foreach (var vm in TangoIOC.Default.GetAllInstancesByBase()) + try { - vm.OnApplicationShuttingDown(); + LogManager.Log("Shutting down application..."); + _watchdogServer.Dispose(); + + foreach (var vm in TangoIOC.Default.GetAllInstancesByBase()) + { + vm.OnApplicationShuttingDown(); + } } + catch { } + + Environment.Exit(0); } /// @@ -340,6 +357,23 @@ namespace Tango.PPC.UI.PPCApplication /// public void Restart() { + if (IsShuttingDown) return; + + IsShuttingDown = true; + + try + { + LogManager.Log("Restarting the application..."); + + _watchdogServer.Dispose(); + + foreach (var vm in TangoIOC.Default.GetAllInstancesByBase()) + { + vm.OnApplicationShuttingDown(); + } + } + catch { } + Process.Start(Application.ResourceAssembly.Location); Environment.Exit(0); } 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 ee1b39ca6..48aae2b8f 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineSetupViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineSetupViewVM.cs @@ -59,6 +59,7 @@ namespace Tango.PPC.UI.ViewModels private MachineSetupResult _setup_result; private IOperationSystemManager _operationSystemManager; + private IPPCApplicationManager _appManager; #region Properties @@ -193,6 +194,7 @@ namespace Tango.PPC.UI.ViewModels /// The machine setup manager. public MachineSetupViewVM(IPPCApplicationManager applicationManager, IMachineSetupManager machineSetupManager, IOperationSystemManager operationSystemManager) { + _appManager = applicationManager; MachineSetupManager = machineSetupManager; DeploymentSlot = Settings.DeploymentSlot; @@ -282,7 +284,7 @@ namespace Tango.PPC.UI.ViewModels LogManager.Log($"Executing '{updater_exe}' with arguments '{PathHelper.GetStartupPath()}'..."); Process.Start(updater_exe, PathHelper.GetStartupPath()); LogManager.Log("Terminating application process!"); - Environment.Exit(0); + _appManager.ShutDown(); } /// diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs index 07d034964..2f6199ecb 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs @@ -220,7 +220,7 @@ namespace Tango.PPC.UI.ViewModels LogManager.Log($"Executing '{updater_exe}' with arguments '{PathHelper.GetStartupPath()}'..."); Process.Start(updater_exe, PathHelper.GetStartupPath()); LogManager.Log("Terminating application process!"); - Environment.Exit(0); + ApplicationManager.ShutDown(); } else { diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MainViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MainViewVM.cs index b01be3734..a4f550a39 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MainViewVM.cs @@ -13,6 +13,7 @@ using Tango.PPC.Common.ExternalBridge; using Tango.PPC.Common.Modules; using Tango.PPC.Common.Navigation; using Tango.PPC.Common.Notifications; +using Tango.PPC.Common.WatchDog; using Tango.SharedUI; namespace Tango.PPC.UI.ViewModels diff --git a/Software/Visual_Studio/PPC/Tango.PPC.WatchDog/App.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.WatchDog/App.xaml.cs index 3e39963bd..2247b95e5 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.WatchDog/App.xaml.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.WatchDog/App.xaml.cs @@ -5,6 +5,7 @@ using System.Data; using System.Linq; using System.Threading.Tasks; using System.Windows; +using Tango.Logging; namespace Tango.PPC.WatchDog { @@ -13,5 +14,16 @@ namespace Tango.PPC.WatchDog /// public partial class App : Application { + private LogManager LogManager = LogManager.Default; + + protected override void OnStartup(StartupEventArgs e) + { + LogManager.RegisterLogger(new FileLogger()); + LogManager.RegisterLogger(new VSOutputLogger()); + + LogManager.Log("Watchdog process started..."); + + base.OnStartup(e); + } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.WatchDog/MainWindow.xaml b/Software/Visual_Studio/PPC/Tango.PPC.WatchDog/MainWindow.xaml index 4e772e774..82056048e 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.WatchDog/MainWindow.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.WatchDog/MainWindow.xaml @@ -3,31 +3,44 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:components="clr-namespace:Tango.SharedUI.Components;assembly=Tango.SharedUI" xmlns:local="clr-namespace:Tango.PPC.WatchDog" mc:Ignorable="d" - Title="Tango Watch Dog" Background="Transparent" AllowsTransparency="True" Height="250" Width="500" WindowStartupLocation="CenterScreen" WindowStyle="None" ResizeMode="NoResize" Icon="/cat.png" + Title="Tango WatchDog" Visibility="Visible" Background="Transparent" AllowsTransparency="True" Height="400" Width="700" WindowStartupLocation="CenterScreen" WindowStyle="None" ResizeMode="NoResize" Icon="/cat.png" d:DataContext="{d:DesignInstance Type=local:MainWindowVM, IsDesignTimeCreatable=False}"> - + - + - Tango Watch Dog - + Tango WatchDog + + + + + - + + + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.WatchDog/MainWindow.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.WatchDog/MainWindow.xaml.cs index 585fc3510..1e3c90342 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.WatchDog/MainWindow.xaml.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.WatchDog/MainWindow.xaml.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -7,11 +8,14 @@ using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; +using System.Windows.Forms; using System.Windows.Input; +using System.Windows.Interop; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; +using Tango.SharedUI.Helpers; namespace Tango.PPC.WatchDog { @@ -20,10 +24,50 @@ namespace Tango.PPC.WatchDog /// public partial class MainWindow : Window { + private NotifyIcon _icon; + public MainWindow() { InitializeComponent(); DataContext = new MainWindowVM(); + Visibility = Visibility.Hidden; + + var helper = new WindowInteropHelper(this); + helper.EnsureHandle(); + + _icon = new NotifyIcon(); + _icon.Icon = new System.Drawing.Icon(Core.Helpers.EmbeddedResourceHelper.GetEmbeddedResourceStream("Tango.PPC.WatchDog.cat24.ico")); + _icon.BalloonTipIcon = ToolTipIcon.Info; + _icon.BalloonTipTitle = Title; + _icon.BalloonTipText = "Working..."; + _icon.Click += _icon_Click; + _icon.Visible = true; + } + + private void _icon_Click(object sender, EventArgs e) + { + _icon.Visible = false; + Show(); + } + + private void Button_Click(object sender, RoutedEventArgs e) + { + _icon.Visible = true; + Hide(); + } + + protected override void OnClosing(CancelEventArgs e) + { + _icon.Visible = false; + _icon.Dispose(); + base.OnClosing(e); + } + + private void Button_Click_1(object sender, RoutedEventArgs e) + { + _icon.Visible = false; + _icon.Dispose(); + Environment.Exit(0); } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.WatchDog/MainWindowVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.WatchDog/MainWindowVM.cs index a95a9503c..466c178a2 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.WatchDog/MainWindowVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.WatchDog/MainWindowVM.cs @@ -1,14 +1,121 @@ using System; using System.Collections.Generic; +using System.Diagnostics; +using System.IO; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; +using Tango.Core.Helpers; +using Tango.Logging; +using Tango.PPC.Common.WatchDog; using Tango.SharedUI; +using Tango.SharedUI.Components; namespace Tango.PPC.WatchDog { public class MainWindowVM : ViewModel { + private const String tango_process_name = "Tango.PPC.UI"; + private WatchDogClient _watchdog; + public TextController Log { get; set; } + public MainWindowVM() + { + var logger = new SimpleStringLogger(); + logger.LogReceived += Logger_LogReceived; + LogManager.RegisterLogger(logger); + + _watchdog = new WatchDogClient(); + _watchdog.ServerNotResponding += _watchdog_ServerNotResponding; + Log = new TextController(); + + _watchdog.Start(); + } + + private void Logger_LogReceived(object sender, LogItemBase e) + { + if (e is ExceptionLogItem) + { + Log.WriteLine(e.ToString()); + } + else + { + Log.WriteLine($"[{e.TimeStamp.ToString()}] {e.Message}"); + } + } + + private void _watchdog_ServerNotResponding(object sender, EventArgs e) + { + LogManager.Log("PPC application failed to respond!", LogCategory.Warning); + LogManager.Log("Ensuring PPC application is down..."); + + var appProcess = Process.GetProcessesByName(tango_process_name).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", tango_process_name); + + try + { + if (appProcess != null) + { + LogManager.Log("PPC application process found and seems to be frozen. Trying to kill the process..."); + appProcess.Kill(); + + appProcess = Process.GetProcessesByName(tango_process_name).FirstOrDefault(); + + if (appProcess != null) + { + LogManager.Log("Process kill failed. Trying again..."); + p.Start(); + Thread.Sleep(2000); + + appProcess = Process.GetProcessesByName(tango_process_name).FirstOrDefault(); + + if (appProcess == null) + { + LogManager.Log("PPC application is down."); + } + } + else + { + LogManager.Log("PPC application is down."); + } + } + } + catch + { + try + { + LogManager.Log("Process kill failed. Trying again..."); + p.Start(); + Thread.Sleep(2000); + + appProcess = Process.GetProcessesByName(tango_process_name).FirstOrDefault(); + + if (appProcess == null) + { + LogManager.Log("PPC application is down."); + } + } + catch { } + } + + LogManager.Log("Restarting PPC application..."); + + try + { + Process.Start(Path.Combine(AssemblyHelper.GetCurrentAssemblyFolder(), tango_process_name + ".exe")); + LogManager.Log("PPC application started."); + Thread.Sleep(5000); + _watchdog.Start(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error starting PPC application."); + } + } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.WatchDog/Tango.PPC.WatchDog.csproj b/Software/Visual_Studio/PPC/Tango.PPC.WatchDog/Tango.PPC.WatchDog.csproj index b9429e044..a1e6e5e88 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.WatchDog/Tango.PPC.WatchDog.csproj +++ b/Software/Visual_Studio/PPC/Tango.PPC.WatchDog/Tango.PPC.WatchDog.csproj @@ -37,6 +37,8 @@ + + @@ -101,18 +103,26 @@ - - - {a34ee0f0-649d-41c8-8489-b6f1cc6924ee} Tango.Core + + {BC932DBD-7CDB-488C-99E4-F02CF441F55E} + Tango.Logging + {8491d07b-c1f6-4b62-a412-41b9fd2d6538} Tango.SharedUI + + {0be74eee-22cb-4dba-b896-793b9e1a3ac0} + Tango.PPC.Common + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/PPC/Tango.PPC.WatchDog/cat24.ico b/Software/Visual_Studio/PPC/Tango.PPC.WatchDog/cat24.ico new file mode 100644 index 000000000..6fa3cb368 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.WatchDog/cat24.ico differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.WatchDog/close.png b/Software/Visual_Studio/PPC/Tango.PPC.WatchDog/close.png deleted file mode 100644 index 3a040a008..000000000 Binary files a/Software/Visual_Studio/PPC/Tango.PPC.WatchDog/close.png and /dev/null differ diff --git a/Software/Visual_Studio/Tango.SharedUI/Components/TextController.cs b/Software/Visual_Studio/Tango.SharedUI/Components/TextController.cs new file mode 100644 index 000000000..786754d6e --- /dev/null +++ b/Software/Visual_Studio/Tango.SharedUI/Components/TextController.cs @@ -0,0 +1,163 @@ +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.Controls.Primitives; + +namespace Tango.SharedUI.Components +{ + /// + /// Represents an MVVM TextBox controller + /// + /// + public class TextController : DependencyObject + { + private TextBox _textBox; + private bool _isMouseDown; + + /// + /// Determines whether an element is Controller. + /// + public static readonly DependencyProperty ControllerProperty = + DependencyProperty.RegisterAttached("Controller", + typeof(TextController), typeof(TextController), + new FrameworkPropertyMetadata(null,ControllerChanged)); + + /// + /// On controller changed. + /// + /// The d. + /// The instance containing the event data. + /// The text controller component can only handle elements of type TextBox. + private static void ControllerChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (d != null && e.NewValue != null) + { + if (!(d is TextBox)) + { + throw new ArgumentException("The text controller component can only handle elements of type TextBox."); + } + + (e.NewValue as TextController).SetTextBox(d as TextBox); + } + } + + /// + /// Sets the Controller attached property. + /// + /// The element. + /// if set to true [value]. + public static void SetController(FrameworkElement element, TextController value) + { + element.SetValue(ControllerProperty, value); + } + + /// + /// Gets the Controller attached property. + /// + /// The element. + /// + public static TextController GetController(FrameworkElement element) + { + return (TextController)element.GetValue(ControllerProperty); + } + + /// + /// Gets or sets a value indicating whether to automatically scroll to end of text. + /// + public bool AutoScrollToEnd { get; set; } + + /// + /// Initializes a new instance of the class. + /// + public TextController() + { + AutoScrollToEnd = true; + } + + /// + /// Sets the text box. + /// + /// The text box. + private void SetTextBox(TextBox textBox) + { + _textBox = textBox; + _textBox.PreviewMouseDown += (_, __) => _isMouseDown = true; + _textBox.PreviewMouseUp += (_, __) => _isMouseDown = false; + } + + /// + /// Appends the specified text. + /// + /// The text. + public void WriteLine(String text) + { + Write(text + Environment.NewLine); + } + + /// + /// Appends the specified text. + /// + /// The text. + public void Write(String text) + { + Invoke(() => + { + _textBox.AppendText(text); + + if (AutoScrollToEnd && !_isMouseDown) + { + ScrollToEnd(); + } + }); + } + + /// + /// Sets the specified text. + /// + /// The text. + public void Set(String text) + { + Invoke(() => + { + _textBox.Text = text; + + if (AutoScrollToEnd && !_isMouseDown) + { + ScrollToEnd(); + } + }); + } + + /// + /// Clears the text. + /// + public void Clear() + { + Invoke(() => + { + _textBox.Clear(); + }); + } + + /// + /// Scrolls to the end of the text. + /// + public void ScrollToEnd() + { + _textBox.ScrollToEnd(); + } + + /// + /// Invokes the specified action. + /// + /// The action. + private void Invoke(Action action) + { + Dispatcher.BeginInvoke(action); + } + } +} diff --git a/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj b/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj index 048edca82..65f2fe46b 100644 --- a/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj +++ b/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj @@ -65,6 +65,7 @@ + @@ -233,7 +234,7 @@ - + \ No newline at end of file -- cgit v1.3.1