From 9db4d7e0cda23d9812fef48f1d0dd7ce10998e34 Mon Sep 17 00:00:00 2001 From: Andrey Dernov Date: Wed, 24 Oct 2018 10:20:42 +0300 Subject: [PATCH 1/7] Adds ability to use separate pipes for reading and writing Some clients (e.g. Java on Windows) have blocking File I/O API, thus it is not possible for them to use single named pipe for reading and writing asynchronously. It will add the ability to use separate pipes for reading and writing when the client specifies the "-SplitInOutPipes" switch for the startup script. --- .../PowerShellEditorServices.psm1 | 22 ++++- .../Start-EditorServices.ps1 | 48 ++++++++-- .../EditorServicesHost.cs | 14 ++- .../Channel/NamedPipeServerChannel.cs | 14 ++- .../Channel/NamedPipeServerListener.cs | 90 +++++++++++++------ 5 files changed, 151 insertions(+), 37 deletions(-) diff --git a/module/PowerShellEditorServices/PowerShellEditorServices.psm1 b/module/PowerShellEditorServices/PowerShellEditorServices.psm1 index 956287f2b..3de4a751c 100644 --- a/module/PowerShellEditorServices/PowerShellEditorServices.psm1 +++ b/module/PowerShellEditorServices/PowerShellEditorServices.psm1 @@ -37,9 +37,15 @@ function Start-EditorServicesHost { [string] $LanguageServiceNamedPipe, + [string] + $LanguageServiceWriteNamedPipe, + [string] $DebugServiceNamedPipe, + [string] + $DebugServiceWriteNamedPipe, + [ValidateNotNullOrEmpty()] [string] $BundledModulesPath, @@ -106,12 +112,24 @@ function Start-EditorServicesHost { if ($LanguageServiceNamedPipe) { $languageServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::NamedPipe - $languageServiceConfig.Endpoint = "$LanguageServiceNamedPipe" + if ($LanguageServiceWriteNamedPipe) { + $languageServiceConfig.Endpoint = "$LanguageServiceNamedPipe;$LanguageServiceWriteNamedPipe" + } + else + { + $languageServiceConfig.Endpoint = "$LanguageServiceNamedPipe" + } } if ($DebugServiceNamedPipe) { $debugServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::NamedPipe - $debugServiceConfig.Endpoint = "$DebugServiceNamedPipe" + if ($DebugServiceWriteNamedPipe) { + $debugServiceConfig.Endpoint = "$DebugServiceNamedPipe;$DebugServiceWriteNamedPipe" + } + else + { + $debugServiceConfig.Endpoint = "$DebugServiceNamedPipe" + } } if ($DebugServiceOnly.IsPresent) { diff --git a/module/PowerShellEditorServices/Start-EditorServices.ps1 b/module/PowerShellEditorServices/Start-EditorServices.ps1 index c84ad537a..da6d7e347 100644 --- a/module/PowerShellEditorServices/Start-EditorServices.ps1 +++ b/module/PowerShellEditorServices/Start-EditorServices.ps1 @@ -68,6 +68,9 @@ param( [switch] $Stdio, + [switch] + $SplitInOutPipes, + [string] $LanguageServicePipeName = $null, @@ -173,8 +176,7 @@ function New-NamedPipeName { # We try 10 times to find a valid pipe name for ($i = 0; $i -lt 10; $i++) { - # add a guid to make the pipe unique - $PipeName = "PSES_$([guid]::NewGuid())" + $PipeName = "PSES_$([System.IO.Path]::GetRandomFileName())" if ((Test-NamedPipeName -PipeName $PipeName)) { return $PipeName @@ -269,6 +271,9 @@ try { $languageServiceTransport = $null $debugServiceTransport = $null + $LanguageServiceWritePipeName = $null + $DebugServiceWritePipeName = $null + if ($Stdio.IsPresent) { $languageServiceTransport = "Stdio" $debugServiceTransport = "Stdio" @@ -292,6 +297,11 @@ try { ExitWithError "Pipe name supplied is already taken: $DebugServicePipeName" } } + # If present create second pipe for writing + if ($SplitInOutPipes.IsPresent) { + $LanguageServiceWritePipeName = New-NamedPipeName + $DebugServiceWritePipeName = New-NamedPipeName + } } if ($EnableConsoleRepl) { @@ -309,7 +319,9 @@ try { -LogLevel $LogLevel ` -AdditionalModules $AdditionalModules ` -LanguageServiceNamedPipe $LanguageServicePipeName ` + -LanguageServiceWriteNamedPipe $LanguageServiceWritePipeName ` -DebugServiceNamedPipe $DebugServicePipeName ` + -DebugServiceWriteNamedPipe $DebugServiceWritePipeName ` -Stdio:$Stdio.IsPresent` -BundledModulesPath $BundledModulesPath ` -EnableConsoleRepl:$EnableConsoleRepl.IsPresent ` @@ -326,15 +338,35 @@ try { }; if ($LanguageServicePipeName) { - $resultDetails["languageServicePipeName"] = Get-NamedPipePath -PipeName $LanguageServicePipeName - if ($IsLinux -or $IsMacOS) { - Set-NamedPipeMode -PipeFile $resultDetails["languageServicePipeName"] + if ($LanguageServiceWritePipeName) { + $resultDetails["languageServiceReadPipeName"] = Get-NamedPipePath -PipeName $LanguageServicePipeName + $resultDetails["languageServiceWritePipeName"] = Get-NamedPipePath -PipeName $LanguageServiceWritePipeName + if ($IsLinux -or $IsMacOS) { + Set-NamedPipeMode -PipeFile $resultDetails["languageServiceReadPipeName"] + Set-NamedPipeMode -PipeFile $resultDetails["languageServiceWritePipeName"] + } + } + else { + $resultDetails["languageServicePipeName"] = Get-NamedPipePath -PipeName $LanguageServicePipeName + if ($IsLinux -or $IsMacOS) { + Set-NamedPipeMode -PipeFile $resultDetails["languageServicePipeName"] + } } } if ($DebugServicePipeName) { - $resultDetails["debugServicePipeName"] = Get-NamedPipePath -PipeName $DebugServicePipeName - if ($IsLinux -or $IsMacOS) { - Set-NamedPipeMode -PipeFile $resultDetails["debugServicePipeName"] + if ($DebugServiceWritePipeName) { + $resultDetails["debugServiceReadPipeName"] = Get-NamedPipePath -PipeName $DebugServicePipeName + $resultDetails["debugServiceWritePipeName"] = Get-NamedPipePath -PipeName $DebugServiceWritePipeName + if ($IsLinux -or $IsMacOS) { + Set-NamedPipeMode -PipeFile $resultDetails["debugServiceReadPipeName"] + Set-NamedPipeMode -PipeFile $resultDetails["debugServiceWritePipeName"] + } + } + else { + $resultDetails["debugServicePipeName"] = Get-NamedPipePath -PipeName $DebugServicePipeName + if ($IsLinux -or $IsMacOS) { + Set-NamedPipeMode -PipeFile $resultDetails["debugServicePipeName"] + } } } diff --git a/src/PowerShellEditorServices.Host/EditorServicesHost.cs b/src/PowerShellEditorServices.Host/EditorServicesHost.cs index 324590877..587cb2a51 100644 --- a/src/PowerShellEditorServices.Host/EditorServicesHost.cs +++ b/src/PowerShellEditorServices.Host/EditorServicesHost.cs @@ -463,7 +463,19 @@ private IServerListener CreateServiceListener(MessageProtocolType protocol, Edit case EditorServiceTransportType.NamedPipe: { - return new NamedPipeServerListener(protocol, config.Endpoint, this.logger); + string endpoint = config.Endpoint; + int splitIndex = endpoint.IndexOf(';'); + if (splitIndex > 0) + { + string readPipeName = endpoint.Substring(0, splitIndex); + string writePipeName = endpoint.Substring(splitIndex + 1); + this.logger.Write(LogLevel.Verbose, $"Creating NamedPipeServerListener for ${protocol} protocol with two pipes: Read: '" + readPipeName + "'. Write: '" + writePipeName + "'"); + return new NamedPipeServerListener(protocol, readPipeName, writePipeName, this.logger); + } + else + { + return new NamedPipeServerListener(protocol, endpoint, this.logger); + } } default: diff --git a/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerChannel.cs b/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerChannel.cs index ad4e01de9..664cf16ac 100644 --- a/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerChannel.cs +++ b/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerChannel.cs @@ -12,12 +12,23 @@ public class NamedPipeServerChannel : ChannelBase { private ILogger logger; private NamedPipeServerStream pipeServer; + private NamedPipeServerStream writePipeServer; public NamedPipeServerChannel( NamedPipeServerStream pipeServer, ILogger logger) { this.pipeServer = pipeServer; + this.writePipeServer = null; + this.logger = logger; + } + public NamedPipeServerChannel( + NamedPipeServerStream readPipeServer, + NamedPipeServerStream writePipeServer, + ILogger logger) + { + this.pipeServer = readPipeServer; + this.writePipeServer = writePipeServer; this.logger = logger; } @@ -31,7 +42,7 @@ protected override void Initialize(IMessageSerializer messageSerializer) this.MessageWriter = new MessageWriter( - this.pipeServer, + this.writePipeServer ?? this.pipeServer, messageSerializer, this.logger); } @@ -40,6 +51,7 @@ protected override void Shutdown() { // The server listener will take care of the pipe server this.pipeServer = null; + this.writePipeServer = null; } } } diff --git a/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerListener.cs b/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerListener.cs index 44d6acb75..04a6e74d6 100644 --- a/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerListener.cs +++ b/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerListener.cs @@ -6,6 +6,7 @@ using Microsoft.PowerShell.EditorServices.Utility; using Microsoft.Win32.SafeHandles; using System; +using System.Collections.Generic; using System.IO; using System.IO.Pipes; using System.Runtime.InteropServices; @@ -19,7 +20,9 @@ public class NamedPipeServerListener : ServerListenerBase + List connectionTasks = new List {WaitForConnectionAsync(this.pipeServer)}; + if (this.writePipeServer != null) + { + connectionTasks.Add(WaitForConnectionAsync(this.writePipeServer)); + } + + Task.Run(async () => + { + try { - try - { + await Task.WhenAll(connectionTasks); + this.OnClientConnect(new NamedPipeServerChannel(this.pipeServer, this.writePipeServer, this.logger)); + } + catch (Exception e) + { + this.logger.WriteException( + "An unhandled exception occurred while listening for a named pipe client connection", + e); + + throw e; + } + }); + } + + private static async Task WaitForConnectionAsync(NamedPipeServerStream pipeServerStream) + { #if CoreCLR - await this.pipeServer.WaitForConnectionAsync(); + await pipeServerStream.WaitForConnectionAsync(); #else - await Task.Factory.FromAsync( - this.pipeServer.BeginWaitForConnection, - this.pipeServer.EndWaitForConnection, null); + await Task.Factory.FromAsync(pipeServerStream.BeginWaitForConnection, pipeServerStream.EndWaitForConnection, null); #endif - - await this.pipeServer.FlushAsync(); - - this.OnClientConnect( - new NamedPipeServerChannel( - this.pipeServer, - this.logger)); - } - catch (Exception e) - { - this.logger.WriteException( - "An unhandled exception occurred while listening for a named pipe client connection", - e); - - throw e; - } - }); + await pipeServerStream.FlushAsync(); } } From ea6516273f8079472568a053ed9feca8c20bc3df Mon Sep 17 00:00:00 2001 From: Andrey Dernov Date: Sat, 27 Oct 2018 09:34:37 +0300 Subject: [PATCH 2/7] Use Path.DirectorySeparatorChar as read/write pipe name separator for transport config endpoint --- module/PowerShellEditorServices/PowerShellEditorServices.psm1 | 4 ++-- src/PowerShellEditorServices.Host/EditorServicesHost.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/module/PowerShellEditorServices/PowerShellEditorServices.psm1 b/module/PowerShellEditorServices/PowerShellEditorServices.psm1 index 3de4a751c..a2158378f 100644 --- a/module/PowerShellEditorServices/PowerShellEditorServices.psm1 +++ b/module/PowerShellEditorServices/PowerShellEditorServices.psm1 @@ -113,7 +113,7 @@ function Start-EditorServicesHost { if ($LanguageServiceNamedPipe) { $languageServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::NamedPipe if ($LanguageServiceWriteNamedPipe) { - $languageServiceConfig.Endpoint = "$LanguageServiceNamedPipe;$LanguageServiceWriteNamedPipe" + $languageServiceConfig.Endpoint = "$LanguageServiceNamedPipe$([System.IO.Path]::DirectorySeparatorChar)$LanguageServiceWriteNamedPipe" } else { @@ -124,7 +124,7 @@ function Start-EditorServicesHost { if ($DebugServiceNamedPipe) { $debugServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::NamedPipe if ($DebugServiceWriteNamedPipe) { - $debugServiceConfig.Endpoint = "$DebugServiceNamedPipe;$DebugServiceWriteNamedPipe" + $debugServiceConfig.Endpoint = "$DebugServiceNamedPipe$([System.IO.Path]::DirectorySeparatorChar)$DebugServiceWriteNamedPipe" } else { diff --git a/src/PowerShellEditorServices.Host/EditorServicesHost.cs b/src/PowerShellEditorServices.Host/EditorServicesHost.cs index 587cb2a51..4c70f2a35 100644 --- a/src/PowerShellEditorServices.Host/EditorServicesHost.cs +++ b/src/PowerShellEditorServices.Host/EditorServicesHost.cs @@ -464,7 +464,7 @@ private IServerListener CreateServiceListener(MessageProtocolType protocol, Edit case EditorServiceTransportType.NamedPipe: { string endpoint = config.Endpoint; - int splitIndex = endpoint.IndexOf(';'); + int splitIndex = endpoint.IndexOf(Path.DirectorySeparatorChar); if (splitIndex > 0) { string readPipeName = endpoint.Substring(0, splitIndex); From 8d20b53472515d80fb38d046b1eb68128f419b76 Mon Sep 17 00:00:00 2001 From: Andrey Dernov Date: Sat, 27 Oct 2018 09:50:56 +0300 Subject: [PATCH 3/7] WritePipeServer: pipe direction should be "Out" --- .../MessageProtocol/Channel/NamedPipeServerListener.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerListener.cs b/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerListener.cs index 04a6e74d6..37fcb359b 100644 --- a/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerListener.cs +++ b/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerListener.cs @@ -98,7 +98,7 @@ public override void Start() { this.writePipeServer = new NamedPipeServerStream( pipeName: writePipeName, - direction: PipeDirection.InOut, + direction: PipeDirection.Out, maxNumberOfServerInstances: 1, transmissionMode: PipeTransmissionMode.Byte, options: PipeOptions.None); From c47e80b1ff9a66a1d0ac6cc6543e560a6b151aa9 Mon Sep 17 00:00:00 2001 From: Andrey Dernov Date: Sat, 27 Oct 2018 13:03:32 +0300 Subject: [PATCH 4/7] Organize startup script parameters by parameter sets --- .../PowerShellEditorServices.psm1 | 61 +++-- .../Start-EditorServices.ps1 | 216 ++++++++++-------- 2 files changed, 157 insertions(+), 120 deletions(-) diff --git a/module/PowerShellEditorServices/PowerShellEditorServices.psm1 b/module/PowerShellEditorServices/PowerShellEditorServices.psm1 index a2158378f..007070d51 100644 --- a/module/PowerShellEditorServices/PowerShellEditorServices.psm1 +++ b/module/PowerShellEditorServices/PowerShellEditorServices.psm1 @@ -31,20 +31,36 @@ function Start-EditorServicesHost { [string] $HostVersion, + [Parameter(ParameterSetName="Stdio",Mandatory=$true)] [switch] $Stdio, + [Parameter(ParameterSetName="NamedPipe",Mandatory=$true)] + [ValidateNotNullOrEmpty()] [string] $LanguageServiceNamedPipe, + [Parameter(ParameterSetName="NamedPipe")] [string] - $LanguageServiceWriteNamedPipe, + $DebugServiceNamedPipe, + [Parameter(ParameterSetName="NamedPipeHalfDuplex",Mandatory=$true)] + [ValidateNotNullOrEmpty()] [string] - $DebugServiceNamedPipe, + $LanguageServiceInNamedPipe, + + [Parameter(ParameterSetName="NamedPipeHalfDuplex",Mandatory=$true)] + [ValidateNotNullOrEmpty()] + [string] + $LanguageServiceOutNamedPipe, + + [Parameter(ParameterSetName="NamedPipeHalfDuplex")] + [string] + $DebugServiceInNamedPipe, + [Parameter(ParameterSetName="NamedPipeHalfDuplex")] [string] - $DebugServiceWriteNamedPipe, + $DebugServiceOutNamedPipe, [ValidateNotNullOrEmpty()] [string] @@ -105,30 +121,27 @@ function Start-EditorServicesHost { $debugServiceConfig = Microsoft.PowerShell.Utility\New-Object Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportConfig - if ($Stdio.IsPresent) { - $languageServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::Stdio - $debugServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::Stdio - } - - if ($LanguageServiceNamedPipe) { - $languageServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::NamedPipe - if ($LanguageServiceWriteNamedPipe) { - $languageServiceConfig.Endpoint = "$LanguageServiceNamedPipe$([System.IO.Path]::DirectorySeparatorChar)$LanguageServiceWriteNamedPipe" + switch ($PSCmdlet.ParameterSetName) { + "Stdio" { + $languageServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::Stdio + $debugServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::Stdio } - else - { + "NamedPipe" { + $languageServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::NamedPipe $languageServiceConfig.Endpoint = "$LanguageServiceNamedPipe" + if ($DebugServiceNamedPipe) { + $debugServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::NamedPipe + $debugServiceConfig.Endpoint = "$DebugServiceNamedPipe" + } } - } - - if ($DebugServiceNamedPipe) { - $debugServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::NamedPipe - if ($DebugServiceWriteNamedPipe) { - $debugServiceConfig.Endpoint = "$DebugServiceNamedPipe$([System.IO.Path]::DirectorySeparatorChar)$DebugServiceWriteNamedPipe" - } - else - { - $debugServiceConfig.Endpoint = "$DebugServiceNamedPipe" + "NamedPipeHalfDuplex" { + $sep = [System.IO.Path]::DirectorySeparatorChar + $languageServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::NamedPipe + $languageServiceConfig.Endpoint = "$LanguageServiceInNamedPipe$sep$LanguageServiceOutNamedPipe" + if ($DebugServiceInNamedPipe -and $DebugServiceOutNamedPipe) { + $debugServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::NamedPipe + $debugServiceConfig.Endpoint = "$DebugServiceInNamedPipe$sep$DebugServiceOutNamedPipe" + } } } diff --git a/module/PowerShellEditorServices/Start-EditorServices.ps1 b/module/PowerShellEditorServices/Start-EditorServices.ps1 index da6d7e347..5c3be81a0 100644 --- a/module/PowerShellEditorServices/Start-EditorServices.ps1 +++ b/module/PowerShellEditorServices/Start-EditorServices.ps1 @@ -15,7 +15,7 @@ # Services GitHub repository: # # https://github.com/PowerShell/PowerShellEditorServices/blob/master/module/PowerShellEditorServices/Start-EditorServices.ps1 - +[Cmdletbinding(DefaultParameterSetName="NamedPipe")] param( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] @@ -65,17 +65,39 @@ param( [switch] $ConfirmInstall, + [Parameter(ParameterSetName="Stdio",Mandatory=$true)] [switch] $Stdio, + [Parameter(ParameterSetName="NamedPipe")] + [string] + $LanguageServicePipeName = $null, + + [Parameter(ParameterSetName="NamedPipe")] + [string] + $DebugServicePipeName = $null, + + [Parameter(ParameterSetName="NamedPipeHalfDuplex",Mandatory=$true)] [switch] $SplitInOutPipes, + [Parameter(ParameterSetName="NamedPipeHalfDuplexParam",Mandatory=$true)] + [ValidateNotNullOrEmpty()] [string] - $LanguageServicePipeName = $null, + $LanguageServiceInPipeName, + [Parameter(ParameterSetName="NamedPipeHalfDuplexParam",Mandatory=$true)] + [ValidateNotNullOrEmpty()] [string] - $DebugServicePipeName = $null + $LanguageServiceOutPipeName, + + [Parameter(ParameterSetName="NamedPipeHalfDuplexParam")] + [string] + $DebugServiceInPipeName = $null, + + [Parameter(ParameterSetName="NamedPipeHalfDuplexParam")] + [string] + $DebugServiceOutPipeName = $null ) $DEFAULT_USER_MODE = "600" @@ -245,6 +267,29 @@ function Set-NamedPipeMode { } } +function Test-NamedPipeName-OrCreate-IfNull { + param( + [string] + $PipeName + ) + if (-not $PipeName) { + $PipeName = New-NamedPipeName + } + else { + if (-not (Test-NamedPipeName -PipeName $PipeName)) { + ExitWithError "Pipe name supplied is already taken: $PipeName" + } + } + return $PipeName +} + +function SetPipeFileResult($ResultTable, [string]$PipeNameKey, [string]$PipeNameValue) { + $ResultTable[$PipeNameKey] = Get-NamedPipePath -PipeName $PipeNameValue + if ($IsLinux -or $IsMacOS) { + Set-NamedPipeMode -PipeFile $ResultTable[$PipeNameKey] + } +} + # Add BundledModulesPath to $env:PSModulePath if ($BundledModulesPath) { $env:PSModulePath = $env:PSModulePath.TrimEnd([System.IO.Path]::PathSeparator) + [System.IO.Path]::PathSeparator + $BundledModulesPath @@ -265,111 +310,90 @@ try { Microsoft.PowerShell.Core\Import-Module PowerShellEditorServices -ErrorAction Stop - # Locate available port numbers for services - # There could be only one service on Stdio channel - - $languageServiceTransport = $null - $debugServiceTransport = $null - - $LanguageServiceWritePipeName = $null - $DebugServiceWritePipeName = $null - - if ($Stdio.IsPresent) { - $languageServiceTransport = "Stdio" - $debugServiceTransport = "Stdio" - } - else { - $languageServiceTransport = "NamedPipe" - $debugServiceTransport = "NamedPipe" - if (-not $LanguageServicePipeName) { - $LanguageServicePipeName = New-NamedPipeName - } - else { - if (-not (Test-NamedPipeName -PipeName $LanguageServicePipeName)) { - ExitWithError "Pipe name supplied is already taken: $LanguageServicePipeName" - } - } - if (-not $DebugServicePipeName) { - $DebugServicePipeName = New-NamedPipeName - } - else { - if (-not (Test-NamedPipeName -PipeName $DebugServicePipeName)) { - ExitWithError "Pipe name supplied is already taken: $DebugServicePipeName" - } - } - # If present create second pipe for writing - if ($SplitInOutPipes.IsPresent) { - $LanguageServiceWritePipeName = New-NamedPipeName - $DebugServiceWritePipeName = New-NamedPipeName - } - } - if ($EnableConsoleRepl) { Write-Host "PowerShell Integrated Console`n" } - # Create the Editor Services host - Log "Invoking Start-EditorServicesHost" - $editorServicesHost = - Start-EditorServicesHost ` - -HostName $HostName ` - -HostProfileId $HostProfileId ` - -HostVersion $HostVersion ` - -LogPath $LogPath ` - -LogLevel $LogLevel ` - -AdditionalModules $AdditionalModules ` - -LanguageServiceNamedPipe $LanguageServicePipeName ` - -LanguageServiceWriteNamedPipe $LanguageServiceWritePipeName ` - -DebugServiceNamedPipe $DebugServicePipeName ` - -DebugServiceWriteNamedPipe $DebugServiceWritePipeName ` - -Stdio:$Stdio.IsPresent` - -BundledModulesPath $BundledModulesPath ` - -EnableConsoleRepl:$EnableConsoleRepl.IsPresent ` - -DebugServiceOnly:$DebugServiceOnly.IsPresent ` - -WaitForDebugger:$WaitForDebugger.IsPresent - - # TODO: Verify that the service is started - Log "Start-EditorServicesHost returned $editorServicesHost" - $resultDetails = @{ - "status" = "started"; - "languageServiceTransport" = $languageServiceTransport; - "debugServiceTransport" = $debugServiceTransport; + "status" = "not started"; + "languageServiceTransport" = $PSCmdlet.ParameterSetName.Replace("Param",""); + "debugServiceTransport" = $PSCmdlet.ParameterSetName.Replace("Param",""); }; - if ($LanguageServicePipeName) { - if ($LanguageServiceWritePipeName) { - $resultDetails["languageServiceReadPipeName"] = Get-NamedPipePath -PipeName $LanguageServicePipeName - $resultDetails["languageServiceWritePipeName"] = Get-NamedPipePath -PipeName $LanguageServiceWritePipeName - if ($IsLinux -or $IsMacOS) { - Set-NamedPipeMode -PipeFile $resultDetails["languageServiceReadPipeName"] - Set-NamedPipeMode -PipeFile $resultDetails["languageServiceWritePipeName"] - } - } - else { - $resultDetails["languageServicePipeName"] = Get-NamedPipePath -PipeName $LanguageServicePipeName - if ($IsLinux -or $IsMacOS) { - Set-NamedPipeMode -PipeFile $resultDetails["languageServicePipeName"] - } + # Create the Editor Services host + Log "Invoking Start-EditorServicesHost" + # There could be only one service on Stdio channel + # Locate available port numbers for services + switch -Wildcard ($PSCmdlet.ParameterSetName) { + "Stdio" { + $editorServicesHost = Start-EditorServicesHost ` + -HostName $HostName ` + -HostProfileId $HostProfileId ` + -HostVersion $HostVersion ` + -LogPath $LogPath ` + -LogLevel $LogLevel ` + -AdditionalModules $AdditionalModules ` + -Stdio ` + -BundledModulesPath $BundledModulesPath ` + -EnableConsoleRepl:$EnableConsoleRepl.IsPresent ` + -DebugServiceOnly:$DebugServiceOnly.IsPresent ` + -WaitForDebugger:$WaitForDebugger.IsPresent } - } - if ($DebugServicePipeName) { - if ($DebugServiceWritePipeName) { - $resultDetails["debugServiceReadPipeName"] = Get-NamedPipePath -PipeName $DebugServicePipeName - $resultDetails["debugServiceWritePipeName"] = Get-NamedPipePath -PipeName $DebugServiceWritePipeName - if ($IsLinux -or $IsMacOS) { - Set-NamedPipeMode -PipeFile $resultDetails["debugServiceReadPipeName"] - Set-NamedPipeMode -PipeFile $resultDetails["debugServiceWritePipeName"] - } + "NamedPipeHalfDuplex*" { + $LanguageServiceInPipeName = Test-NamedPipeName-OrCreate-IfNull $LanguageServiceInPipeName + $LanguageServiceOutPipeName = Test-NamedPipeName-OrCreate-IfNull $LanguageServiceOutPipeName + $DebugServiceInPipeName = Test-NamedPipeName-OrCreate-IfNull $DebugServiceInPipeName + $DebugServiceOutPipeName = Test-NamedPipeName-OrCreate-IfNull $DebugServiceOutPipeName + + $editorServicesHost = Start-EditorServicesHost ` + -HostName $HostName ` + -HostProfileId $HostProfileId ` + -HostVersion $HostVersion ` + -LogPath $LogPath ` + -LogLevel $LogLevel ` + -AdditionalModules $AdditionalModules ` + -LanguageServiceInNamedPipe $LanguageServiceInPipeName ` + -LanguageServiceOutNamedPipe $LanguageServiceOutPipeName ` + -DebugServiceInNamedPipe $DebugServiceInPipeName ` + -DebugServiceOutNamedPipe $DebugServiceOutPipeName ` + -BundledModulesPath $BundledModulesPath ` + -EnableConsoleRepl:$EnableConsoleRepl.IsPresent ` + -DebugServiceOnly:$DebugServiceOnly.IsPresent ` + -WaitForDebugger:$WaitForDebugger.IsPresent + + SetPipeFileResult $resultDetails "languageServiceReadPipeName" $LanguageServiceInPipeName + SetPipeFileResult $resultDetails "languageServiceWritePipeName" $LanguageServiceOutPipeName + SetPipeFileResult $resultDetails "debugServiceReadPipeName" $DebugServiceInPipeName + SetPipeFileResult $resultDetails "debugServiceWritePipeName" $DebugServiceOutPipeName } - else { - $resultDetails["debugServicePipeName"] = Get-NamedPipePath -PipeName $DebugServicePipeName - if ($IsLinux -or $IsMacOS) { - Set-NamedPipeMode -PipeFile $resultDetails["debugServicePipeName"] - } + Default { + $LanguageServicePipeName = Test-NamedPipeName-OrCreate-IfNull $LanguageServicePipeName + $DebugServicePipeName = Test-NamedPipeName-OrCreate-IfNull $DebugServicePipeName + + $editorServicesHost = Start-EditorServicesHost ` + -HostName $HostName ` + -HostProfileId $HostProfileId ` + -HostVersion $HostVersion ` + -LogPath $LogPath ` + -LogLevel $LogLevel ` + -AdditionalModules $AdditionalModules ` + -LanguageServiceNamedPipe $LanguageServicePipeName ` + -DebugServiceNamedPipe $DebugServicePipeName ` + -BundledModulesPath $BundledModulesPath ` + -EnableConsoleRepl:$EnableConsoleRepl.IsPresent ` + -DebugServiceOnly:$DebugServiceOnly.IsPresent ` + -WaitForDebugger:$WaitForDebugger.IsPresent + + SetPipeFileResult $resultDetails "languageServicePipeName" $LanguageServicePipeName + SetPipeFileResult $resultDetails "debugServicePipeName" $DebugServicePipeName } } + # TODO: Verify that the service is started + Log "Start-EditorServicesHost returned $editorServicesHost" + + $resultDetails["status"] = "started" + # Notify the client that the services have started WriteSessionFile $resultDetails From 4e747a136fb655bab0ca511697489264c49d5864 Mon Sep 17 00:00:00 2001 From: Andrey Dernov Date: Sat, 27 Oct 2018 13:13:14 +0300 Subject: [PATCH 5/7] EditorServiceTransportType: Introduce separate properties for read/write pipes --- .../PowerShellEditorServices.psm1 | 11 ++-- .../EditorServicesHost.cs | 17 +++--- .../Channel/NamedPipeServerChannel.cs | 26 ++++----- .../Channel/NamedPipeServerListener.cs | 58 +++++++++---------- 4 files changed, 56 insertions(+), 56 deletions(-) diff --git a/module/PowerShellEditorServices/PowerShellEditorServices.psm1 b/module/PowerShellEditorServices/PowerShellEditorServices.psm1 index 007070d51..873e1e6f7 100644 --- a/module/PowerShellEditorServices/PowerShellEditorServices.psm1 +++ b/module/PowerShellEditorServices/PowerShellEditorServices.psm1 @@ -128,19 +128,20 @@ function Start-EditorServicesHost { } "NamedPipe" { $languageServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::NamedPipe - $languageServiceConfig.Endpoint = "$LanguageServiceNamedPipe" + $languageServiceConfig.InOutPipeName = "$LanguageServiceNamedPipe" if ($DebugServiceNamedPipe) { $debugServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::NamedPipe - $debugServiceConfig.Endpoint = "$DebugServiceNamedPipe" + $debugServiceConfig.InOutPipeName = "$DebugServiceNamedPipe" } } "NamedPipeHalfDuplex" { - $sep = [System.IO.Path]::DirectorySeparatorChar $languageServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::NamedPipe - $languageServiceConfig.Endpoint = "$LanguageServiceInNamedPipe$sep$LanguageServiceOutNamedPipe" + $languageServiceConfig.InPipeName = $LanguageServiceInNamedPipe + $languageServiceConfig.OutPipeName = $LanguageServiceOutNamedPipe if ($DebugServiceInNamedPipe -and $DebugServiceOutNamedPipe) { $debugServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::NamedPipe - $debugServiceConfig.Endpoint = "$DebugServiceInNamedPipe$sep$DebugServiceOutNamedPipe" + $debugServiceConfig.InPipeName = $DebugServiceInNamedPipe + $debugServiceConfig.OutPipeName = $DebugServiceOutNamedPipe } } } diff --git a/src/PowerShellEditorServices.Host/EditorServicesHost.cs b/src/PowerShellEditorServices.Host/EditorServicesHost.cs index 4c70f2a35..83192bbc3 100644 --- a/src/PowerShellEditorServices.Host/EditorServicesHost.cs +++ b/src/PowerShellEditorServices.Host/EditorServicesHost.cs @@ -43,7 +43,10 @@ public class EditorServiceTransportConfig /// For Stdio it's ignored. /// For NamedPipe it's the pipe name. /// - public string Endpoint { get; set; } + public string InOutPipeName { get; set; } + public string OutPipeName { get; set; } + public string InPipeName { get; set; } + internal string Endpoint => OutPipeName != null && InPipeName!=null ? $"In pipe: {InPipeName} Out pipe: {OutPipeName}" : $" InOut pipe: {InOutPipeName}"; } /// @@ -463,18 +466,14 @@ private IServerListener CreateServiceListener(MessageProtocolType protocol, Edit case EditorServiceTransportType.NamedPipe: { - string endpoint = config.Endpoint; - int splitIndex = endpoint.IndexOf(Path.DirectorySeparatorChar); - if (splitIndex > 0) + if (config.OutPipeName !=null && config.InPipeName !=null) { - string readPipeName = endpoint.Substring(0, splitIndex); - string writePipeName = endpoint.Substring(splitIndex + 1); - this.logger.Write(LogLevel.Verbose, $"Creating NamedPipeServerListener for ${protocol} protocol with two pipes: Read: '" + readPipeName + "'. Write: '" + writePipeName + "'"); - return new NamedPipeServerListener(protocol, readPipeName, writePipeName, this.logger); + this.logger.Write(LogLevel.Verbose, $"Creating NamedPipeServerListener for ${protocol} protocol with two pipes: In: '" + config.InPipeName + "'. Out: '" + config.OutPipeName + "'"); + return new NamedPipeServerListener(protocol, config.InPipeName, config.OutPipeName, this.logger); } else { - return new NamedPipeServerListener(protocol, endpoint, this.logger); + return new NamedPipeServerListener(protocol, config.InOutPipeName, this.logger); } } diff --git a/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerChannel.cs b/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerChannel.cs index 664cf16ac..0c3a9cfeb 100644 --- a/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerChannel.cs +++ b/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerChannel.cs @@ -11,24 +11,24 @@ namespace Microsoft.PowerShell.EditorServices.Protocol.MessageProtocol.Channel public class NamedPipeServerChannel : ChannelBase { private ILogger logger; - private NamedPipeServerStream pipeServer; - private NamedPipeServerStream writePipeServer; + private NamedPipeServerStream inOutPipeServer; + private NamedPipeServerStream outPipeServer; public NamedPipeServerChannel( - NamedPipeServerStream pipeServer, + NamedPipeServerStream inOutPipeServer, ILogger logger) { - this.pipeServer = pipeServer; - this.writePipeServer = null; + this.inOutPipeServer = inOutPipeServer; + this.outPipeServer = null; this.logger = logger; } public NamedPipeServerChannel( - NamedPipeServerStream readPipeServer, - NamedPipeServerStream writePipeServer, + NamedPipeServerStream inOutPipeServer, + NamedPipeServerStream outPipeServer, ILogger logger) { - this.pipeServer = readPipeServer; - this.writePipeServer = writePipeServer; + this.inOutPipeServer = inOutPipeServer; + this.outPipeServer = outPipeServer; this.logger = logger; } @@ -36,13 +36,13 @@ protected override void Initialize(IMessageSerializer messageSerializer) { this.MessageReader = new MessageReader( - this.pipeServer, + this.inOutPipeServer, messageSerializer, this.logger); this.MessageWriter = new MessageWriter( - this.writePipeServer ?? this.pipeServer, + this.outPipeServer ?? this.inOutPipeServer, messageSerializer, this.logger); } @@ -50,8 +50,8 @@ protected override void Initialize(IMessageSerializer messageSerializer) protected override void Shutdown() { // The server listener will take care of the pipe server - this.pipeServer = null; - this.writePipeServer = null; + this.inOutPipeServer = null; + this.outPipeServer = null; } } } diff --git a/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerListener.cs b/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerListener.cs index 37fcb359b..e9dc23008 100644 --- a/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerListener.cs +++ b/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerListener.cs @@ -19,32 +19,32 @@ namespace Microsoft.PowerShell.EditorServices.Protocol.MessageProtocol.Channel public class NamedPipeServerListener : ServerListenerBase { private ILogger logger; - private string pipeName; - private readonly string writePipeName; - private NamedPipeServerStream pipeServer; - private NamedPipeServerStream writePipeServer; + private string inOutPipeName; + private readonly string outPipeName; + private NamedPipeServerStream inOutPipeServer; + private NamedPipeServerStream outPipeServer; public NamedPipeServerListener( MessageProtocolType messageProtocolType, - string pipeName, + string inOutPipeName, ILogger logger) : base(messageProtocolType) { this.logger = logger; - this.pipeName = pipeName; - this.writePipeName = null; + this.inOutPipeName = inOutPipeName; + this.outPipeName = null; } public NamedPipeServerListener( MessageProtocolType messageProtocolType, - string readPipeName, - string writePipeName, + string inPipeName, + string outPipeName, ILogger logger) : base(messageProtocolType) { this.logger = logger; - this.pipeName = readPipeName; - this.writePipeName = writePipeName; + this.inOutPipeName = inPipeName; + this.outPipeName = outPipeName; } public override void Start() @@ -78,26 +78,26 @@ public override void Start() // 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.pipeServer = NamedPipeNative.CreateNamedPipe(pipeName, pipeSecurity); - if (this.writePipeName != null) + this.inOutPipeServer = NamedPipeNative.CreateNamedPipe(inOutPipeName, pipeSecurity); + if (this.outPipeName != null) { - this.writePipeServer = NamedPipeNative.CreateNamedPipe(writePipeName, pipeSecurity); + 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.pipeServer = new NamedPipeServerStream( - pipeName: pipeName, + this.inOutPipeServer = new NamedPipeServerStream( + pipeName: inOutPipeName, direction: PipeDirection.InOut, maxNumberOfServerInstances: 1, transmissionMode: PipeTransmissionMode.Byte, options: PipeOptions.Asynchronous); - if (this.writePipeName != null) + if (this.outPipeName != null) { - this.writePipeServer = new NamedPipeServerStream( - pipeName: writePipeName, + this.outPipeServer = new NamedPipeServerStream( + pipeName: outPipeName, direction: PipeDirection.Out, maxNumberOfServerInstances: 1, transmissionMode: PipeTransmissionMode.Byte, @@ -118,30 +118,30 @@ public override void Start() public override void Stop() { - if (this.pipeServer != null) + if (this.inOutPipeServer != null) { this.logger.Write(LogLevel.Verbose, "Named pipe server shutting down..."); - this.pipeServer.Dispose(); + this.inOutPipeServer.Dispose(); this.logger.Write(LogLevel.Verbose, "Named pipe server has been disposed."); } - if (this.writePipeServer != null) + if (this.outPipeServer != null) { - this.logger.Write(LogLevel.Verbose, $"Named write pipe server {writePipeServer} shutting down..."); + this.logger.Write(LogLevel.Verbose, $"Named out pipe server {outPipeServer} shutting down..."); - this.writePipeServer.Dispose(); + this.outPipeServer.Dispose(); - this.logger.Write(LogLevel.Verbose, $"Named write pipe server {writePipeServer} has been disposed."); + this.logger.Write(LogLevel.Verbose, $"Named out pipe server {outPipeServer} has been disposed."); } } private void ListenForConnection() { - List connectionTasks = new List {WaitForConnectionAsync(this.pipeServer)}; - if (this.writePipeServer != null) + List connectionTasks = new List {WaitForConnectionAsync(this.inOutPipeServer)}; + if (this.outPipeServer != null) { - connectionTasks.Add(WaitForConnectionAsync(this.writePipeServer)); + connectionTasks.Add(WaitForConnectionAsync(this.outPipeServer)); } Task.Run(async () => @@ -149,7 +149,7 @@ private void ListenForConnection() try { await Task.WhenAll(connectionTasks); - this.OnClientConnect(new NamedPipeServerChannel(this.pipeServer, this.writePipeServer, this.logger)); + this.OnClientConnect(new NamedPipeServerChannel(this.inOutPipeServer, this.outPipeServer, this.logger)); } catch (Exception e) { From 569c223992f95bdc1cba22a88d6bb51539a00381 Mon Sep 17 00:00:00 2001 From: Andrey Dernov Date: Sat, 10 Nov 2018 14:33:03 +0300 Subject: [PATCH 6/7] [ PowerShell/PowerShellEditorServices#785 PR ] Cleanup: refactorings, code style and reformat --- .../PowerShellEditorServices.psm1 | 13 +++-- .../Start-EditorServices.ps1 | 47 +++++++++++-------- .../EditorServicesHost.cs | 4 +- .../Channel/NamedPipeServerChannel.cs | 1 - .../Channel/NamedPipeServerListener.cs | 3 +- 5 files changed, 39 insertions(+), 29 deletions(-) diff --git a/module/PowerShellEditorServices/PowerShellEditorServices.psm1 b/module/PowerShellEditorServices/PowerShellEditorServices.psm1 index 873e1e6f7..dd8f463a6 100644 --- a/module/PowerShellEditorServices/PowerShellEditorServices.psm1 +++ b/module/PowerShellEditorServices/PowerShellEditorServices.psm1 @@ -44,21 +44,21 @@ function Start-EditorServicesHost { [string] $DebugServiceNamedPipe, - [Parameter(ParameterSetName="NamedPipeHalfDuplex",Mandatory=$true)] + [Parameter(ParameterSetName="NamedPipeSimplex",Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $LanguageServiceInNamedPipe, - [Parameter(ParameterSetName="NamedPipeHalfDuplex",Mandatory=$true)] + [Parameter(ParameterSetName="NamedPipeSimplex",Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $LanguageServiceOutNamedPipe, - [Parameter(ParameterSetName="NamedPipeHalfDuplex")] + [Parameter(ParameterSetName="NamedPipeSimplex")] [string] $DebugServiceInNamedPipe, - [Parameter(ParameterSetName="NamedPipeHalfDuplex")] + [Parameter(ParameterSetName="NamedPipeSimplex")] [string] $DebugServiceOutNamedPipe, @@ -125,6 +125,7 @@ function Start-EditorServicesHost { "Stdio" { $languageServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::Stdio $debugServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::Stdio + break } "NamedPipe" { $languageServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::NamedPipe @@ -133,8 +134,9 @@ function Start-EditorServicesHost { $debugServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::NamedPipe $debugServiceConfig.InOutPipeName = "$DebugServiceNamedPipe" } + break } - "NamedPipeHalfDuplex" { + "NamedPipeSimplex" { $languageServiceConfig.TransportType = [Microsoft.PowerShell.EditorServices.Host.EditorServiceTransportType]::NamedPipe $languageServiceConfig.InPipeName = $LanguageServiceInNamedPipe $languageServiceConfig.OutPipeName = $LanguageServiceOutNamedPipe @@ -143,6 +145,7 @@ function Start-EditorServicesHost { $debugServiceConfig.InPipeName = $DebugServiceInNamedPipe $debugServiceConfig.OutPipeName = $DebugServiceOutNamedPipe } + break } } diff --git a/module/PowerShellEditorServices/Start-EditorServices.ps1 b/module/PowerShellEditorServices/Start-EditorServices.ps1 index acc152543..79e2db18c 100644 --- a/module/PowerShellEditorServices/Start-EditorServices.ps1 +++ b/module/PowerShellEditorServices/Start-EditorServices.ps1 @@ -15,7 +15,7 @@ # Services GitHub repository: # # https://github.com/PowerShell/PowerShellEditorServices/blob/master/module/PowerShellEditorServices/Start-EditorServices.ps1 -[Cmdletbinding(DefaultParameterSetName="NamedPipe")] +[CmdletBinding(DefaultParameterSetName="NamedPipe")] param( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] @@ -77,25 +77,23 @@ param( [string] $DebugServicePipeName = $null, - [Parameter(ParameterSetName="NamedPipeHalfDuplex",Mandatory=$true)] + [Parameter(ParameterSetName="NamedPipeSimplex")] [switch] $SplitInOutPipes, - [Parameter(ParameterSetName="NamedPipeHalfDuplexParam",Mandatory=$true)] - [ValidateNotNullOrEmpty()] + [Parameter(ParameterSetName="NamedPipeSimplex")] [string] $LanguageServiceInPipeName, - [Parameter(ParameterSetName="NamedPipeHalfDuplexParam",Mandatory=$true)] - [ValidateNotNullOrEmpty()] + [Parameter(ParameterSetName="NamedPipeSimplex")] [string] $LanguageServiceOutPipeName, - [Parameter(ParameterSetName="NamedPipeHalfDuplexParam")] + [Parameter(ParameterSetName="NamedPipeSimplex")] [string] $DebugServiceInPipeName = $null, - [Parameter(ParameterSetName="NamedPipeHalfDuplexParam")] + [Parameter(ParameterSetName="NamedPipeSimplex")] [string] $DebugServiceOutPipeName = $null ) @@ -286,7 +284,15 @@ function Test-NamedPipeName-OrCreate-IfNull { return $PipeName } -function SetPipeFileResult($ResultTable, [string]$PipeNameKey, [string]$PipeNameValue) { +function Set-PipeFileResult { + param ( + [Hashtable] + $ResultTable, + [string] + $PipeNameKey, + [string] + $PipeNameValue + ) $ResultTable[$PipeNameKey] = Get-NamedPipePath -PipeName $PipeNameValue if ($IsLinux -or $IsMacOS) { Set-NamedPipeMode -PipeFile $ResultTable[$PipeNameKey] @@ -319,15 +325,15 @@ try { $resultDetails = @{ "status" = "not started"; - "languageServiceTransport" = $PSCmdlet.ParameterSetName.Replace("Param",""); - "debugServiceTransport" = $PSCmdlet.ParameterSetName.Replace("Param",""); + "languageServiceTransport" = $PSCmdlet.ParameterSetName; + "debugServiceTransport" = $PSCmdlet.ParameterSetName; }; # Create the Editor Services host Log "Invoking Start-EditorServicesHost" # There could be only one service on Stdio channel # Locate available port numbers for services - switch -Wildcard ($PSCmdlet.ParameterSetName) { + switch ($PSCmdlet.ParameterSetName) { "Stdio" { $editorServicesHost = Start-EditorServicesHost ` -HostName $HostName ` @@ -341,8 +347,9 @@ try { -EnableConsoleRepl:$EnableConsoleRepl.IsPresent ` -DebugServiceOnly:$DebugServiceOnly.IsPresent ` -WaitForDebugger:$WaitForDebugger.IsPresent + break } - "NamedPipeHalfDuplex*" { + "NamedPipeSimplex" { $LanguageServiceInPipeName = Test-NamedPipeName-OrCreate-IfNull $LanguageServiceInPipeName $LanguageServiceOutPipeName = Test-NamedPipeName-OrCreate-IfNull $LanguageServiceOutPipeName $DebugServiceInPipeName = Test-NamedPipeName-OrCreate-IfNull $DebugServiceInPipeName @@ -364,10 +371,11 @@ try { -DebugServiceOnly:$DebugServiceOnly.IsPresent ` -WaitForDebugger:$WaitForDebugger.IsPresent - SetPipeFileResult $resultDetails "languageServiceReadPipeName" $LanguageServiceInPipeName - SetPipeFileResult $resultDetails "languageServiceWritePipeName" $LanguageServiceOutPipeName - SetPipeFileResult $resultDetails "debugServiceReadPipeName" $DebugServiceInPipeName - SetPipeFileResult $resultDetails "debugServiceWritePipeName" $DebugServiceOutPipeName + Set-PipeFileResult $resultDetails "languageServiceReadPipeName" $LanguageServiceInPipeName + Set-PipeFileResult $resultDetails "languageServiceWritePipeName" $LanguageServiceOutPipeName + Set-PipeFileResult $resultDetails "debugServiceReadPipeName" $DebugServiceInPipeName + Set-PipeFileResult $resultDetails "debugServiceWritePipeName" $DebugServiceOutPipeName + break } Default { $LanguageServicePipeName = Test-NamedPipeName-OrCreate-IfNull $LanguageServicePipeName @@ -387,8 +395,9 @@ try { -DebugServiceOnly:$DebugServiceOnly.IsPresent ` -WaitForDebugger:$WaitForDebugger.IsPresent - SetPipeFileResult $resultDetails "languageServicePipeName" $LanguageServicePipeName - SetPipeFileResult $resultDetails "debugServicePipeName" $DebugServicePipeName + Set-PipeFileResult $resultDetails "languageServicePipeName" $LanguageServicePipeName + Set-PipeFileResult $resultDetails "debugServicePipeName" $DebugServicePipeName + break } } diff --git a/src/PowerShellEditorServices.Host/EditorServicesHost.cs b/src/PowerShellEditorServices.Host/EditorServicesHost.cs index b33258273..f30ffc4ec 100644 --- a/src/PowerShellEditorServices.Host/EditorServicesHost.cs +++ b/src/PowerShellEditorServices.Host/EditorServicesHost.cs @@ -47,7 +47,7 @@ public class EditorServiceTransportConfig public string InOutPipeName { get; set; } public string OutPipeName { get; set; } public string InPipeName { get; set; } - internal string Endpoint => OutPipeName != null && InPipeName!=null ? $"In pipe: {InPipeName} Out pipe: {OutPipeName}" : $" InOut pipe: {InOutPipeName}"; + internal string Endpoint => OutPipeName != null && InPipeName != null ? $"In pipe: {InPipeName} Out pipe: {OutPipeName}" : $" InOut pipe: {InOutPipeName}"; } /// @@ -468,7 +468,7 @@ private IServerListener CreateServiceListener(MessageProtocolType protocol, Edit { if (config.OutPipeName !=null && config.InPipeName !=null) { - this.logger.Write(LogLevel.Verbose, $"Creating NamedPipeServerListener for ${protocol} protocol with two pipes: In: '" + config.InPipeName + "'. Out: '" + config.OutPipeName + "'"); + this.logger.Write(LogLevel.Verbose, $"Creating NamedPipeServerListener for ${protocol} protocol with two pipes: In: '{config.InPipeName}'. Out: '{config.OutPipeName}'"); return new NamedPipeServerListener(protocol, config.InPipeName, config.OutPipeName, this.logger); } else diff --git a/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerChannel.cs b/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerChannel.cs index 0c3a9cfeb..870640c49 100644 --- a/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerChannel.cs +++ b/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerChannel.cs @@ -19,7 +19,6 @@ public NamedPipeServerChannel( ILogger logger) { this.inOutPipeServer = inOutPipeServer; - this.outPipeServer = null; this.logger = logger; } public NamedPipeServerChannel( diff --git a/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerListener.cs b/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerListener.cs index e9dc23008..8c42f2395 100644 --- a/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerListener.cs +++ b/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerListener.cs @@ -32,7 +32,6 @@ public NamedPipeServerListener( { this.logger = logger; this.inOutPipeName = inOutPipeName; - this.outPipeName = null; } public NamedPipeServerListener( @@ -138,7 +137,7 @@ public override void Stop() private void ListenForConnection() { - List connectionTasks = new List {WaitForConnectionAsync(this.inOutPipeServer)}; + var connectionTasks = new List {WaitForConnectionAsync(this.inOutPipeServer)}; if (this.outPipeServer != null) { connectionTasks.Add(WaitForConnectionAsync(this.outPipeServer)); From 93a391fe8790d5873be4fd7f5b57b06bb77baf1c Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Wed, 21 Nov 2018 09:25:36 -0800 Subject: [PATCH 7/7] remove e in excpe --- .../MessageProtocol/Channel/NamedPipeServerListener.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerListener.cs b/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerListener.cs index 8c42f2395..ba2c74931 100644 --- a/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerListener.cs +++ b/src/PowerShellEditorServices.Protocol/MessageProtocol/Channel/NamedPipeServerListener.cs @@ -156,7 +156,7 @@ private void ListenForConnection() "An unhandled exception occurred while listening for a named pipe client connection", e); - throw e; + throw; } }); }