public override void Start() { try { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { PipeSecurity pipeSecurity = new PipeSecurity(); WindowsIdentity identity = WindowsIdentity.GetCurrent(); WindowsPrincipal principal = new WindowsPrincipal(identity); if (principal.IsInRole(WindowsBuiltInRole.Administrator)) { // Allow the Administrators group full access to the pipe. pipeSecurity.AddAccessRule(new PipeAccessRule( new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null).Translate(typeof(NTAccount)), PipeAccessRights.FullControl, AccessControlType.Allow)); } else { // Allow the current user read/write access to the pipe. pipeSecurity.AddAccessRule(new PipeAccessRule( WindowsIdentity.GetCurrent().User, PipeAccessRights.ReadWrite, AccessControlType.Allow)); } // Unfortunately, .NET Core does not support passing in a PipeSecurity object into the constructor for // NamedPipeServerStream so we are creating native Named Pipes and securing them using native APIs. The // issue on .NET Core regarding Named Pipe security is here: https://github.com/dotnet/corefx/issues/30170 // 99% of this code was borrowed from PowerShell here: // https://github.com/PowerShell/PowerShell/blob/master/src/System.Management.Automation/engine/remoting/common/RemoteSessionNamedPipe.cs#L124-L256 this.inOutPipeServer = NamedPipeNative.CreateNamedPipe(inOutPipeName, pipeSecurity); if (this.outPipeName != null) { this.outPipeServer = NamedPipeNative.CreateNamedPipe(outPipeName, pipeSecurity); } } else { // This handles the Unix case since PipeSecurity is not supported on Unix. // Instead, we use chmod in Start-EditorServices.ps1 this.inOutPipeServer = new NamedPipeServerStream( pipeName: inOutPipeName, direction: PipeDirection.InOut, maxNumberOfServerInstances: 1, transmissionMode: PipeTransmissionMode.Byte, options: PipeOptions.Asynchronous); if (this.outPipeName != null) { this.outPipeServer = new NamedPipeServerStream( pipeName: outPipeName, direction: PipeDirection.Out, maxNumberOfServerInstances: 1, transmissionMode: PipeTransmissionMode.Byte, options: PipeOptions.None); } } ListenForConnection(); } catch (IOException e) { this.logger.Write( LogLevel.Verbose, "Named pipe server failed to start due to exception:\r\n\r\n" + e.Message); throw e; } }