diff --git a/src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs b/src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs index 8ace8df25..0e97b8edd 100644 --- a/src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs +++ b/src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs @@ -16,7 +16,6 @@ using System.Diagnostics; using System.IO; using System.Linq; -using System.Management.Automation; using System.Management.Automation.Language; using System.Management.Automation.Runspaces; using System.Text; @@ -28,6 +27,8 @@ namespace Microsoft.PowerShell.EditorServices.Protocol.Server { + using System.Management.Automation; + public class LanguageServer { private static CancellationTokenSource s_existingRequestCancellation; @@ -1225,7 +1226,7 @@ protected async Task HandleGetRunspaceRequestAsync( string processId, RequestContext requestContext) { - var runspaceResponses = new List(); + IEnumerable runspaces = null; if (this.editorSession.PowerShellContext.LocalPowerShellVersion.Version.Major >= 5) { @@ -1233,36 +1234,42 @@ protected async Task HandleGetRunspaceRequestAsync( processId = "current"; } - var isNotCurrentProcess = processId != null && processId != "current"; - - var psCommand = new PSCommand(); - - if (isNotCurrentProcess) { - psCommand.AddCommand("Enter-PSHostProcess").AddParameter("Id", processId).AddStatement(); - } - - psCommand.AddCommand("Get-Runspace"); - - StringBuilder sb = new StringBuilder(); - IEnumerable runspaces = await editorSession.PowerShellContext.ExecuteCommandAsync(psCommand, sb); - if (runspaces != null) + // If the processId is a valid int, we need to run Get-Runspace within that process + // otherwise just use the current runspace. + if (int.TryParse(processId, out int pid)) { - foreach (var p in runspaces) + // Create a remote runspace that we will invoke Get-Runspace in. + using(var rs = RunspaceFactory.CreateRunspace(new NamedPipeConnectionInfo(pid))) + using(var ps = PowerShell.Create()) { - runspaceResponses.Add( - new GetRunspaceResponse - { - Id = p.Id, - Name = p.Name, - Availability = p.RunspaceAvailability.ToString() - }); + rs.Open(); + ps.Runspace = rs; + // Returns deserialized Runspaces. For simpler code, we use PSObject and rely on dynamic later. + runspaces = ps.AddCommand("Microsoft.PowerShell.Utility\\Get-Runspace").Invoke(); } } + else + { + var psCommand = new PSCommand().AddCommand("Microsoft.PowerShell.Utility\\Get-Runspace"); + var sb = new StringBuilder(); + // returns (not deserialized) Runspaces. For simpler code, we use PSObject and rely on dynamic later. + runspaces = await editorSession.PowerShellContext.ExecuteCommandAsync(psCommand, sb); + } + } + + var runspaceResponses = new List(); - if (isNotCurrentProcess) { - var exitCommand = new PSCommand(); - exitCommand.AddCommand("Exit-PSHostProcess"); - await editorSession.PowerShellContext.ExecuteCommandAsync(exitCommand); + if (runspaces != null) + { + foreach (dynamic runspace in runspaces) + { + runspaceResponses.Add( + new GetRunspaceResponse + { + Id = runspace.Id, + Name = runspace.Name, + Availability = runspace.RunspaceAvailability.ToString() + }); } }