Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add attach to local runspace. #875

Merged
merged 11 commits into from
Mar 13, 2019
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class AttachRequestArguments

public string ProcessId { get; set; }

public int RunspaceId { get; set; }
public string RunspaceId { get; set; }

public string CustomPipeName { get; set; }
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

using Microsoft.PowerShell.EditorServices.Protocol.MessageProtocol;

namespace Microsoft.PowerShell.EditorServices.Protocol.LanguageServer
{
public class GetRunspaceRequest
{
public static readonly
RequestType<string, GetRunspaceResponse[], object, object> Type =
RequestType<string, GetRunspaceResponse[], object, object>.Create("powerShell/getRunspace");
}

public class GetRunspaceResponse
{
public int Id { get; set; }

public string Name { get; set; }

public string Availability { get; set; }
}
}
17 changes: 15 additions & 2 deletions src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ await requestContext.SendErrorAsync(
return;
}
}
else
else if (attachParams.ProcessId != "current")
{
Logger.Write(
LogLevel.Error,
Expand All @@ -469,7 +469,20 @@ await requestContext.SendErrorAsync(
// will block the debug adapter initialization process. The
// InitializedEvent will be sent as soon as the RunspaceChanged
// event gets fired with the attached runspace.
int runspaceId = attachParams.RunspaceId > 0 ? attachParams.RunspaceId : 1;

var runspaceId = 1;
if (!int.TryParse(attachParams.RunspaceId, out runspaceId) || runspaceId <= 0)
{
Logger.Write(
LogLevel.Error,
$"Attach request failed, '{attachParams.RunspaceId}' is an invalid value for the processId.");

await requestContext.SendErrorAsync(
"A positive integer must be specified for the RunspaceId field.");

return;
}

_waitingForAttach = true;
Task nonAwaitedTask = _editorSession.PowerShellContext
.ExecuteScriptStringAsync($"\nDebug-Runspace -Id {runspaceId}")
Expand Down
51 changes: 51 additions & 0 deletions src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
using System.Linq;
using System.Management.Automation;
using System.Management.Automation.Language;
using System.Management.Automation.Runspaces;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
Expand Down Expand Up @@ -161,6 +162,8 @@ public void Start()
this.messageHandlers.SetRequestHandler(GetPSHostProcessesRequest.Type, this.HandleGetPSHostProcessesRequestAsync);
this.messageHandlers.SetRequestHandler(CommentHelpRequest.Type, this.HandleCommentHelpRequestAsync);

this.messageHandlers.SetRequestHandler(GetRunspaceRequest.Type, this.HandleGetRunspaceRequestAsync);

// Initialize the extension service
// TODO: This should be made awaited once Initialize is async!
this.editorSession.ExtensionService.InitializeAsync(
Expand Down Expand Up @@ -1218,6 +1221,54 @@ protected async Task HandleCommentHelpRequestAsync(
await requestContext.SendResultAsync(result);
}

protected async Task HandleGetRunspaceRequestAsync(
string processId,
RequestContext<GetRunspaceResponse[]> requestContext)
{
var runspaceResponses = new List<GetRunspaceResponse>();

if (this.editorSession.PowerShellContext.LocalPowerShellVersion.Version.Major >= 5)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was Get-Runspace added in 5?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a really good question. I just took that check from the process picker but I'm not sure when Debug-Runspace\Get-Runspace was added. I can try and find out.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well looks like that answers our question :)

{
if (processId == null) {
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<Runspace> runspaces = await editorSession.PowerShellContext.ExecuteCommandAsync<Runspace>(psCommand, sb);
if (runspaces != null)
{
foreach (var p in runspaces)
{
runspaceResponses.Add(
new GetRunspaceResponse
{
Id = p.Id,
Name = p.Name,
Availability = p.RunspaceAvailability.ToString()
});
}
}

if (isNotCurrentProcess) {
var exitCommand = new PSCommand();
exitCommand.AddCommand("Exit-PSHostProcess");
await editorSession.PowerShellContext.ExecuteCommandAsync(exitCommand);
}
}

await requestContext.SendResultAsync(runspaceResponses.ToArray());
}

private bool IsQueryMatch(string query, string symbolName)
{
return symbolName.IndexOf(query, StringComparison.OrdinalIgnoreCase) >= 0;
Expand Down