refactor creation of debugger process
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using Microsoft.VisualStudio.Shared.VSCodeDebugProtocol.Messages;
|
||||
using SharpIDE.Application.Features.Run;
|
||||
using SharpIDE.Application.Features.SolutionDiscovery;
|
||||
using SharpIDE.Application.Features.SolutionDiscovery.VsPersistence;
|
||||
|
||||
@@ -10,9 +11,9 @@ public class Debugger
|
||||
public required SharpIdeProjectModel Project { get; init; }
|
||||
public required int ProcessId { get; init; }
|
||||
private DebuggingService _debuggingService = new DebuggingService();
|
||||
public async Task Attach(string? debuggerExecutablePath, Dictionary<SharpIdeFile, List<Breakpoint>> breakpointsByFile, SharpIdeProjectModel project, CancellationToken cancellationToken)
|
||||
public async Task Attach(DebuggerExecutableInfo? debuggerExecutableInfo, Dictionary<SharpIdeFile, List<Breakpoint>> breakpointsByFile, SharpIdeProjectModel project, CancellationToken cancellationToken)
|
||||
{
|
||||
await _debuggingService.Attach(ProcessId, debuggerExecutablePath, breakpointsByFile, project, cancellationToken);
|
||||
await _debuggingService.Attach(ProcessId, debuggerExecutableInfo, breakpointsByFile, project, cancellationToken);
|
||||
}
|
||||
public async Task SetBreakpointsForFile(SharpIdeFile file, List<Breakpoint> breakpoints, CancellationToken cancellationToken = default) => await _debuggingService.SetBreakpointsForFile(file, breakpoints, cancellationToken);
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
using System.Diagnostics;
|
||||
using Ardalis.GuardClauses;
|
||||
using SharpIDE.Application.Features.Run;
|
||||
|
||||
namespace SharpIDE.Application.Features.Debugging;
|
||||
|
||||
public static class DebuggerProcessStreamHelper
|
||||
{
|
||||
public static (Stream Input, Stream Output, bool IsNetCoreDbg) NewDebuggerProcessStreamsForInfo(DebuggerExecutableInfo? debuggerExecutableInfoNullable)
|
||||
{
|
||||
if (debuggerExecutableInfoNullable is not {} debuggerExecutableInfo) throw new ArgumentNullException(nameof(debuggerExecutableInfoNullable), "Debugger executable info cannot be null.");
|
||||
var debuggerExecutablePath = debuggerExecutableInfo.DebuggerExecutablePath;
|
||||
Guard.Against.NullOrWhiteSpace(debuggerExecutablePath, nameof(debuggerExecutablePath), "Debugger executable path cannot be null or empty.");
|
||||
var isNetCoreDbg = Path.GetFileNameWithoutExtension(debuggerExecutablePath).Equals("netcoredbg", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
var process = new Process
|
||||
{
|
||||
StartInfo = new ProcessStartInfo
|
||||
{
|
||||
//FileName = @"C:\Users\Matthew\Downloads\netcoredbg-win64\netcoredbg\netcoredbg.exe",
|
||||
FileName = debuggerExecutablePath,
|
||||
Arguments = "--interpreter=vscode",
|
||||
RedirectStandardInput = true,
|
||||
RedirectStandardOutput = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
}
|
||||
};
|
||||
process.Start();
|
||||
return (process.StandardInput.BaseStream, process.StandardOutput.BaseStream, isNetCoreDbg);
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ using Microsoft.VisualStudio.Shared.VSCodeDebugProtocol.Messages;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using SharpIDE.Application.Features.Debugging.Signing;
|
||||
using SharpIDE.Application.Features.Events;
|
||||
using SharpIDE.Application.Features.Run;
|
||||
using SharpIDE.Application.Features.SolutionDiscovery;
|
||||
using SharpIDE.Application.Features.SolutionDiscovery.VsPersistence;
|
||||
|
||||
@@ -16,33 +17,14 @@ namespace SharpIDE.Application.Features.Debugging;
|
||||
public class DebuggingService
|
||||
{
|
||||
private DebugProtocolHost _debugProtocolHost = null!;
|
||||
public async Task Attach(int debuggeeProcessId, string? debuggerExecutablePath, Dictionary<SharpIdeFile, List<Breakpoint>> breakpointsByFile, SharpIdeProjectModel project, CancellationToken cancellationToken = default)
|
||||
public async Task Attach(int debuggeeProcessId, DebuggerExecutableInfo? debuggerExecutableInfo, Dictionary<SharpIdeFile, List<Breakpoint>> breakpointsByFile, SharpIdeProjectModel project, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Guard.Against.NegativeOrZero(debuggeeProcessId, nameof(debuggeeProcessId), "Process ID must be a positive integer.");
|
||||
await Task.CompletedTask.ConfigureAwait(ConfigureAwaitOptions.ForceYielding);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(debuggerExecutablePath))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(debuggerExecutablePath), "Debugger executable path cannot be null or empty.");
|
||||
}
|
||||
var isNetCoreDbg = Path.GetFileNameWithoutExtension(debuggerExecutablePath).Equals("netcoredbg", StringComparison.OrdinalIgnoreCase);
|
||||
var (inputStream, outputStream, isNetCoreDbg) = DebuggerProcessStreamHelper.NewDebuggerProcessStreamsForInfo(debuggerExecutableInfo);
|
||||
|
||||
var process = new Process
|
||||
{
|
||||
StartInfo = new ProcessStartInfo
|
||||
{
|
||||
//FileName = @"C:\Users\Matthew\Downloads\netcoredbg-win64\netcoredbg\netcoredbg.exe",
|
||||
FileName = debuggerExecutablePath,
|
||||
Arguments = "--interpreter=vscode",
|
||||
RedirectStandardInput = true,
|
||||
RedirectStandardOutput = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
}
|
||||
};
|
||||
process.Start();
|
||||
|
||||
var debugProtocolHost = new DebugProtocolHost(process.StandardInput.BaseStream, process.StandardOutput.BaseStream, false);
|
||||
var debugProtocolHost = new DebugProtocolHost(inputStream, outputStream, false);
|
||||
var initializedEventTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
_debugProtocolHost = debugProtocolHost;
|
||||
debugProtocolHost.LogMessage += (sender, args) =>
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace SharpIDE.Application.Features.Run;
|
||||
|
||||
public readonly record struct DebuggerExecutableInfo
|
||||
{
|
||||
public required bool UseInMemorySharpDbg { get; init; }
|
||||
public required string? DebuggerExecutablePath { get; init; }
|
||||
}
|
||||
@@ -22,7 +22,7 @@ public partial class RunService(ILogger<RunService> logger, RoslynAnalysis rosly
|
||||
private readonly ILogger<RunService> _logger = logger;
|
||||
private readonly RoslynAnalysis _roslynAnalysis = roslynAnalysis;
|
||||
|
||||
public async Task RunProject(SharpIdeProjectModel project, bool isDebug = false, string? debuggerExecutablePath = null)
|
||||
public async Task RunProject(SharpIdeProjectModel project, bool isDebug = false, DebuggerExecutableInfo? debuggerExecutableInfo = null)
|
||||
{
|
||||
Guard.Against.Null(project, nameof(project));
|
||||
Guard.Against.NullOrWhiteSpace(project.FilePath, nameof(project.FilePath), "Project file path cannot be null or empty.");
|
||||
@@ -93,7 +93,7 @@ public partial class RunService(ILogger<RunService> logger, RoslynAnalysis rosly
|
||||
// Attach debugger (which internally uses a DiagnosticClient to resume startup)
|
||||
var debugger = new Debugger { Project = project, ProcessId = process.ProcessId };
|
||||
_debugger = debugger;
|
||||
await debugger.Attach(debuggerExecutablePath, Breakpoints.ToDictionary(), project, project.RunningCancellationTokenSource.Token).ConfigureAwait(false);
|
||||
await debugger.Attach(debuggerExecutableInfo, Breakpoints.ToDictionary(), project, project.RunningCancellationTokenSource.Token).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
project.Running = true;
|
||||
|
||||
@@ -62,6 +62,11 @@ public partial class RunMenuItem : HBoxContainer
|
||||
private async void OnDebugButtonPressed()
|
||||
{
|
||||
GodotGlobalEvents.Instance.BottomPanelTabExternallySelected.InvokeParallelFireAndForget(BottomPanelType.Debug);
|
||||
await _runService.RunProject(Project, true, Singletons.AppState.IdeSettings.DebuggerExecutablePath).ConfigureAwait(false);
|
||||
var debuggerExecutableInfo = new DebuggerExecutableInfo
|
||||
{
|
||||
UseInMemorySharpDbg = false,
|
||||
DebuggerExecutablePath = Singletons.AppState.IdeSettings.DebuggerExecutablePath
|
||||
};
|
||||
await _runService.RunProject(Project, true, debuggerExecutableInfo).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user