public async Task <List <Breakpoint> > GetBreakpointsAsync() { if (BreakpointApiUtils.SupportsBreakpointApis) { return(BreakpointApiUtils.GetBreakpoints( _powerShellContextService.CurrentRunspace.Runspace.Debugger, _debugStateService.RunspaceId)); } // Legacy behavior PSCommand psCommand = new PSCommand(); psCommand.AddCommand(@"Microsoft.PowerShell.Utility\Get-PSBreakpoint"); IEnumerable <Breakpoint> breakpoints = await _powerShellContextService.ExecuteCommandAsync <Breakpoint>(psCommand); return(breakpoints.ToList()); }
private bool IsFileSupportedForBreakpoints(string requestedPath, ScriptFile resolvedScriptFile) { // PowerShell 7 and above support breakpoints in untitled files if (ScriptFile.IsUntitledPath(requestedPath)) { return(BreakpointApiUtils.SupportsBreakpointApis(_runspaceContext.CurrentRunspace)); } if (string.IsNullOrEmpty(resolvedScriptFile?.FilePath)) { return(false); } string fileExtension = Path.GetExtension(resolvedScriptFile.FilePath); return(s_supportedDebugFileExtensions.Contains(fileExtension, StringComparer.OrdinalIgnoreCase)); }
public async Task RemoveBreakpointsAsync(IEnumerable <Breakpoint> breakpoints) { if (BreakpointApiUtils.SupportsBreakpointApis) { foreach (Breakpoint breakpoint in breakpoints) { BreakpointApiUtils.RemoveBreakpoint( _powerShellContextService.CurrentRunspace.Runspace.Debugger, breakpoint, _debugStateService.RunspaceId); switch (breakpoint) { case CommandBreakpoint commandBreakpoint: CommandBreakpoints.Remove(commandBreakpoint); break; case LineBreakpoint lineBreakpoint: if (BreakpointsPerFile.TryGetValue(lineBreakpoint.Script, out HashSet <Breakpoint> bps)) { bps.Remove(lineBreakpoint); } break; default: throw new ArgumentException("Unsupported breakpoint type."); } } return; } // Legacy behavior var breakpointIds = breakpoints.Select(b => b.Id).ToArray(); if (breakpointIds.Length > 0) { PSCommand psCommand = new PSCommand(); psCommand.AddCommand(@"Microsoft.PowerShell.Utility\Remove-PSBreakpoint"); psCommand.AddParameter("Id", breakpoints.Select(b => b.Id).ToArray()); await _powerShellContextService.ExecuteCommandAsync <object>(psCommand); } }
/// <summary> /// Clears all breakpoints in the current session. /// </summary> public async Task RemoveAllBreakpointsAsync(string scriptPath = null) { try { if (BreakpointApiUtils.SupportsBreakpointApis) { foreach (Breakpoint breakpoint in BreakpointApiUtils.GetBreakpoints( _powerShellContextService.CurrentRunspace.Runspace.Debugger, _debugStateService.RunspaceId)) { if (scriptPath == null || scriptPath == breakpoint.Script) { BreakpointApiUtils.RemoveBreakpoint( _powerShellContextService.CurrentRunspace.Runspace.Debugger, breakpoint, _debugStateService.RunspaceId); } } return; } // Legacy behavior PSCommand psCommand = new PSCommand(); psCommand.AddCommand(@"Microsoft.PowerShell.Utility\Get-PSBreakpoint"); if (!string.IsNullOrEmpty(scriptPath)) { psCommand.AddParameter("Script", scriptPath); } psCommand.AddCommand(@"Microsoft.PowerShell.Utility\Remove-PSBreakpoint"); await _powerShellContextService.ExecuteCommandAsync <object>(psCommand).ConfigureAwait(false); } catch (Exception e) { _logger.LogException("Caught exception while clearing breakpoints from session", e); } }
public async Task <IEnumerable <BreakpointDetails> > SetBreakpointsAsync(string escapedScriptPath, IEnumerable <BreakpointDetails> breakpoints) { if (BreakpointApiUtils.SupportsBreakpointApis) { foreach (BreakpointDetails breakpointDetails in breakpoints) { try { BreakpointApiUtils.SetBreakpoint(_powerShellContextService.CurrentRunspace.Runspace.Debugger, breakpointDetails, _debugStateService.RunspaceId); } catch (InvalidOperationException e) { breakpointDetails.Message = e.Message; breakpointDetails.Verified = false; } } return(breakpoints); } // Legacy behavior PSCommand psCommand = null; List <BreakpointDetails> configuredBreakpoints = new List <BreakpointDetails>(); foreach (BreakpointDetails breakpoint in breakpoints) { ScriptBlock actionScriptBlock = null; // Check if this is a "conditional" line breakpoint. if (!string.IsNullOrWhiteSpace(breakpoint.Condition) || !string.IsNullOrWhiteSpace(breakpoint.HitCondition) || !string.IsNullOrWhiteSpace(breakpoint.LogMessage)) { actionScriptBlock = BreakpointApiUtils.GetBreakpointActionScriptBlock( breakpoint.Condition, breakpoint.HitCondition, breakpoint.LogMessage, out string errorMessage); if (!string.IsNullOrEmpty(errorMessage)) { breakpoint.Verified = false; breakpoint.Message = errorMessage; configuredBreakpoints.Add(breakpoint); continue; } } // On first iteration psCommand will be null, every subsequent // iteration will need to start a new statement. if (psCommand == null) { psCommand = new PSCommand(); } else { psCommand.AddStatement(); } psCommand .AddCommand(@"Microsoft.PowerShell.Utility\Set-PSBreakpoint") .AddParameter("Script", escapedScriptPath) .AddParameter("Line", breakpoint.LineNumber); // Check if the user has specified the column number for the breakpoint. if (breakpoint.ColumnNumber.HasValue && breakpoint.ColumnNumber.Value > 0) { // It bums me out that PowerShell will silently ignore a breakpoint // where either the line or the column is invalid. I'd rather have an // error or warning message I could relay back to the client. psCommand.AddParameter("Column", breakpoint.ColumnNumber.Value); } if (actionScriptBlock != null) { psCommand.AddParameter("Action", actionScriptBlock); } } // If no PSCommand was created then there are no breakpoints to set. if (psCommand != null) { IEnumerable <Breakpoint> setBreakpoints = await _powerShellContextService.ExecuteCommandAsync <Breakpoint>(psCommand); configuredBreakpoints.AddRange( setBreakpoints.Select(BreakpointDetails.Create)); } return(configuredBreakpoints); }
public async Task <IEnumerable <CommandBreakpointDetails> > SetCommandBreakpoints(IEnumerable <CommandBreakpointDetails> breakpoints) { if (BreakpointApiUtils.SupportsBreakpointApis) { foreach (CommandBreakpointDetails commandBreakpointDetails in breakpoints) { try { BreakpointApiUtils.SetBreakpoint(_powerShellContextService.CurrentRunspace.Runspace.Debugger, commandBreakpointDetails, _debugStateService.RunspaceId); } catch (InvalidOperationException e) { commandBreakpointDetails.Message = e.Message; commandBreakpointDetails.Verified = false; } } return(breakpoints); } // Legacy behavior PSCommand psCommand = null; List <CommandBreakpointDetails> configuredBreakpoints = new List <CommandBreakpointDetails>(); foreach (CommandBreakpointDetails breakpoint in breakpoints) { // On first iteration psCommand will be null, every subsequent // iteration will need to start a new statement. if (psCommand == null) { psCommand = new PSCommand(); } else { psCommand.AddStatement(); } psCommand .AddCommand(@"Microsoft.PowerShell.Utility\Set-PSBreakpoint") .AddParameter("Command", breakpoint.Name); // Check if this is a "conditional" line breakpoint. if (!string.IsNullOrWhiteSpace(breakpoint.Condition) || !string.IsNullOrWhiteSpace(breakpoint.HitCondition)) { ScriptBlock actionScriptBlock = BreakpointApiUtils.GetBreakpointActionScriptBlock( breakpoint.Condition, breakpoint.HitCondition, logMessage: null, out string errorMessage); // If there was a problem with the condition string, // move onto the next breakpoint. if (!string.IsNullOrEmpty(errorMessage)) { breakpoint.Verified = false; breakpoint.Message = errorMessage; configuredBreakpoints.Add(breakpoint); continue; } psCommand.AddParameter("Action", actionScriptBlock); } } // If no PSCommand was created then there are no breakpoints to set. if (psCommand != null) { IEnumerable <Breakpoint> setBreakpoints = await _powerShellContextService.ExecuteCommandAsync <Breakpoint>(psCommand); configuredBreakpoints.AddRange( setBreakpoints.Select(CommandBreakpointDetails.Create)); } return(configuredBreakpoints); }