using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Runtime.InteropServices; 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 { [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)] static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName); 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 { var process = Process.Start(Path.Combine(AssemblyHelper.GetCurrentAssemblyFolder(), tango_process_name + ".exe")); LogManager.Log("PPC application started."); LogManager.Log("Waiting for the application main window...."); if (WaitForPPCWindow(TimeSpan.FromSeconds(5), TimeSpan.FromMinutes(1))) { LogManager.Log("Application main window opened. waiting another 10 seconds..."); Thread.Sleep(TimeSpan.FromSeconds(10)); _watchdog.Start(); } else { LogManager.Log("The PPC application main window has failed to open within 1 minute. The Watchdog will not start again!"); } } catch (Exception ex) { LogManager.Log(ex, "Error starting PPC application."); } } private bool WaitForPPCWindow(TimeSpan interval, TimeSpan timeout) { for (TimeSpan time = TimeSpan.Zero; time < timeout; time = time.Add(interval)) { IntPtr windowPtr = FindWindowByCaption(IntPtr.Zero, "Tango - PPC"); if (windowPtr != IntPtr.Zero) { return true; } Thread.Sleep(interval); } return false; } } }