diff --git a/DesktopEdge/App.config b/DesktopEdge/App.config index 5ffd8f8e..f9a3ea29 100644 --- a/DesktopEdge/App.config +++ b/DesktopEdge/App.config @@ -1,5 +1,8 @@ + + + diff --git a/DesktopEdge/MainMenu.xaml b/DesktopEdge/MainMenu.xaml index b59242c2..0d2fe879 100644 --- a/DesktopEdge/MainMenu.xaml +++ b/DesktopEdge/MainMenu.xaml @@ -53,7 +53,7 @@ - + diff --git a/DesktopEdge/MainMenu.xaml.cs b/DesktopEdge/MainMenu.xaml.cs index 56d559a7..067733c7 100644 --- a/DesktopEdge/MainMenu.xaml.cs +++ b/DesktopEdge/MainMenu.xaml.cs @@ -13,6 +13,7 @@ using ZitiDesktopEdge.ServiceClient; using NLog; using ZitiDesktopEdge.DataStructures; using ZitiDesktopEdge.Native; +using System.Configuration; namespace ZitiDesktopEdge { @@ -32,6 +33,7 @@ namespace ZitiDesktopEdge public string licenseData = "it's open source."; public string LogLevel = ""; private string appVersion = null; + private bool allowReleaseSelect = false; private bool isBeta { get { @@ -42,6 +44,16 @@ namespace ZitiDesktopEdge public MainMenu() { InitializeComponent(); + try { + allowReleaseSelect = bool.Parse(ConfigurationManager.AppSettings.Get("ReleaseStreamSelect")); + } catch { + //if we can't parse the config - leave it as false... + allowReleaseSelect = false; //setting it here in case anyone changes the default above + } +#if DEBUG + Debug.WriteLine("OVERRIDING allowReleaseSelect to true!"); + allowReleaseSelect = true; +#endif appVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); LicensesItems.Text = licenseData; // don't check from the UI any more... CheckUpdates(); @@ -87,7 +99,7 @@ namespace ZitiDesktopEdge menuState = "UILogs"; UpdateState(); } - async private void ShowReleaseStreamMenuAction(object sender, MouseButtonEventArgs e) { + private void ShowReleaseStreamMenuAction(object sender, MouseButtonEventArgs e) { logger.Warn("this is ShowReleaseStreamMenuAction at warn"); logger.Info("this is ShowReleaseStreamMenuAction at info"); logger.Debug("this is ShowReleaseStreamMenuAction at debug"); @@ -169,6 +181,7 @@ namespace ZitiDesktopEdge MenuTitle.Content = "Advanced Settings"; AdvancedItems.Visibility = Visibility.Visible; BackArrow.Visibility = Visibility.Visible; + ShowReleaseStreamMenuItem.Visibility = allowReleaseSelect ? Visibility.Visible : Visibility.Collapsed; } else if (menuState == "Licenses") { MenuTitle.Content = "Third Party Licenses"; LicensesItems.Visibility = Visibility.Visible; @@ -197,7 +210,7 @@ namespace ZitiDesktopEdge SetReleaseStream(); MenuTitle.Content = "Set Release Stream"; - ReleaseStreamItems.Visibility = Visibility.Visible; + ReleaseStreamItems.Visibility = allowReleaseSelect ? Visibility.Visible : Visibility.Collapsed; BackArrow.Visibility = Visibility.Visible; //xxxxxxxx } else if (menuState == "Config") { diff --git a/DesktopEdge/MainWindow.xaml.cs b/DesktopEdge/MainWindow.xaml.cs index 9d42c116..8e733ef3 100644 --- a/DesktopEdge/MainWindow.xaml.cs +++ b/DesktopEdge/MainWindow.xaml.cs @@ -45,7 +45,7 @@ namespace ZitiDesktopEdge { public static string ExpectedLogPathRoot; public static string ExpectedLogPathUI; public static string ExpectedLogPathServices; - + static MainWindow() { var asm = System.Reflection.Assembly.GetExecutingAssembly(); ThisAssemblyName = asm.GetName().Name; @@ -206,7 +206,8 @@ namespace ZitiDesktopEdge { monitorClient = new MonitorClient(); monitorClient.OnClientConnected += MonitorClient_OnClientConnected; - monitorClient.OnServiceStatusEvent += MonitorClient_OnServiceStatusEvent; + monitorClient.OnServiceStatusEvent += MonitorClient_OnServiceStatusEvent; + monitorClient.OnShutdownEvent += MonitorClient_OnShutdownEvent; Application.Current.Properties.Add("MonitorClient", monitorClient); Application.Current.Properties.Add("Identities", new List()); @@ -233,8 +234,16 @@ namespace ZitiDesktopEdge { Placement(); } + private void MonitorClient_OnShutdownEvent(object sender, StatusEvent e) { + Application.Current.Shutdown(); + } + private void MonitorClient_OnServiceStatusEvent(object sender, MonitorServiceStatusEvent evt) { - logger.Debug("MonitorClient_OnServiceStatusEvent"); + if (evt.Status == "upgrading") { + logger.Info("The monitor has indicated an upgrade is in progress. Shutting down the UI"); + Application.Current.Shutdown(); + } + logger.Debug("MonitorClient_OnServiceStatusEvent: {0}", evt.Status); Application.Current.Properties["ReleaseStream"] = evt.ReleaseStream; ServiceControllerStatus status = (ServiceControllerStatus)Enum.Parse(typeof(ServiceControllerStatus), evt.Status); @@ -248,6 +257,7 @@ namespace ZitiDesktopEdge { break; case ServiceControllerStatus.StopPending: logger.Info("Service is stopping..."); + this.Dispatcher.Invoke(async () => { SetCantDisplay("The Service is Stopping", "Please wait while the service stops", Visibility.Hidden); await WaitForServiceToStop(DateTime.Now + TimeSpan.FromSeconds(30)); diff --git a/ZitiDesktopEdge.Client/Server/EventRegistry.cs b/ZitiDesktopEdge.Client/Server/EventRegistry.cs index cddd6cfc..efef65eb 100644 --- a/ZitiDesktopEdge.Client/Server/EventRegistry.cs +++ b/ZitiDesktopEdge.Client/Server/EventRegistry.cs @@ -1,4 +1,5 @@ -using System; +using Newtonsoft.Json; +using System; using System.Threading; namespace ZitiDesktopEdge.Server { @@ -8,7 +9,7 @@ namespace ZitiDesktopEdge.Server { public static event EventHandler MyEvent; public static void SendEventToConsumers(object objToSend) { - MyEvent?.Invoke(objToSend, null); + MyEvent?.Invoke(JsonConvert.SerializeObject(objToSend), null); } } } diff --git a/ZitiDesktopEdge.Client/Server/IPCServer.cs b/ZitiDesktopEdge.Client/Server/IPCServer.cs index 8105c16d..76631137 100644 --- a/ZitiDesktopEdge.Client/Server/IPCServer.cs +++ b/ZitiDesktopEdge.Client/Server/IPCServer.cs @@ -44,7 +44,7 @@ namespace ZitiDesktopEdge.Server { eventPipeName = EventPipeName; } - async public Task startIpcServer(OnClientAsync onClient) { + async public Task startIpcServerAsync(OnClientAsync onClient) { int idx = 0; // Allow AuthenticatedUserSid read and write access to the pipe. @@ -81,10 +81,7 @@ namespace ZitiDesktopEdge.Server { } } - - //public event EventHandler OnShutdownEvent; - - async public Task startEventsServer(OnClientAsync onClient) { + async public Task startEventsServerAsync(OnClientAsync onClient) { int idx = 0; // Allow AuthenticatedUserSid read and write access to the pipe. diff --git a/ZitiDesktopEdge.Client/Server/ServiceActions.cs b/ZitiDesktopEdge.Client/Server/ServiceActions.cs index 8a7f1653..7c9468a4 100644 --- a/ZitiDesktopEdge.Client/Server/ServiceActions.cs +++ b/ZitiDesktopEdge.Client/Server/ServiceActions.cs @@ -10,6 +10,18 @@ namespace ZitiDesktopEdge.Server { public static string ServiceStatus() { var status = sc.Status; Logger.Debug("service status set to: {0}", sc.Status); + + if (sc.Status == ServiceControllerStatus.StopPending) { + //ServiceControllerStatus is reporting 'stop pending' when the service crashes or is terminated by a user + //this is INCORRECT as the service is dead - it is not pending. Test for the process by name and if there's + //still a process - cool. if NOT - send the 'stopped' message... + var procs = System.Diagnostics.Process.GetProcessesByName("ziti-tunnel"); + if (procs != null && procs.Length == 1) { + // if there's more than one ziti-tunnel that'd be bad too but we can't account for that here + Logger.Warn("ServiceControllerStatus is StopPending but there is NO ziti-tunnel process! report service is stopped"); + return ServiceControllerStatus.Stopped.ToString(); + } + } return status.ToString(); } diff --git a/ZitiDesktopEdge.Client/ZitiDesktopEdge.Client.csproj b/ZitiDesktopEdge.Client/ZitiDesktopEdge.Client.csproj index 76f0bd16..379bf357 100644 --- a/ZitiDesktopEdge.Client/ZitiDesktopEdge.Client.csproj +++ b/ZitiDesktopEdge.Client/ZitiDesktopEdge.Client.csproj @@ -59,9 +59,9 @@ - + diff --git a/ZitiUpdateService/UpdateService.cs b/ZitiUpdateService/UpdateService.cs index 720cf181..f4561279 100644 --- a/ZitiUpdateService/UpdateService.cs +++ b/ZitiUpdateService/UpdateService.cs @@ -229,9 +229,9 @@ namespace ZitiUpdateService { AccessUtils.GrantAccessToFile(Path.Combine(exeLocation, "ZitiDesktopEdge-log.config")); //allow anyone to change the log file config Logger.Info("starting ipc server"); - ipcServer = svr.startIpcServer(onIpcClient); + ipcServer = svr.startIpcServerAsync(onIpcClientAsync); Logger.Info("starting events server"); - eventServer = svr.startEventsServer(onEventsClient); + eventServer = svr.startEventsServerAsync(onEventsClientAsync); Logger.Info("starting service watchers"); if (!running) { @@ -243,7 +243,7 @@ namespace ZitiUpdateService { Logger.Info("ziti-monitor service is initialized and running"); } - async private Task onEventsClient(StreamWriter writer) { + async private Task onEventsClientAsync(StreamWriter writer) { Logger.Info("a new events client was connected"); //reset to release stream //initial status when connecting the event stream @@ -258,7 +258,7 @@ namespace ZitiUpdateService { await writer.FlushAsync(); } - async private Task onIpcClient(StreamWriter writer) { + async private Task onIpcClientAsync(StreamWriter writer) { Logger.Info("a new ipc client was connected"); } @@ -359,6 +359,7 @@ namespace ZitiUpdateService { if (avail >= 0) { Logger.Debug("update check complete. no update available"); inUpdateCheck = false; + return; } @@ -414,7 +415,7 @@ namespace ZitiUpdateService { } StopZiti(); - StopUI(); + StopUI().Wait(); Logger.Info("Running update package: " + fileDestination); // shell out to a new process and run the uninstall, reinstall steps which SHOULD stop this current process as well @@ -515,12 +516,31 @@ namespace ZitiUpdateService { } } - private void StopUI() { + async private Task StopUI() { + //first try to ask the UI to exit: + + MonitorServiceStatusEvent status = new MonitorServiceStatusEvent() { + Code = 0, + Error = "", + Message = "Upgrading" + }; + EventRegistry.SendEventToConsumers(status); + + await Task.Delay(500); //wait for the event to send and give the UI time to close... + stopProcessForcefully("ZitiDesktopEdge", "UI"); } private static void Svc_OnShutdownEvent(object sender, StatusEvent e) { Logger.Info("the service is shutting down normally..."); + + MonitorServiceStatusEvent status = new MonitorServiceStatusEvent() { + Code = 0, + Error = "SERVICE DOWN", + Message = "SERVICE DOWN", + Status = ServiceActions.ServiceStatus() + }; + EventRegistry.SendEventToConsumers(status); } private static void Svc_OnTunnelStatusEvent(object sender, TunnelStatusEvent e) { @@ -539,6 +559,14 @@ namespace ZitiUpdateService { if (svc.CleanShutdown) { //then this is fine and expected - the service is shutting down Logger.Info("client disconnected due to clean service shutdown"); + + MonitorServiceStatusEvent status = new MonitorServiceStatusEvent() { + Code = 0, + Error = "SERVICE DOWN", + Message = "SERVICE DOWN", + Status = ServiceActions.ServiceStatus() + }; + EventRegistry.SendEventToConsumers(status); } else { Logger.Error("SERVICE IS DOWN and did not exit cleanly. initiating DNS cleanup");