diff --git a/src/Microsoft.SqlTools.ServiceLayer/Program.cs b/src/Microsoft.SqlTools.ServiceLayer/Program.cs index 7cdae5a4..bfe69856 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Program.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Program.cs @@ -6,8 +6,8 @@ using Microsoft.SqlTools.ServiceLayer.Hosting; using Microsoft.SqlTools.ServiceLayer.SqlContext; using Microsoft.SqlTools.ServiceLayer.Utility; using Microsoft.SqlTools.Utility; -using System.IO; using System.Diagnostics; +using System.Threading; namespace Microsoft.SqlTools.ServiceLayer { @@ -46,6 +46,14 @@ namespace Microsoft.SqlTools.ServiceLayer SqlToolsContext sqlToolsContext = new SqlToolsContext(hostDetails); ServiceHost serviceHost = HostLoader.CreateAndStartServiceHost(sqlToolsContext); + // If this service was started by another process, then it should shutdown when that parent process does. + if (commandOptions.ParentProcessId != null) + { + var parentProcess = Process.GetProcessById(commandOptions.ParentProcessId.Value); + var statusThread = new Thread(() => CheckParentStatusLoop(parentProcess)); + statusThread.Start(); + } + serviceHost.WaitForExit(); } catch (Exception ex) @@ -66,5 +74,20 @@ namespace Microsoft.SqlTools.ServiceLayer Logger.Close(); } } + + private static void CheckParentStatusLoop(Process parent) + { + Logger.Write(TraceEventType.Information, $"Starting thread to check status of parent process. Parent PID: {parent.Id}"); + while (true) + { + if (parent.HasExited) + { + var processName = Process.GetCurrentProcess().ProcessName; + Logger.Write(TraceEventType.Information, $"Terminating {processName} process because parent process has exited. Parent PID: {parent.Id}"); + Environment.Exit(0); + } + Thread.Sleep(5000); + } + } } } diff --git a/src/Microsoft.SqlTools.ServiceLayer/Utility/ServiceLayerCommandOptions.cs b/src/Microsoft.SqlTools.ServiceLayer/Utility/ServiceLayerCommandOptions.cs index 9e586633..18728b47 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Utility/ServiceLayerCommandOptions.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Utility/ServiceLayerCommandOptions.cs @@ -13,7 +13,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Utility { internal const string ServiceLayerServiceName = "MicrosoftSqlToolsServiceLayer.exe"; - private static readonly string[] serviceLayerCommandArgs = { "-d", "--developers" }; + private static readonly string[] serviceLayerCommandArgs = { "-d", "--developers", "--parent-pid" }; /** * List of contributors to this project, used as part of the onboarding process. @@ -23,6 +23,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Utility "Charles-Gagnon" }; + public int? ParentProcessId { get; private set; } + public ServiceLayerCommandOptions(string[] args) : base(args.Where(arg => !serviceLayerCommandArgs.Contains(arg)).ToArray(), ServiceLayerServiceName) { for (int i = 0; i < args.Length; ++i) @@ -41,6 +43,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Utility Console.WriteLine(string.Join(Environment.NewLine, contributors.Select(contributor => $"\t{contributor}"))); this.ShouldExit = true; break; + case "--parent-pid": + string nextArg = args[++i]; + if (Int32.TryParse(nextArg, out int parsedInt)) + { + ParentProcessId = parsedInt; + } + break; } } }