From 13e1385308083a6352bd74b7a6617904912a3b84 Mon Sep 17 00:00:00 2001 From: "Tyler Leonhardt (POWERSHELL)" Date: Tue, 26 Feb 2019 15:46:42 -0800 Subject: [PATCH 1/4] Support -CustomPipeName --- .../DebugAdapter/AttachRequest.cs | 2 + .../Server/DebugAdapter.cs | 64 ++++++++++++------- 2 files changed, 44 insertions(+), 22 deletions(-) diff --git a/src/PowerShellEditorServices.Protocol/DebugAdapter/AttachRequest.cs b/src/PowerShellEditorServices.Protocol/DebugAdapter/AttachRequest.cs index e9734e002..24f117699 100644 --- a/src/PowerShellEditorServices.Protocol/DebugAdapter/AttachRequest.cs +++ b/src/PowerShellEditorServices.Protocol/DebugAdapter/AttachRequest.cs @@ -21,5 +21,7 @@ public class AttachRequestArguments public string ProcessId { get; set; } public int RunspaceId { get; set; } + + public string CustomPipeName { get; set; } } } diff --git a/src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs b/src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs index 69a720f8e..a3261346f 100644 --- a/src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs +++ b/src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs @@ -350,11 +350,17 @@ protected async Task HandleAttachRequestAsync( RegisterEventHandlers(); + bool processIdIsSet = !string.IsNullOrEmpty(attachParams.ProcessId) && attachParams.ProcessId != "undefined"; + bool customPipeNameIsSet = !string.IsNullOrEmpty(attachParams.CustomPipeName) && attachParams.CustomPipeName != "undefined"; + + PowerShellVersionDetails runspaceVersion = + _editorSession.PowerShellContext.CurrentRunspace.PowerShellVersion; + // If there are no host processes to attach to or the user cancels selection, we get a null for the process id. // This is not an error, just a request to stop the original "attach to" request. // Testing against "undefined" is a HACK because I don't know how to make "Cancel" on quick pick loading // to cancel on the VSCode side without sending an attachRequest with processId set to "undefined". - if (string.IsNullOrEmpty(attachParams.ProcessId) || (attachParams.ProcessId == "undefined")) + if (!processIdIsSet && !customPipeNameIsSet) { Logger.Write( LogLevel.Normal, @@ -370,9 +376,6 @@ await requestContext.SendErrorAsync( if (attachParams.ComputerName != null) { - PowerShellVersionDetails runspaceVersion = - _editorSession.PowerShellContext.CurrentRunspace.PowerShellVersion; - if (runspaceVersion.Version.Major < 4) { await requestContext.SendErrorAsync( @@ -403,16 +406,12 @@ await requestContext.SendErrorAsync( _isRemoteAttach = true; } - if (int.TryParse(attachParams.ProcessId, out int processId) && (processId > 0)) + if (processIdIsSet && int.TryParse(attachParams.ProcessId, out int processId) && (processId > 0)) { - PowerShellVersionDetails runspaceVersion = - _editorSession.PowerShellContext.CurrentRunspace.PowerShellVersion; - if (runspaceVersion.Version.Major < 5) { await requestContext.SendErrorAsync( $"Attaching to a process is only available with PowerShell 5 and higher (current session is {runspaceVersion.Version})."); - return; } @@ -427,20 +426,27 @@ await requestContext.SendErrorAsync( return; } + } + else if (customPipeNameIsSet) + { + if (runspaceVersion.Version.Major < 6 && runspaceVersion.Version.Minor < 2) + { + await requestContext.SendErrorAsync( + $"Attaching to a process with CustomPipeName is only available with PowerShell 6.2 and higher (current session is {runspaceVersion.Version})."); + return; + } + + await _editorSession.PowerShellContext.ExecuteScriptStringAsync( + $"Enter-PSHostProcess -CustomPipeName {attachParams.CustomPipeName}", + errorMessages); + + if (errorMessages.Length > 0) + { + await requestContext.SendErrorAsync( + $"Could not attach to process with CustomPipeName: '{attachParams.CustomPipeName}'"); - // Clear any existing breakpoints before proceeding - await ClearSessionBreakpointsAsync(); - - // Execute the Debug-Runspace command but don't await it because it - // 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; - _waitingForAttach = true; - Task nonAwaitedTask = - _editorSession.PowerShellContext - .ExecuteScriptStringAsync($"\nDebug-Runspace -Id {runspaceId}") - .ContinueWith(OnExecutionCompletedAsync); + return; + } } else { @@ -454,6 +460,20 @@ await requestContext.SendErrorAsync( return; } + // Clear any existing breakpoints before proceeding + await ClearSessionBreakpointsAsync(); + + // Execute the Debug-Runspace command but don't await it because it + // 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; + _waitingForAttach = true; + Task nonAwaitedTask = + _editorSession.PowerShellContext + .ExecuteScriptStringAsync($"\nDebug-Runspace -Id {runspaceId}") + .ContinueWith(OnExecutionCompletedAsync); + await requestContext.SendResultAsync(null); } From 5162fb9a6ce7724990962c00cb99652d8411b4f3 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Tue, 5 Mar 2019 08:02:51 -0500 Subject: [PATCH 2/4] codacy fix --- .../Server/DebugAdapter.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs b/src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs index a3261346f..6d54b85f4 100644 --- a/src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs +++ b/src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs @@ -461,7 +461,7 @@ await requestContext.SendErrorAsync( } // Clear any existing breakpoints before proceeding - await ClearSessionBreakpointsAsync(); + await ClearSessionBreakpointsAsync().ConfigureAwait(false); // Execute the Debug-Runspace command but don't await it because it // will block the debug adapter initialization process. The @@ -470,9 +470,9 @@ await requestContext.SendErrorAsync( int runspaceId = attachParams.RunspaceId > 0 ? attachParams.RunspaceId : 1; _waitingForAttach = true; Task nonAwaitedTask = - _editorSession.PowerShellContext - .ExecuteScriptStringAsync($"\nDebug-Runspace -Id {runspaceId}") - .ContinueWith(OnExecutionCompletedAsync); + _editorSession.PowerShellContext + .ExecuteScriptStringAsync($"\nDebug-Runspace -Id {runspaceId}") + .ContinueWith(OnExecutionCompletedAsync); await requestContext.SendResultAsync(null); } From fc7b4ad5d5b9f996b300b195779f207de4a12ef1 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Wed, 6 Mar 2019 14:00:08 -0800 Subject: [PATCH 3/4] feedback from @rjmholt --- .../Server/DebugAdapter.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs b/src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs index 6d54b85f4..d7eef7bab 100644 --- a/src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs +++ b/src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs @@ -23,6 +23,8 @@ namespace Microsoft.PowerShell.EditorServices.Protocol.Server { public class DebugAdapter { + private static Version _minVersionForCustomPipeName = new Version(6, 2); + private EditorSession _editorSession; private bool _noDebug; @@ -429,7 +431,7 @@ await requestContext.SendErrorAsync( } else if (customPipeNameIsSet) { - if (runspaceVersion.Version.Major < 6 && runspaceVersion.Version.Minor < 2) + if (runspaceVersion.Version < _minVersionForCustomPipeName) { await requestContext.SendErrorAsync( $"Attaching to a process with CustomPipeName is only available with PowerShell 6.2 and higher (current session is {runspaceVersion.Version})."); @@ -461,7 +463,7 @@ await requestContext.SendErrorAsync( } // Clear any existing breakpoints before proceeding - await ClearSessionBreakpointsAsync().ConfigureAwait(false); + await ClearSessionBreakpointsAsync().ConfigureAwait(continueOnCapturedContext: false); // Execute the Debug-Runspace command but don't await it because it // will block the debug adapter initialization process. The @@ -469,8 +471,7 @@ await requestContext.SendErrorAsync( // event gets fired with the attached runspace. int runspaceId = attachParams.RunspaceId > 0 ? attachParams.RunspaceId : 1; _waitingForAttach = true; - Task nonAwaitedTask = - _editorSession.PowerShellContext + Task nonAwaitedTask = _editorSession.PowerShellContext .ExecuteScriptStringAsync($"\nDebug-Runspace -Id {runspaceId}") .ContinueWith(OnExecutionCompletedAsync); From 89d2217300689fb33f4ecabf7d5150744fca2fca Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Wed, 6 Mar 2019 16:50:45 -0800 Subject: [PATCH 4/4] address more feedback from @rjmholt --- src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs b/src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs index d7eef7bab..88fc797e1 100644 --- a/src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs +++ b/src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs @@ -23,7 +23,7 @@ namespace Microsoft.PowerShell.EditorServices.Protocol.Server { public class DebugAdapter { - private static Version _minVersionForCustomPipeName = new Version(6, 2); + private static readonly Version _minVersionForCustomPipeName = new Version(6, 2); private EditorSession _editorSession;