mirror of
https://github.com/ZuneDev/ZuneUIXTools.git
synced 2026-07-27 13:11:59 -07:00
[WIP] DAP
This commit is contained in:
@@ -60,7 +60,7 @@ public class IrisDebugAdapterClient : IDebuggerClient, IRemoteDebuggerState, IDi
|
|||||||
{
|
{
|
||||||
if (ConnectionString is not null)
|
if (ConnectionString is not null)
|
||||||
{
|
{
|
||||||
ConnectionStringHelper.CreateFromString(ConnectionString, out _inputStream, out _outputStream);
|
ConnectionStringHelper.ConnectToString(ConnectionString, out _inputStream, out _outputStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
_debugAdapter = await DebugAdapterClient.From(options =>
|
_debugAdapter = await DebugAdapterClient.From(options =>
|
||||||
@@ -70,10 +70,12 @@ public class IrisDebugAdapterClient : IDebuggerClient, IRemoteDebuggerState, IDi
|
|||||||
.WithOutput(_outputStream)
|
.WithOutput(_outputStream)
|
||||||
.OnInitialize((server, _, cancellationToken) =>
|
.OnInitialize((server, _, cancellationToken) =>
|
||||||
{
|
{
|
||||||
|
var __ = server.RequestDebugAdapterInitialize(new());
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
})
|
})
|
||||||
.OnInitialized((_, _, response, _) =>
|
.OnInitialized((_, _, response, _) =>
|
||||||
{
|
{
|
||||||
|
Connected?.Invoke(this, EventArgs.Empty);
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
})
|
})
|
||||||
.OnContinued(args =>
|
.OnContinued(args =>
|
||||||
@@ -141,7 +143,16 @@ public class IrisDebugAdapterClient : IDebuggerClient, IRemoteDebuggerState, IDi
|
|||||||
|
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
StartAsync().RunSynchronously();
|
System.Threading.Thread clientThread = new(() =>
|
||||||
Connected?.Invoke(this, EventArgs.Empty);
|
{
|
||||||
|
_ = StartAsync();
|
||||||
|
//.ContinueWith(t =>
|
||||||
|
//{
|
||||||
|
// if (t.Exception is not null)
|
||||||
|
// System.Diagnostics.Debug.WriteLine(t.Exception);
|
||||||
|
//});
|
||||||
|
});
|
||||||
|
clientThread.IsBackground = true;
|
||||||
|
clientThread.Start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,84 +0,0 @@
|
|||||||
using Microsoft.Iris.Debug;
|
|
||||||
using Microsoft.Iris.Debug.Data;
|
|
||||||
using OmniSharp.Extensions.DebugAdapter.Protocol.Events;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Microsoft.Iris.DebugAdapter.Server;
|
|
||||||
|
|
||||||
public class DapDebuggerServer : IDebuggerServer, IRemoteDebuggerState
|
|
||||||
{
|
|
||||||
private readonly IrisDebugServerOptions _debugAdapterOptions;
|
|
||||||
private IrisDebugAdapterServer? _debugAdapter;
|
|
||||||
private InterpreterCommand _debuggerCommand;
|
|
||||||
|
|
||||||
public InterpreterCommand DebuggerCommand
|
|
||||||
{
|
|
||||||
get => _debuggerCommand;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_debuggerCommand = value;
|
|
||||||
|
|
||||||
if (_debugAdapter?.Server is null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (value is InterpreterCommand.Continue)
|
|
||||||
{
|
|
||||||
_debugAdapter.Server.SendContinued(new()
|
|
||||||
{
|
|
||||||
ThreadId = Environment.CurrentManagedThreadId,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else if (value is InterpreterCommand.Break)
|
|
||||||
{
|
|
||||||
_debugAdapter.Server.SendStopped(new()
|
|
||||||
{
|
|
||||||
Reason = new("unknown"),
|
|
||||||
ThreadId = Environment.CurrentManagedThreadId,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string ConnectionString { get; }
|
|
||||||
|
|
||||||
public event Action<IDebuggerState, object>? Connected;
|
|
||||||
|
|
||||||
public DapDebuggerServer(string connectionString, IrisDebugServerOptions options)
|
|
||||||
{
|
|
||||||
ConnectionString = connectionString;
|
|
||||||
|
|
||||||
_debugAdapterOptions = options;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void LogDispatcher(string message)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void LogInterpreterDecode(object context, InterpreterInstruction instruction)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void LogInterpreterExecute(object context, InterpreterEntry entry)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public MarkupLineNumberEntry[] OnLineNumberTableRequested(string uri)
|
|
||||||
{
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Start()
|
|
||||||
{
|
|
||||||
ConnectionStringHelper.CreateFromString(ConnectionString, out var input, out var output);
|
|
||||||
|
|
||||||
_debugAdapter = new(input, output, _debugAdapterOptions);
|
|
||||||
_debugAdapter.StartAsync().RunSynchronously();
|
|
||||||
|
|
||||||
Connected?.Invoke(this, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void WaitForContinue()
|
|
||||||
{
|
|
||||||
while (DebuggerCommand is InterpreterCommand.Break) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,42 +1,73 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Iris.Debug;
|
using Microsoft.Iris.Debug;
|
||||||
|
using Microsoft.Iris.Debug.Data;
|
||||||
using Microsoft.Iris.DebugAdapter.Server.Handlers;
|
using Microsoft.Iris.DebugAdapter.Server.Handlers;
|
||||||
|
using OmniSharp.Extensions.DebugAdapter.Protocol.Events;
|
||||||
using OmniSharp.Extensions.DebugAdapter.Server;
|
using OmniSharp.Extensions.DebugAdapter.Server;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.Iris.DebugAdapter.Server;
|
namespace Microsoft.Iris.DebugAdapter.Server;
|
||||||
|
|
||||||
public class IrisDebugAdapterServer : IDisposable
|
public class IrisDebugAdapterServer : IDebuggerServer, IRemoteDebuggerState, IDisposable
|
||||||
{
|
{
|
||||||
private readonly Stream _inputStream;
|
|
||||||
private readonly Stream _outputStream;
|
|
||||||
private readonly TaskCompletionSource<bool> _serverStopped;
|
private readonly TaskCompletionSource<bool> _serverStopped;
|
||||||
|
private Stream _inputStream, _outputStream;
|
||||||
|
private InterpreterCommand _debuggerCommand;
|
||||||
|
|
||||||
public IrisDebugAdapterServer(
|
public IrisDebugAdapterServer(IrisDebugServerOptions options)
|
||||||
Stream inputStream,
|
|
||||||
Stream outputStream,
|
|
||||||
IrisDebugServerOptions options)
|
|
||||||
{
|
{
|
||||||
_inputStream = inputStream;
|
|
||||||
_outputStream = outputStream;
|
|
||||||
_serverStopped = new();
|
_serverStopped = new();
|
||||||
|
|
||||||
Options = options;
|
Options = options;
|
||||||
|
ConnectionString = options.ConnectionString;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal IrisDebugServerOptions Options { get; }
|
internal IrisDebugServerOptions Options { get; }
|
||||||
|
|
||||||
internal DebugAdapterServer? Server { get; private set; }
|
internal DebugAdapterServer? Server { get; private set; }
|
||||||
|
|
||||||
|
public InterpreterCommand DebuggerCommand
|
||||||
|
{
|
||||||
|
get => _debuggerCommand;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_debuggerCommand = value;
|
||||||
|
|
||||||
|
if (Server is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (value is InterpreterCommand.Continue)
|
||||||
|
{
|
||||||
|
Server.SendContinued(new()
|
||||||
|
{
|
||||||
|
ThreadId = Environment.CurrentManagedThreadId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (value is InterpreterCommand.Break)
|
||||||
|
{
|
||||||
|
Server.SendStopped(new()
|
||||||
|
{
|
||||||
|
Reason = new("unknown"),
|
||||||
|
ThreadId = Environment.CurrentManagedThreadId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ConnectionString { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Start the debug server listening.
|
/// Start the debug server listening.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A task that completes when the server is ready.</returns>
|
/// <returns>A task that completes when the server is ready.</returns>
|
||||||
public async Task StartAsync()
|
public async Task StartAsync()
|
||||||
{
|
{
|
||||||
Server = await DebugAdapterServer.From(options =>
|
ConnectionStringHelper.CreateFromString(ConnectionString, out _inputStream, out _outputStream);
|
||||||
|
|
||||||
|
Server = DebugAdapterServer.Create(options =>
|
||||||
{
|
{
|
||||||
// We need to let the PowerShell Context Service know that we are in a debug session
|
// We need to let the PowerShell Context Service know that we are in a debug session
|
||||||
// so that it doesn't send the powerShell/startDebugger message.
|
// so that it doesn't send the powerShell/startDebugger message.
|
||||||
@@ -49,7 +80,7 @@ public class IrisDebugAdapterServer : IDisposable
|
|||||||
.WithServices(serviceCollection =>
|
.WithServices(serviceCollection =>
|
||||||
serviceCollection
|
serviceCollection
|
||||||
.AddOptions()
|
.AddOptions()
|
||||||
.AddIrisDebugServices(Options.SymbolDir, Options.SourceDir)
|
.AddIrisDebugServices(this, Options.SymbolDir, Options.SourceDir)
|
||||||
)
|
)
|
||||||
// TODO: Consider replacing all WithHandler with AddSingleton
|
// TODO: Consider replacing all WithHandler with AddSingleton
|
||||||
//.WithHandler<AttachHandler>()
|
//.WithHandler<AttachHandler>()
|
||||||
@@ -98,7 +129,11 @@ public class IrisDebugAdapterServer : IDisposable
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
})
|
})
|
||||||
;
|
;
|
||||||
}).ConfigureAwait(false);
|
});
|
||||||
|
|
||||||
|
await Server.Initialize(default).ConfigureAwait(false);
|
||||||
|
|
||||||
|
Connected?.Invoke(this, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
@@ -116,6 +151,44 @@ public class IrisDebugAdapterServer : IDisposable
|
|||||||
public async Task WaitForShutdownAsync() => await _serverStopped.Task.ConfigureAwait(false);
|
public async Task WaitForShutdownAsync() => await _serverStopped.Task.ConfigureAwait(false);
|
||||||
|
|
||||||
public event EventHandler? SessionEnded;
|
public event EventHandler? SessionEnded;
|
||||||
|
public event Action<IDebuggerState, object> Connected;
|
||||||
|
|
||||||
internal void OnSessionEnded() => SessionEnded?.Invoke(this, EventArgs.Empty);
|
internal void OnSessionEnded() => SessionEnded?.Invoke(this, EventArgs.Empty);
|
||||||
|
|
||||||
|
public MarkupLineNumberEntry[] OnLineNumberTableRequested(string uri)
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LogInterpreterDecode(object context, InterpreterInstruction instruction)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LogInterpreterExecute(object context, InterpreterEntry entry)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LogDispatcher(string message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WaitForContinue()
|
||||||
|
{
|
||||||
|
while (DebuggerCommand is InterpreterCommand.Break) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
Thread serverThread = new(() =>
|
||||||
|
{
|
||||||
|
_ = StartAsync();
|
||||||
|
//.ContinueWith(t =>
|
||||||
|
//{
|
||||||
|
// if (t.Exception is not null)
|
||||||
|
// System.Diagnostics.Debug.WriteLine(t.Exception);
|
||||||
|
//});
|
||||||
|
});
|
||||||
|
serverThread.IsBackground = true;
|
||||||
|
serverThread.Start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
public class IrisDebugServerOptions
|
public class IrisDebugServerOptions
|
||||||
{
|
{
|
||||||
public string SymbolDir { get; set; }
|
public required string ConnectionString { get; set; }
|
||||||
|
|
||||||
|
public required string SymbolDir { get; set; }
|
||||||
|
|
||||||
public string? SourceDir { get; set; }
|
public string? SourceDir { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Iris.Debug;
|
||||||
|
|
||||||
namespace Microsoft.Iris.DebugAdapter.Server;
|
namespace Microsoft.Iris.DebugAdapter.Server;
|
||||||
|
|
||||||
internal static class ServiceCollectionExtensions
|
internal static class ServiceCollectionExtensions
|
||||||
{
|
{
|
||||||
public static IServiceCollection AddIrisDebugServices(this IServiceCollection services, string symbolDir, string? sourceDir)
|
public static IServiceCollection AddIrisDebugServices(this IServiceCollection services, IDebuggerServer debuggerServer, string symbolDir, string? sourceDir)
|
||||||
{
|
{
|
||||||
DebugSymbolResolver symbolResolver = new(symbolDir, sourceDir);
|
DebugSymbolResolver symbolResolver = new(symbolDir, sourceDir);
|
||||||
|
|
||||||
return services
|
return services
|
||||||
.AddSingleton(symbolResolver);
|
.AddSingleton(symbolResolver)
|
||||||
|
.AddSingleton(debuggerServer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,20 @@ public static class ConnectionStringHelper
|
|||||||
? connectionString
|
? connectionString
|
||||||
: NamedPipeUtils.GenerateValidNamedPipeName();
|
: NamedPipeUtils.GenerateValidNamedPipeName();
|
||||||
|
|
||||||
input = NamedPipeUtils.CreateNamedPipe(pipeName, PipeDirection.InOut);
|
var pipe = NamedPipeUtils.CreateNamedPipe(pipeName, PipeDirection.InOut);
|
||||||
output = input;
|
pipe.WaitForConnection();
|
||||||
|
|
||||||
|
output = input = pipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ConnectToString(string connectionString, out Stream input, out Stream output)
|
||||||
|
{
|
||||||
|
if (!connectionString.StartsWith(PIPE_PREFIX))
|
||||||
|
throw new System.NotSupportedException();
|
||||||
|
|
||||||
|
var pipe = new NamedPipeClientStream(connectionString);
|
||||||
|
pipe.Connect();
|
||||||
|
|
||||||
|
output = input = pipe;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,5 +147,5 @@ public static class NamedPipeUtils
|
|||||||
#endif
|
#endif
|
||||||
return $@"\\.\pipe\{pipeName}";
|
return $@"\\.\pipe\{pipeName}";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#pragma warning restore IDE0022
|
#pragma warning restore IDE0022
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ using System.Globalization;
|
|||||||
|
|
||||||
namespace UIXC.Commands;
|
namespace UIXC.Commands;
|
||||||
|
|
||||||
public class DebugCommand : Command<DebugCommand.Settings>
|
public class DebugCommand : AsyncCommand<DebugCommand.Settings>
|
||||||
{
|
{
|
||||||
private bool isRunning = true;
|
private readonly TaskCompletionSource _exit = new();
|
||||||
|
|
||||||
public override int Execute(CommandContext context, Settings settings)
|
public override async Task<int> ExecuteAsync(CommandContext context, Settings settings)
|
||||||
{
|
{
|
||||||
if (settings.ConnectionString is null)
|
if (settings.ConnectionString is null)
|
||||||
{
|
{
|
||||||
@@ -58,7 +58,7 @@ public class DebugCommand : Command<DebugCommand.Settings>
|
|||||||
|
|
||||||
c.Start();
|
c.Start();
|
||||||
|
|
||||||
while (isRunning) ;
|
await _exit.Task.ConfigureAwait(false);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -148,7 +148,7 @@ public class DebugCommand : Command<DebugCommand.Settings>
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case "EXIT" or "QUIT":
|
case "EXIT" or "QUIT":
|
||||||
isRunning = false;
|
_exit.SetResult();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"UIXC": {
|
"UIXC": {
|
||||||
"commandName": "Project",
|
"commandName": "Project",
|
||||||
|
|
||||||
"commandLineArgs": "debug --symbols E:\\Repos\\ZuneDev\\ZuneUIXTools\\test\\syms --sources E:\\Repos\\ZuneDev\\ZuneUIXTools\\test",
|
"commandLineArgs": "debug -u \\\\.\\pipe\\IrisUIX_OpenZune_WPFHost --symbols E:\\Repos\\ZuneDev\\ZuneUIXTools\\test\\syms --sources E:\\Repos\\ZuneDev\\ZuneUIXTools\\test",
|
||||||
//"commandLineArgs": "decompile E:\\Documents\\REProj\\Zune\\Resources\\ZuneShellResources48\\NOWPLAYINGMUSICBACKGROUND.UIX -l xml -A ZuneShell.dll -A UIXControls.dll -A ZuneDBApi.dll -o E:\\Repos\\ZuneDev\\ZuneUIXTools\\test --symbols E:\\Repos\\ZuneDev\\ZuneUIXTools\\test\\syms",
|
//"commandLineArgs": "decompile E:\\Documents\\REProj\\Zune\\Resources\\ZuneShellResources48\\NOWPLAYINGMUSICBACKGROUND.UIX -l xml -A ZuneShell.dll -A UIXControls.dll -A ZuneDBApi.dll -o E:\\Repos\\ZuneDev\\ZuneUIXTools\\test --symbols E:\\Repos\\ZuneDev\\ZuneUIXTools\\test\\syms",
|
||||||
|
|
||||||
//"commandLineArgs": "decompile E:\\Documents\\REProj\\Zune\\Resources\\ZuneMarketplaceResources48\\MarketplaceData.schema.xml -l xml -A ZuneShell.dll -A UIXControls.dll -A ZuneDBApi.dll -o E:\\Repos\\ZuneDev\\ZuneUIXTools\\test",
|
//"commandLineArgs": "decompile E:\\Documents\\REProj\\Zune\\Resources\\ZuneMarketplaceResources48\\MarketplaceData.schema.xml -l xml -A ZuneShell.dll -A UIXControls.dll -A ZuneDBApi.dll -o E:\\Repos\\ZuneDev\\ZuneUIXTools\\test",
|
||||||
|
|||||||
Reference in New Issue
Block a user