示例#1
0
        protected async Task HandleSetBreakpointsRequest(
            SetBreakpointsRequestArguments setBreakpointsParams,
            RequestContext <SetBreakpointsResponseBody> requestContext)
        {
            ScriptFile scriptFile;

            // Fix for issue #195 - user can change name of file outside of VSCode in which case
            // VSCode sends breakpoint requests with the original filename that doesn't exist anymore.
            try
            {
                scriptFile = editorSession.Workspace.GetFile(setBreakpointsParams.Source.Path);
            }
            catch (FileNotFoundException)
            {
                Logger.Write(
                    LogLevel.Warning,
                    $"Attempted to set breakpoints on a non-existing file: {setBreakpointsParams.Source.Path}");

                string message = this.noDebug ? string.Empty : "Source does not exist, breakpoint not set.";

                var srcBreakpoints = setBreakpointsParams.Breakpoints
                                     .Select(srcBkpt => Protocol.DebugAdapter.Breakpoint.Create(
                                                 srcBkpt, setBreakpointsParams.Source.Path, message, verified: this.noDebug));

                // Return non-verified breakpoint message.
                await requestContext.SendResult(
                    new SetBreakpointsResponseBody {
                    Breakpoints = srcBreakpoints.ToArray()
                });

                return;
            }

            var breakpointDetails = new BreakpointDetails[setBreakpointsParams.Breakpoints.Length];

            for (int i = 0; i < breakpointDetails.Length; i++)
            {
                SourceBreakpoint srcBreakpoint = setBreakpointsParams.Breakpoints[i];
                breakpointDetails[i] = BreakpointDetails.Create(
                    scriptFile.FilePath,
                    srcBreakpoint.Line,
                    srcBreakpoint.Column,
                    srcBreakpoint.Condition);
            }

            // If this is a "run without debugging (Ctrl+F5)" session ignore requests to set breakpoints.
            BreakpointDetails[] updatedBreakpointDetails = breakpointDetails;
            if (!this.noDebug)
            {
                updatedBreakpointDetails =
                    await editorSession.DebugService.SetLineBreakpoints(
                        scriptFile,
                        breakpointDetails);
            }

            await requestContext.SendResult(
                new SetBreakpointsResponseBody {
                Breakpoints =
                    updatedBreakpointDetails
                    .Select(Protocol.DebugAdapter.Breakpoint.Create)
                    .ToArray()
            });
        }
        protected async Task HandleSetBreakpointsRequestAsync(
            SetBreakpointsRequestArguments setBreakpointsParams,
            RequestContext <SetBreakpointsResponseBody> requestContext)
        {
            ScriptFile scriptFile = null;

            // When you set a breakpoint in the right pane of a Git diff window on a PS1 file,
            // the Source.Path comes through as Untitled-X. That's why we check for IsUntitledPath.
            if (!ScriptFile.IsUntitledPath(setBreakpointsParams.Source.Path) &&
                !_editorSession.Workspace.TryGetFile(
                    setBreakpointsParams.Source.Path,
                    out scriptFile))
            {
                string message        = _noDebug ? string.Empty : "Source file could not be accessed, breakpoint not set.";
                var    srcBreakpoints = setBreakpointsParams.Breakpoints
                                        .Select(srcBkpt => Protocol.DebugAdapter.Breakpoint.Create(
                                                    srcBkpt, setBreakpointsParams.Source.Path, message, verified: _noDebug));

                // Return non-verified breakpoint message.
                await requestContext.SendResultAsync(
                    new SetBreakpointsResponseBody {
                    Breakpoints = srcBreakpoints.ToArray()
                });

                return;
            }

            // Verify source file is a PowerShell script file.
            string fileExtension = Path.GetExtension(scriptFile?.FilePath ?? "")?.ToLower();

            if (string.IsNullOrEmpty(fileExtension) || ((fileExtension != ".ps1") && (fileExtension != ".psm1")))
            {
                Logger.Write(
                    LogLevel.Warning,
                    $"Attempted to set breakpoints on a non-PowerShell file: {setBreakpointsParams.Source.Path}");

                string message = _noDebug ? string.Empty : "Source is not a PowerShell script, breakpoint not set.";

                var srcBreakpoints = setBreakpointsParams.Breakpoints
                                     .Select(srcBkpt => Protocol.DebugAdapter.Breakpoint.Create(
                                                 srcBkpt, setBreakpointsParams.Source.Path, message, verified: _noDebug));

                // Return non-verified breakpoint message.
                await requestContext.SendResultAsync(
                    new SetBreakpointsResponseBody
                {
                    Breakpoints = srcBreakpoints.ToArray()
                });

                return;
            }

            // At this point, the source file has been verified as a PowerShell script.
            var breakpointDetails = new BreakpointDetails[setBreakpointsParams.Breakpoints.Length];

            for (int i = 0; i < breakpointDetails.Length; i++)
            {
                SourceBreakpoint srcBreakpoint = setBreakpointsParams.Breakpoints[i];
                breakpointDetails[i] = BreakpointDetails.Create(
                    scriptFile.FilePath,
                    srcBreakpoint.Line,
                    srcBreakpoint.Column,
                    srcBreakpoint.Condition,
                    srcBreakpoint.HitCondition);
            }

            // If this is a "run without debugging (Ctrl+F5)" session ignore requests to set breakpoints.
            BreakpointDetails[] updatedBreakpointDetails = breakpointDetails;
            if (!_noDebug)
            {
                _setBreakpointInProgress = true;

                try
                {
                    updatedBreakpointDetails =
                        await _editorSession.DebugService.SetLineBreakpointsAsync(
                            scriptFile,
                            breakpointDetails);
                }
                catch (Exception e)
                {
                    // Log whatever the error is
                    Logger.WriteException($"Caught error while setting breakpoints in SetBreakpoints handler for file {scriptFile?.FilePath}", e);
                }
                finally
                {
                    _setBreakpointInProgress = false;
                }
            }

            await requestContext.SendResultAsync(
                new SetBreakpointsResponseBody {
                Breakpoints =
                    updatedBreakpointDetails
                    .Select(Protocol.DebugAdapter.Breakpoint.Create)
                    .ToArray()
            });
        }
        protected async Task HandleSetBreakpointsRequest(
            SetBreakpointsRequestArguments setBreakpointsParams,
            RequestContext <SetBreakpointsResponseBody> requestContext)
        {
            ScriptFile scriptFile = null;

            // Fix for issue #195 - user can change name of file outside of VSCode in which case
            // VSCode sends breakpoint requests with the original filename that doesn't exist anymore.
            try
            {
                // When you set a breakpoint in the right pane of a Git diff window on a PS1 file,
                // the Source.Path comes through as Untitled-X.
                if (!ScriptFile.IsUntitledPath(setBreakpointsParams.Source.Path))
                {
                    scriptFile = editorSession.Workspace.GetFile(setBreakpointsParams.Source.Path);
                }
            }
            catch (Exception e) when(
                e is FileNotFoundException ||
                e is DirectoryNotFoundException ||
                e is IOException ||
                e is NotSupportedException ||
                e is PathTooLongException ||
                e is SecurityException ||
                e is UnauthorizedAccessException)
            {
                Logger.WriteException(
                    $"Failed to set breakpoint on file: {setBreakpointsParams.Source.Path}",
                    e);

                string message        = this.noDebug ? string.Empty : "Source file could not be accessed, breakpoint not set - " + e.Message;
                var    srcBreakpoints = setBreakpointsParams.Breakpoints
                                        .Select(srcBkpt => Protocol.DebugAdapter.Breakpoint.Create(
                                                    srcBkpt, setBreakpointsParams.Source.Path, message, verified: this.noDebug));

                // Return non-verified breakpoint message.
                await requestContext.SendResult(
                    new SetBreakpointsResponseBody {
                    Breakpoints = srcBreakpoints.ToArray()
                });

                return;
            }

            // Verify source file is a PowerShell script file.
            string fileExtension = Path.GetExtension(scriptFile?.FilePath ?? "")?.ToLower();

            if (string.IsNullOrEmpty(fileExtension) || ((fileExtension != ".ps1") && (fileExtension != ".psm1")))
            {
                Logger.Write(
                    LogLevel.Warning,
                    $"Attempted to set breakpoints on a non-PowerShell file: {setBreakpointsParams.Source.Path}");

                string message = this.noDebug ? string.Empty : "Source is not a PowerShell script, breakpoint not set.";

                var srcBreakpoints = setBreakpointsParams.Breakpoints
                                     .Select(srcBkpt => Protocol.DebugAdapter.Breakpoint.Create(
                                                 srcBkpt, setBreakpointsParams.Source.Path, message, verified: this.noDebug));

                // Return non-verified breakpoint message.
                await requestContext.SendResult(
                    new SetBreakpointsResponseBody
                {
                    Breakpoints = srcBreakpoints.ToArray()
                });

                return;
            }

            // At this point, the source file has been verified as a PowerShell script.
            var breakpointDetails = new BreakpointDetails[setBreakpointsParams.Breakpoints.Length];

            for (int i = 0; i < breakpointDetails.Length; i++)
            {
                SourceBreakpoint srcBreakpoint = setBreakpointsParams.Breakpoints[i];
                breakpointDetails[i] = BreakpointDetails.Create(
                    scriptFile.FilePath,
                    srcBreakpoint.Line,
                    srcBreakpoint.Column,
                    srcBreakpoint.Condition,
                    srcBreakpoint.HitCondition);
            }

            // If this is a "run without debugging (Ctrl+F5)" session ignore requests to set breakpoints.
            BreakpointDetails[] updatedBreakpointDetails = breakpointDetails;
            if (!this.noDebug)
            {
                this.setBreakpointInProgress = true;

                try
                {
                    updatedBreakpointDetails =
                        await editorSession.DebugService.SetLineBreakpoints(
                            scriptFile,
                            breakpointDetails);
                }
                catch (Exception e)
                {
                    // Log whatever the error is
                    Logger.WriteException($"Caught error while setting breakpoints in SetBreakpoints handler for file {scriptFile?.FilePath}", e);
                }
                finally
                {
                    this.setBreakpointInProgress = false;
                }
            }

            await requestContext.SendResult(
                new SetBreakpointsResponseBody {
                Breakpoints =
                    updatedBreakpointDetails
                    .Select(Protocol.DebugAdapter.Breakpoint.Create)
                    .ToArray()
            });
        }