mirror of
https://github.com/ZuneDev/ZuneUIXTools.git
synced 2026-07-27 13:11:59 -07:00
First pass at debug adapter support
This commit is contained in:
@@ -0,0 +1,147 @@
|
|||||||
|
using Microsoft.Iris.Debug;
|
||||||
|
using Microsoft.Iris.Debug.Data;
|
||||||
|
using OmniSharp.Extensions.DebugAdapter.Client;
|
||||||
|
using OmniSharp.Extensions.DebugAdapter.Protocol.Events;
|
||||||
|
using OmniSharp.Extensions.DebugAdapter.Protocol.Models;
|
||||||
|
using OmniSharp.Extensions.DebugAdapter.Protocol.Requests;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
using IrisBreakpoint = Microsoft.Iris.Debug.Data.Breakpoint;
|
||||||
|
|
||||||
|
namespace Microsoft.Iris.DebugAdapter.Client;
|
||||||
|
|
||||||
|
public class IrisDebugAdapterClient : IDebuggerClient, IRemoteDebuggerState, IDisposable
|
||||||
|
{
|
||||||
|
private Stream _inputStream;
|
||||||
|
private Stream _outputStream;
|
||||||
|
private DebugAdapterClient? _debugAdapter;
|
||||||
|
private InterpreterCommand _debuggerCommand;
|
||||||
|
|
||||||
|
public InterpreterCommand DebuggerCommand
|
||||||
|
{
|
||||||
|
get => _debuggerCommand;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_debuggerCommand = value;
|
||||||
|
|
||||||
|
_ = value switch
|
||||||
|
{
|
||||||
|
InterpreterCommand.Break => _debugAdapter.RequestPause(new()),
|
||||||
|
InterpreterCommand.Continue => _debugAdapter.RequestContinue(new()),
|
||||||
|
InterpreterCommand.Step => _debugAdapter.RequestNext(new()),
|
||||||
|
_ => Task.CompletedTask
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ConnectionString { get; }
|
||||||
|
|
||||||
|
public event Action<InterpreterCommand> InterpreterStateChanged;
|
||||||
|
public event EventHandler<InterpreterInstruction> InterpreterDecode;
|
||||||
|
public event EventHandler<InterpreterEntry> InterpreterExecute;
|
||||||
|
public event Action<string> DispatcherStep;
|
||||||
|
public event Action<IDebuggerState, object> Connected;
|
||||||
|
|
||||||
|
public IrisDebugAdapterClient(Stream inputStream, Stream outputStream)
|
||||||
|
{
|
||||||
|
_inputStream = inputStream;
|
||||||
|
_outputStream = outputStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IrisDebugAdapterClient(string connectionString)
|
||||||
|
{
|
||||||
|
ConnectionString = connectionString;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task StartAsync()
|
||||||
|
{
|
||||||
|
if (ConnectionString is not null)
|
||||||
|
{
|
||||||
|
ConnectionStringHelper.CreateFromString(ConnectionString, out _inputStream, out _outputStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
_debugAdapter = await DebugAdapterClient.From(options =>
|
||||||
|
{
|
||||||
|
options
|
||||||
|
.WithInput(_inputStream)
|
||||||
|
.WithOutput(_outputStream)
|
||||||
|
.OnInitialize((server, _, cancellationToken) =>
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
})
|
||||||
|
.OnInitialized((_, _, response, _) =>
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
})
|
||||||
|
.OnContinued(args =>
|
||||||
|
{
|
||||||
|
_debuggerCommand = InterpreterCommand.Continue;
|
||||||
|
InterpreterStateChanged?.Invoke(_debuggerCommand);
|
||||||
|
})
|
||||||
|
.OnStopped(args =>
|
||||||
|
{
|
||||||
|
_debuggerCommand = InterpreterCommand.Break;
|
||||||
|
InterpreterStateChanged?.Invoke(_debuggerCommand);
|
||||||
|
})
|
||||||
|
;
|
||||||
|
}).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_debugAdapter?.Dispose();
|
||||||
|
_inputStream.Dispose();
|
||||||
|
_outputStream.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateBreakpoint(IrisBreakpoint irisBreakpoint)
|
||||||
|
{
|
||||||
|
if (irisBreakpoint.Line > 0)
|
||||||
|
{
|
||||||
|
List<SourceBreakpoint> sourceBreakpoints = [
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Line = irisBreakpoint.Line,
|
||||||
|
Column = irisBreakpoint.Column > 0
|
||||||
|
? irisBreakpoint.Column
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
_ = _debugAdapter.SetBreakpoints(new()
|
||||||
|
{
|
||||||
|
Breakpoints = sourceBreakpoints
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (irisBreakpoint.Offset != uint.MaxValue)
|
||||||
|
{
|
||||||
|
// Instruction breakpoint
|
||||||
|
List<InstructionBreakpoint> instructionBreakpoints = [
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
InstructionReference = $"{irisBreakpoint.Uri}@0x{irisBreakpoint.Offset:X}",
|
||||||
|
//Offset = irisBreakpoint.Offset,
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
_ = _debugAdapter.SetInstructionBreakpoints(new()
|
||||||
|
{
|
||||||
|
Breakpoints = instructionBreakpoints
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RequestLineNumberTable(string uri, Action<MarkupLineNumberEntry[]> callback)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
StartAsync().RunSynchronously();
|
||||||
|
Connected?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFrameworks>net461;net6.0;net6.0-windows10.0.22000</TargetFrameworks>
|
||||||
|
<LangVersion>12</LangVersion>
|
||||||
|
<RootNamespace>Microsoft.Iris.DebugAdapter.Client</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="OmniSharp.Extensions.DebugAdapter.Client" Version="0.19.9" />
|
||||||
|
<ProjectReference Include="..\..\libs\MicrosoftIris\UIX\UIX.csproj" />
|
||||||
|
<ProjectReference Include="..\UIX.DebugAdapter.Shared\UIX.DebugAdapter.Shared.csproj" />
|
||||||
|
|
||||||
|
<PackageReference Include="PolySharp" Version="1.15.0">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
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) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
using Microsoft.Iris.Debug.Symbols;
|
||||||
|
using OmniSharp.Extensions.DebugAdapter.Protocol.Requests;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
using DapBreakpoint = OmniSharp.Extensions.DebugAdapter.Protocol.Models.Breakpoint;
|
||||||
|
using IrisBreakpoint = Microsoft.Iris.Debug.Data.Breakpoint;
|
||||||
|
|
||||||
|
namespace Microsoft.Iris.DebugAdapter.Server.Handlers;
|
||||||
|
|
||||||
|
internal class BreakpointHandler(DebugSymbolResolver symbolResolver)
|
||||||
|
: ISetInstructionBreakpointsHandler, ISetBreakpointsHandler
|
||||||
|
{
|
||||||
|
public Task<SetInstructionBreakpointsResponse> Handle(SetInstructionBreakpointsArguments request, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
List<DapBreakpoint> dapBreakpoints = [];
|
||||||
|
|
||||||
|
foreach (var requestedBreakpoint in request.Breakpoints)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SetInstructionBreakpointsResponse response = new()
|
||||||
|
{
|
||||||
|
Breakpoints = dapBreakpoints
|
||||||
|
};
|
||||||
|
return Task.FromResult(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<SetBreakpointsResponse> Handle(SetBreakpointsArguments request, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
// Debug symbols are required for setting source (line:column) breakpoints
|
||||||
|
var fsym = symbolResolver?.GetForFile(request.Source.Path);
|
||||||
|
if (fsym is null)
|
||||||
|
return Task.FromResult(new SetBreakpointsResponse());
|
||||||
|
|
||||||
|
List<DapBreakpoint> dapBreakpoints = [];
|
||||||
|
|
||||||
|
// TODO: Clear existing breakpoints for file
|
||||||
|
|
||||||
|
foreach (var requestedBreakpoint in request.Breakpoints ?? [])
|
||||||
|
{
|
||||||
|
SourceMap.Entry location;
|
||||||
|
|
||||||
|
if (requestedBreakpoint.Column is not null)
|
||||||
|
{
|
||||||
|
SourcePosition position = new(requestedBreakpoint.Line, requestedBreakpoint.Column.Value);
|
||||||
|
location = fsym.SourceMap.GetLocationFromPosition(position);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Get first location that contains this line
|
||||||
|
location = fsym.SourceMap.GetLocationFromLine(requestedBreakpoint.Line);
|
||||||
|
}
|
||||||
|
|
||||||
|
IrisBreakpoint irisBreakpoint = new(fsym.CompiledFileName, location.Offset);
|
||||||
|
Application.DebugSettings.Breakpoints.Add(irisBreakpoint);
|
||||||
|
|
||||||
|
DapBreakpoint dapBreakpoint = new()
|
||||||
|
{
|
||||||
|
Line = location.Span.Start.Line,
|
||||||
|
Column = location.Span.Start.Column,
|
||||||
|
EndLine = location.Span.End.Line,
|
||||||
|
EndColumn = location.Span.End.Column,
|
||||||
|
};
|
||||||
|
dapBreakpoints.Add(dapBreakpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetBreakpointsResponse response = new()
|
||||||
|
{
|
||||||
|
Breakpoints = dapBreakpoints
|
||||||
|
};
|
||||||
|
return Task.FromResult(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Iris.Debug;
|
||||||
|
using OmniSharp.Extensions.DebugAdapter.Protocol.Requests;
|
||||||
|
|
||||||
|
namespace Microsoft.Iris.DebugAdapter.Server.Handlers;
|
||||||
|
|
||||||
|
internal class ContinueHandler : ContinueHandlerBase
|
||||||
|
{
|
||||||
|
private readonly IDebuggerServer _debugService;
|
||||||
|
|
||||||
|
public ContinueHandler(IDebuggerServer debugService) => _debugService = debugService;
|
||||||
|
|
||||||
|
public override Task<ContinueResponse> Handle(ContinueArguments request, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
_debugService.DebuggerCommand = Debug.Data.InterpreterCommand.Continue;
|
||||||
|
return Task.FromResult(new ContinueResponse());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class NextHandler : NextHandlerBase
|
||||||
|
{
|
||||||
|
private readonly IDebuggerServer _debugService;
|
||||||
|
|
||||||
|
public NextHandler(IDebuggerServer debugService) => _debugService = debugService;
|
||||||
|
|
||||||
|
public override Task<NextResponse> Handle(NextArguments request, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
_debugService.DebuggerCommand = Debug.Data.InterpreterCommand.Step;
|
||||||
|
return Task.FromResult(new NextResponse());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class PauseHandler : PauseHandlerBase
|
||||||
|
{
|
||||||
|
private readonly IDebuggerServer _debugService;
|
||||||
|
|
||||||
|
public PauseHandler(IDebuggerServer debugService) => _debugService = debugService;
|
||||||
|
|
||||||
|
public override Task<PauseResponse> Handle(PauseArguments request, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
_debugService.DebuggerCommand = Debug.Data.InterpreterCommand.Break;
|
||||||
|
return Task.FromResult(new PauseResponse());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class StepInHandler : StepInHandlerBase
|
||||||
|
{
|
||||||
|
private readonly IDebuggerServer _debugService;
|
||||||
|
|
||||||
|
public StepInHandler(IDebuggerServer debugService) => _debugService = debugService;
|
||||||
|
|
||||||
|
public override Task<StepInResponse> Handle(StepInArguments request, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
_debugService.DebuggerCommand = Debug.Data.InterpreterCommand.Step;
|
||||||
|
return Task.FromResult(new StepInResponse());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Iris.Debug;
|
||||||
|
using Microsoft.Iris.DebugAdapter.Server.Handlers;
|
||||||
|
using OmniSharp.Extensions.DebugAdapter.Server;
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Microsoft.Iris.DebugAdapter.Server;
|
||||||
|
|
||||||
|
public class IrisDebugAdapterServer : IDisposable
|
||||||
|
{
|
||||||
|
private readonly Stream _inputStream;
|
||||||
|
private readonly Stream _outputStream;
|
||||||
|
private readonly TaskCompletionSource<bool> _serverStopped;
|
||||||
|
|
||||||
|
public IrisDebugAdapterServer(
|
||||||
|
Stream inputStream,
|
||||||
|
Stream outputStream,
|
||||||
|
IrisDebugServerOptions options)
|
||||||
|
{
|
||||||
|
_inputStream = inputStream;
|
||||||
|
_outputStream = outputStream;
|
||||||
|
_serverStopped = new();
|
||||||
|
|
||||||
|
Options = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal IrisDebugServerOptions Options { get; }
|
||||||
|
|
||||||
|
internal DebugAdapterServer? Server { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Start the debug server listening.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A task that completes when the server is ready.</returns>
|
||||||
|
public async Task StartAsync()
|
||||||
|
{
|
||||||
|
Server = await DebugAdapterServer.From(options =>
|
||||||
|
{
|
||||||
|
// 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.
|
||||||
|
//_psesHost = ServiceProvider.GetService<PsesInternalHost>();
|
||||||
|
//_psesHost.DebugContext.IsDebugServerActive = true;
|
||||||
|
|
||||||
|
options
|
||||||
|
.WithInput(_inputStream)
|
||||||
|
.WithOutput(_outputStream)
|
||||||
|
.WithServices(serviceCollection =>
|
||||||
|
serviceCollection
|
||||||
|
.AddOptions()
|
||||||
|
.AddIrisDebugServices(Options.SymbolDir, Options.SourceDir)
|
||||||
|
)
|
||||||
|
// TODO: Consider replacing all WithHandler with AddSingleton
|
||||||
|
//.WithHandler<AttachHandler>()
|
||||||
|
//.WithHandler<DisconnectHandler>()
|
||||||
|
.WithHandler<BreakpointHandler>()
|
||||||
|
//.WithHandler<ConfigurationDoneHandler>()
|
||||||
|
//.WithHandler<ThreadsHandler>()
|
||||||
|
//.WithHandler<StackTraceHandler>()
|
||||||
|
//.WithHandler<ScopesHandler>()
|
||||||
|
//.WithHandler<VariablesHandler>()
|
||||||
|
.WithHandler<ContinueHandler>()
|
||||||
|
.WithHandler<NextHandler>()
|
||||||
|
.WithHandler<PauseHandler>()
|
||||||
|
.WithHandler<StepInHandler>()
|
||||||
|
//.WithHandler<StepOutHandler>()
|
||||||
|
//.WithHandler<SourceHandler>()
|
||||||
|
//.WithHandler<SetVariableHandler>()
|
||||||
|
//.WithHandler<DebugEvaluateHandler>()
|
||||||
|
// The OnInitialize delegate gets run when we first receive the _Initialize_ request:
|
||||||
|
// https://microsoft.github.io/debug-adapter-protocol/specification#Requests_Initialize
|
||||||
|
.OnInitialize(async (server, _, cancellationToken) =>
|
||||||
|
{
|
||||||
|
// Start the host if not already started, and enable debug mode (required
|
||||||
|
// for remote debugging).
|
||||||
|
//
|
||||||
|
// TODO: We might need to fill in HostStartOptions here.
|
||||||
|
//_startedPses = !await _psesHost.TryStartAsync(new HostStartOptions(), cancellationToken).ConfigureAwait(false);
|
||||||
|
//_psesHost.DebugContext.EnableDebugMode();
|
||||||
|
|
||||||
|
// Clear any existing breakpoints before proceeding.
|
||||||
|
//BreakpointService breakpointService = server.GetService<BreakpointService>();
|
||||||
|
//await breakpointService.RemoveAllBreakpointsAsync().ConfigureAwait(false);
|
||||||
|
})
|
||||||
|
// The OnInitialized delegate gets run right before the server responds to the _Initialize_ request:
|
||||||
|
// https://microsoft.github.io/debug-adapter-protocol/specification#Requests_Initialize
|
||||||
|
.OnInitialized((_, _, response, _) =>
|
||||||
|
{
|
||||||
|
//response.SupportsConditionalBreakpoints = true;
|
||||||
|
//response.SupportsConfigurationDoneRequest = true;
|
||||||
|
//response.SupportsFunctionBreakpoints = true;
|
||||||
|
//response.SupportsHitConditionalBreakpoints = true;
|
||||||
|
//response.SupportsLogPoints = true;
|
||||||
|
//response.SupportsSetVariable = true;
|
||||||
|
//response.SupportsDelayedStackTraceLoading = true;
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
})
|
||||||
|
;
|
||||||
|
}).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
// Note that the lifetime of the DebugContext is longer than the debug server;
|
||||||
|
// It represents the debugger on the PowerShell process we're in,
|
||||||
|
// while a new debug server is spun up for every debugging session
|
||||||
|
//_psesHost.DebugContext.IsDebugServerActive = false;
|
||||||
|
Server?.Dispose();
|
||||||
|
_inputStream.Dispose();
|
||||||
|
_outputStream.Dispose();
|
||||||
|
_serverStopped.SetResult(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task WaitForShutdownAsync() => await _serverStopped.Task.ConfigureAwait(false);
|
||||||
|
|
||||||
|
public event EventHandler? SessionEnded;
|
||||||
|
|
||||||
|
internal void OnSessionEnded() => SessionEnded?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Microsoft.Iris.DebugAdapter;
|
||||||
|
|
||||||
|
public class IrisDebugServerOptions
|
||||||
|
{
|
||||||
|
public string SymbolDir { get; set; }
|
||||||
|
|
||||||
|
public string? SourceDir { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Microsoft.Iris.DebugAdapter.Server;
|
||||||
|
|
||||||
|
internal static class ServiceCollectionExtensions
|
||||||
|
{
|
||||||
|
public static IServiceCollection AddIrisDebugServices(this IServiceCollection services, string symbolDir, string? sourceDir)
|
||||||
|
{
|
||||||
|
DebugSymbolResolver symbolResolver = new(symbolDir, sourceDir);
|
||||||
|
|
||||||
|
return services
|
||||||
|
.AddSingleton(symbolResolver);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFrameworks>net461;net6.0;net6.0-windows10.0.22000</TargetFrameworks>
|
||||||
|
<LangVersion>12</LangVersion>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<RootNamespace>Microsoft.Iris.DebugAdapter.Server</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="OmniSharp.Extensions.DebugAdapter.Server" Version="0.19.9" />
|
||||||
|
<ProjectReference Include="..\..\libs\MicrosoftIris\UIX\UIX.csproj" />
|
||||||
|
<ProjectReference Include="..\UIX.DebugAdapter.Shared\UIX.DebugAdapter.Shared.csproj" />
|
||||||
|
|
||||||
|
<PackageReference Include="PolySharp" Version="1.15.0">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using System.IO;
|
||||||
|
using System.IO.Pipes;
|
||||||
|
|
||||||
|
namespace Microsoft.Iris.DebugAdapter;
|
||||||
|
|
||||||
|
public static class ConnectionStringHelper
|
||||||
|
{
|
||||||
|
private const string PIPE_PREFIX = @"\\.\pipe\";
|
||||||
|
|
||||||
|
public static void CreateFromString(string connectionString, out Stream input, out Stream output)
|
||||||
|
{
|
||||||
|
// TODO: Support other transports
|
||||||
|
var pipeName = connectionString.StartsWith(PIPE_PREFIX)
|
||||||
|
? connectionString
|
||||||
|
: NamedPipeUtils.GenerateValidNamedPipeName();
|
||||||
|
|
||||||
|
input = NamedPipeUtils.CreateNamedPipe(pipeName, PipeDirection.InOut);
|
||||||
|
output = input;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
using Microsoft.Iris.Debug.Symbols;
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Microsoft.Iris.DebugAdapter;
|
||||||
|
|
||||||
|
public class DebugSymbolResolver(string symbolDir, string? sourceDir)
|
||||||
|
{
|
||||||
|
private readonly DirectoryInfo _symbolDir = new(symbolDir);
|
||||||
|
private readonly DirectoryInfo? _sourceDir = sourceDir is not null ? new(sourceDir) : null;
|
||||||
|
|
||||||
|
public ApplicationDebugSymbols? GetForApplication(string? application)
|
||||||
|
{
|
||||||
|
if (application is null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var fileName = $"{application}.asym.json";
|
||||||
|
var asymFile = FindFile(fileName, _symbolDir);
|
||||||
|
|
||||||
|
if (asymFile is null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
using var stream = asymFile.OpenRead();
|
||||||
|
using var reader = new StreamReader(stream);
|
||||||
|
return DebugSymbolsJsonParser.ParseForApplication(reader.ReadToEnd());
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileDebugSymbols? GetForFile(string? file, string? application = null)
|
||||||
|
{
|
||||||
|
if (file is null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var fileName = $"{file}.fsym.json";
|
||||||
|
var fsymFile = FindFile(fileName, _symbolDir);
|
||||||
|
|
||||||
|
if (fsymFile is not null)
|
||||||
|
{
|
||||||
|
using var stream = fsymFile.OpenRead();
|
||||||
|
using var reader = new StreamReader(stream);
|
||||||
|
var fsym = DebugSymbolsJsonParser.ParseForFile(reader.ReadToEnd());
|
||||||
|
|
||||||
|
var sourceFile = FindFile(file, _sourceDir);
|
||||||
|
if (sourceFile is not null)
|
||||||
|
{
|
||||||
|
using var sourceStream = sourceFile.OpenRead();
|
||||||
|
using var sourceReader = new StreamReader(sourceStream);
|
||||||
|
fsym.SetSourceCode(sourceReader.ReadToEnd());
|
||||||
|
}
|
||||||
|
|
||||||
|
return fsym;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (application is null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var asym = GetForApplication(application);
|
||||||
|
if (asym is null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return asym.GetForFile(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static FileInfo? FindFile(string fileName, DirectoryInfo? dir)
|
||||||
|
{
|
||||||
|
return dir?
|
||||||
|
.EnumerateFiles()
|
||||||
|
.FirstOrDefault(f => AreEquivalentFileNames(f.Name, fileName));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool AreEquivalentFileNames(string fileName1, string fileName2)
|
||||||
|
{
|
||||||
|
// NOTE: Assumes Windows. Should be trivial to support other filesystems later.
|
||||||
|
return fileName1.Equals(fileName2, StringComparison.InvariantCultureIgnoreCase);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,151 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.IO.Pipes;
|
||||||
|
|
||||||
|
|
||||||
|
#if !NET
|
||||||
|
using System.Security.Principal;
|
||||||
|
using System.Security.AccessControl;
|
||||||
|
#else
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Microsoft.Iris.DebugAdapter;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Utility class for handling named pipe creation in .NET Core and .NET Framework.
|
||||||
|
/// </summary>
|
||||||
|
public static class NamedPipeUtils
|
||||||
|
{
|
||||||
|
#if !NET
|
||||||
|
// .NET Framework requires the buffer size to be specified
|
||||||
|
private const int PipeBufferSize = 1024;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public static NamedPipeServerStream CreateNamedPipe(
|
||||||
|
string pipeName,
|
||||||
|
PipeDirection pipeDirection)
|
||||||
|
{
|
||||||
|
#if NET
|
||||||
|
return new NamedPipeServerStream(
|
||||||
|
pipeName: pipeName,
|
||||||
|
direction: pipeDirection,
|
||||||
|
maxNumberOfServerInstances: 1,
|
||||||
|
transmissionMode: PipeTransmissionMode.Byte,
|
||||||
|
options: PipeOptions.CurrentUserOnly | PipeOptions.Asynchronous);
|
||||||
|
#else
|
||||||
|
|
||||||
|
// In .NET Framework, we must manually ACL the named pipes we create
|
||||||
|
|
||||||
|
PipeSecurity pipeSecurity = new();
|
||||||
|
|
||||||
|
WindowsIdentity identity = WindowsIdentity.GetCurrent();
|
||||||
|
WindowsPrincipal principal = new(identity);
|
||||||
|
|
||||||
|
if (principal.IsInRole(WindowsBuiltInRole.Administrator))
|
||||||
|
{
|
||||||
|
// Allow the Administrators group full access to the pipe.
|
||||||
|
pipeSecurity.AddAccessRule(
|
||||||
|
new PipeAccessRule(
|
||||||
|
new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, domainSid: null).Translate(typeof(NTAccount)),
|
||||||
|
PipeAccessRights.FullControl, AccessControlType.Allow));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Allow the current user read/write access to the pipe.
|
||||||
|
pipeSecurity.AddAccessRule(new PipeAccessRule(
|
||||||
|
WindowsIdentity.GetCurrent().User,
|
||||||
|
PipeAccessRights.ReadWrite, AccessControlType.Allow));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new NamedPipeServerStream(
|
||||||
|
pipeName,
|
||||||
|
pipeDirection,
|
||||||
|
maxNumberOfServerInstances: 1,
|
||||||
|
PipeTransmissionMode.Byte,
|
||||||
|
PipeOptions.Asynchronous,
|
||||||
|
inBufferSize: PipeBufferSize,
|
||||||
|
outBufferSize: PipeBufferSize,
|
||||||
|
pipeSecurity);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generate a named pipe name known to not already be in use.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="prefixes">Prefix variants of the pipename to test, if any.</param>
|
||||||
|
/// <returns>A named pipe name or name suffix that is safe to you.</returns>
|
||||||
|
public static string GenerateValidNamedPipeName(IReadOnlyCollection<string>? prefixes = null)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
string pipeName = $"IrisUIX_{Path.GetRandomFileName()}";
|
||||||
|
|
||||||
|
// In the simple prefix-less case, just test the pipe name
|
||||||
|
if (prefixes == null)
|
||||||
|
{
|
||||||
|
if (!IsPipeNameValid(pipeName))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pipeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have prefixes, test that all prefix/pipename combinations are valid
|
||||||
|
bool allPipeNamesValid = true;
|
||||||
|
foreach (string prefix in prefixes)
|
||||||
|
{
|
||||||
|
string prefixedPipeName = $"IrisUIX_{prefix}_{pipeName}";
|
||||||
|
if (!IsPipeNameValid(prefixedPipeName))
|
||||||
|
{
|
||||||
|
allPipeNamesValid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allPipeNamesValid)
|
||||||
|
{
|
||||||
|
return pipeName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IOException("Unable to create named pipe; no available names");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Validate that a named pipe file name is a legitimate named pipe file name and is not already in use.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pipeName">The named pipe name to validate. This should be a simple name rather than a path.</param>
|
||||||
|
/// <returns>True if the named pipe name is valid, false otherwise.</returns>
|
||||||
|
public static bool IsPipeNameValid(string pipeName)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(pipeName))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !File.Exists(GetNamedPipePath(pipeName));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the path of a named pipe given its name.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pipeName">The simple name of the named pipe.</param>
|
||||||
|
/// <returns>The full path of the named pipe.</returns>
|
||||||
|
#pragma warning disable IDE0022
|
||||||
|
public static string GetNamedPipePath(string pipeName)
|
||||||
|
{
|
||||||
|
#if NET
|
||||||
|
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||||
|
{
|
||||||
|
return Path.Combine(Path.GetTempPath(), $"CoreFxPipe_{pipeName}");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return $@"\\.\pipe\{pipeName}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#pragma warning restore IDE0022
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFrameworks>net461;net6.0;net6.0-windows10.0.22000</TargetFrameworks>
|
||||||
|
<LangVersion>12</LangVersion>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<RootNamespace>Microsoft.Iris.DebugAdapter</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\libs\MicrosoftIris\UIX\UIX.csproj" />
|
||||||
|
|
||||||
|
<PackageReference Include="PolySharp" Version="1.15.0">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
using Microsoft.Iris.Debug;
|
using Microsoft.Iris.Debug;
|
||||||
using Microsoft.Iris.Debug.Symbols;
|
using Microsoft.Iris.Debug.Symbols;
|
||||||
using Microsoft.Iris.Debug.SystemNet;
|
using Microsoft.Iris.Debug.SystemNet;
|
||||||
|
using Microsoft.Iris.DebugAdapter.Client;
|
||||||
using Spectre.Console;
|
using Spectre.Console;
|
||||||
using Spectre.Console.Cli;
|
using Spectre.Console.Cli;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
@@ -14,12 +15,30 @@ public class DebugCommand : Command<DebugCommand.Settings>
|
|||||||
|
|
||||||
public override int Execute(CommandContext context, Settings settings)
|
public override int Execute(CommandContext context, Settings settings)
|
||||||
{
|
{
|
||||||
if (settings.ServerUri is null)
|
if (settings.ConnectionString is null)
|
||||||
{
|
{
|
||||||
AnsiConsole.MarkupLine("[red]Missing argument: must specify a debug server to connect to.[/]");
|
AnsiConsole.MarkupLine("[red]Missing argument, a connection string must be specified.[/]");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IDebuggerClient c;
|
||||||
|
|
||||||
|
if (Uri.TryCreate(settings.ConnectionString, UriKind.Absolute, out var connectionUri))
|
||||||
|
{
|
||||||
|
if (connectionUri.Scheme == "tcp")
|
||||||
|
{
|
||||||
|
c = new NetDebuggerClient(connectionUri);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c = new IrisDebugAdapterClient(settings.ConnectionString);
|
||||||
|
}
|
||||||
|
|
||||||
DebugSymbolResolver? symbolResolver = null;
|
DebugSymbolResolver? symbolResolver = null;
|
||||||
|
|
||||||
if (settings.SymbolDir is not null)
|
if (settings.SymbolDir is not null)
|
||||||
@@ -28,10 +47,9 @@ public class DebugCommand : Command<DebugCommand.Settings>
|
|||||||
symbolResolver = new(settings.SymbolDir, settings.SourceDir);
|
symbolResolver = new(settings.SymbolDir, settings.SourceDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
AnsiConsole.MarkupLineInterpolated($"Connecting to '{settings.ServerUri}'...");
|
AnsiConsole.MarkupLineInterpolated($"Connecting to '{settings.ConnectionString}'...");
|
||||||
|
|
||||||
var c = new NetDebuggerClient(settings.ServerUri);
|
((IRemoteDebuggerState)c).Connected += (s, e) =>
|
||||||
c.Connected += (s, e) =>
|
|
||||||
{
|
{
|
||||||
AnsiConsole.MarkupLine("[green]Connected[/]");
|
AnsiConsole.MarkupLine("[green]Connected[/]");
|
||||||
Thread consoleThread = new(() => DebugConsole(c, symbolResolver));
|
Thread consoleThread = new(() => DebugConsole(c, symbolResolver));
|
||||||
@@ -117,11 +135,19 @@ public class DebugCommand : Command<DebugCommand.Settings>
|
|||||||
client.DebuggerCommand = Microsoft.Iris.Debug.Data.InterpreterCommand.Continue;
|
client.DebuggerCommand = Microsoft.Iris.Debug.Data.InterpreterCommand.Continue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "STEP" or "S":
|
||||||
|
client.DebuggerCommand = Microsoft.Iris.Debug.Data.InterpreterCommand.Step;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "ENABLE":
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case "CLEAR":
|
case "CLEAR":
|
||||||
// Not implemented yet, should clear all breakpoints
|
// Not implemented yet, should clear all breakpoints
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "EXIT":
|
case "EXIT" or "QUIT":
|
||||||
isRunning = false;
|
isRunning = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -142,8 +168,8 @@ public class DebugCommand : Command<DebugCommand.Settings>
|
|||||||
[CommandOption("-d|--decompile")]
|
[CommandOption("-d|--decompile")]
|
||||||
public bool Decompile { get; init; }
|
public bool Decompile { get; init; }
|
||||||
|
|
||||||
[Description("The URI of the debug server to connect to.")]
|
[Description("The string used to connect to the debug server.")]
|
||||||
[CommandOption("-u|--server <serverUri>")]
|
[CommandOption("-u|--server <serverUri>")]
|
||||||
public Uri ServerUri { get; init; } = DebugRemoting.DEFAULT_TCP_URI;
|
public string ConnectionString { get; init; } = DebugRemoting.DEFAULT_TCP_URI.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
"UIXC": {
|
"UIXC": {
|
||||||
"commandName": "Project",
|
"commandName": "Project",
|
||||||
|
|
||||||
//"commandLineArgs": "debug --symbols E:\\Repos\\ZuneDev\\ZuneUIXTools\\test\\syms --sources E:\\Repos\\ZuneDev\\ZuneUIXTools\\test",
|
"commandLineArgs": "debug --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",
|
||||||
//"commandLineArgs": "decompile E:\\Documents\\REProj\\Zune\\Resources\\ZuneShellResources48\\DeviceLandElements.uix -l xml -A ZuneShell.dll -A UIXControls.dll -A ZuneDBApi.dll -o E:\\Repos\\ZuneDev\\ZuneUIXTools\\test",
|
//"commandLineArgs": "decompile E:\\Documents\\REProj\\Zune\\Resources\\ZuneShellResources48\\DeviceLandElements.uix -l xml -A ZuneShell.dll -A UIXControls.dll -A ZuneDBApi.dll -o E:\\Repos\\ZuneDev\\ZuneUIXTools\\test",
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
<PackageReference Include="OwlCore" Version="0.6.1" />
|
<PackageReference Include="OwlCore" Version="0.6.1" />
|
||||||
<PackageReference Include="Spectre.Console" Version="0.49.1" />
|
<PackageReference Include="Spectre.Console" Version="0.49.1" />
|
||||||
<PackageReference Include="Spectre.Console.Cli" Version="0.49.1" />
|
<PackageReference Include="Spectre.Console.Cli" Version="0.49.1" />
|
||||||
|
<ProjectReference Include="..\DebugAdapter\UIX.DebugAdapter.Client\UIX.DebugAdapter.Client.csproj" />
|
||||||
<ProjectReference Include="..\libs\MicrosoftIris\UIX\UIX.csproj" />
|
<ProjectReference Include="..\libs\MicrosoftIris\UIX\UIX.csproj" />
|
||||||
<ProjectReference Include="..\libs\UIX.Asm\UIX.Asm.csproj" />
|
<ProjectReference Include="..\libs\UIX.Asm\UIX.Asm.csproj" />
|
||||||
<ProjectReference Include="..\libs\UIX.DecompXml\UIX.DecompXml.csproj" />
|
<ProjectReference Include="..\libs\UIX.DecompXml\UIX.DecompXml.csproj" />
|
||||||
|
|||||||
@@ -17,6 +17,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UIXC", "UIXC\UIXC.csproj",
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UIX.DecompXml", "libs\UIX.DecompXml\UIX.DecompXml.csproj", "{3AE2DF12-C52B-48DB-9120-BCA32BB04FB2}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UIX.DecompXml", "libs\UIX.DecompXml\UIX.DecompXml.csproj", "{3AE2DF12-C52B-48DB-9120-BCA32BB04FB2}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UIX.DebugAdapter.Server", "DebugAdapter\UIX.DebugAdapter.Server\UIX.DebugAdapter.Server.csproj", "{C588C2B9-83F9-4DB8-AE82-BD9FDF2E9308}"
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DebugAdapter", "DebugAdapter", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UIX.DebugAdapter.Shared", "DebugAdapter\UIX.DebugAdapter.Shared\UIX.DebugAdapter.Shared.csproj", "{B93521C9-4570-41FC-BA15-09C34F2DFACE}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UIX.DebugAdapter.Client", "DebugAdapter\UIX.DebugAdapter.Client\UIX.DebugAdapter.Client.csproj", "{7AF18BEB-5E48-4D28-8BAB-1FC7B7AFC8D4}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -99,6 +107,42 @@ Global
|
|||||||
{3AE2DF12-C52B-48DB-9120-BCA32BB04FB2}.Release|x64.Build.0 = Release|Any CPU
|
{3AE2DF12-C52B-48DB-9120-BCA32BB04FB2}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{3AE2DF12-C52B-48DB-9120-BCA32BB04FB2}.Release|x86.ActiveCfg = Release|Any CPU
|
{3AE2DF12-C52B-48DB-9120-BCA32BB04FB2}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{3AE2DF12-C52B-48DB-9120-BCA32BB04FB2}.Release|x86.Build.0 = Release|Any CPU
|
{3AE2DF12-C52B-48DB-9120-BCA32BB04FB2}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{C588C2B9-83F9-4DB8-AE82-BD9FDF2E9308}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{C588C2B9-83F9-4DB8-AE82-BD9FDF2E9308}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{C588C2B9-83F9-4DB8-AE82-BD9FDF2E9308}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{C588C2B9-83F9-4DB8-AE82-BD9FDF2E9308}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{C588C2B9-83F9-4DB8-AE82-BD9FDF2E9308}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{C588C2B9-83F9-4DB8-AE82-BD9FDF2E9308}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{C588C2B9-83F9-4DB8-AE82-BD9FDF2E9308}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{C588C2B9-83F9-4DB8-AE82-BD9FDF2E9308}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{C588C2B9-83F9-4DB8-AE82-BD9FDF2E9308}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{C588C2B9-83F9-4DB8-AE82-BD9FDF2E9308}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{C588C2B9-83F9-4DB8-AE82-BD9FDF2E9308}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{C588C2B9-83F9-4DB8-AE82-BD9FDF2E9308}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{B93521C9-4570-41FC-BA15-09C34F2DFACE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{B93521C9-4570-41FC-BA15-09C34F2DFACE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{B93521C9-4570-41FC-BA15-09C34F2DFACE}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{B93521C9-4570-41FC-BA15-09C34F2DFACE}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{B93521C9-4570-41FC-BA15-09C34F2DFACE}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{B93521C9-4570-41FC-BA15-09C34F2DFACE}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{B93521C9-4570-41FC-BA15-09C34F2DFACE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{B93521C9-4570-41FC-BA15-09C34F2DFACE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{B93521C9-4570-41FC-BA15-09C34F2DFACE}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{B93521C9-4570-41FC-BA15-09C34F2DFACE}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{B93521C9-4570-41FC-BA15-09C34F2DFACE}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{B93521C9-4570-41FC-BA15-09C34F2DFACE}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{7AF18BEB-5E48-4D28-8BAB-1FC7B7AFC8D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{7AF18BEB-5E48-4D28-8BAB-1FC7B7AFC8D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{7AF18BEB-5E48-4D28-8BAB-1FC7B7AFC8D4}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{7AF18BEB-5E48-4D28-8BAB-1FC7B7AFC8D4}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{7AF18BEB-5E48-4D28-8BAB-1FC7B7AFC8D4}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{7AF18BEB-5E48-4D28-8BAB-1FC7B7AFC8D4}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{7AF18BEB-5E48-4D28-8BAB-1FC7B7AFC8D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{7AF18BEB-5E48-4D28-8BAB-1FC7B7AFC8D4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{7AF18BEB-5E48-4D28-8BAB-1FC7B7AFC8D4}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{7AF18BEB-5E48-4D28-8BAB-1FC7B7AFC8D4}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{7AF18BEB-5E48-4D28-8BAB-1FC7B7AFC8D4}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{7AF18BEB-5E48-4D28-8BAB-1FC7B7AFC8D4}.Release|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@@ -109,6 +153,9 @@ Global
|
|||||||
{D311AFFC-CA27-4349-8B01-D5CF0E5FC2B6} = {470F14DD-0489-4BE5-BB4B-421EDB4021AC}
|
{D311AFFC-CA27-4349-8B01-D5CF0E5FC2B6} = {470F14DD-0489-4BE5-BB4B-421EDB4021AC}
|
||||||
{C401799F-64DA-41E2-BC37-BE3C304FAE19} = {470F14DD-0489-4BE5-BB4B-421EDB4021AC}
|
{C401799F-64DA-41E2-BC37-BE3C304FAE19} = {470F14DD-0489-4BE5-BB4B-421EDB4021AC}
|
||||||
{3AE2DF12-C52B-48DB-9120-BCA32BB04FB2} = {470F14DD-0489-4BE5-BB4B-421EDB4021AC}
|
{3AE2DF12-C52B-48DB-9120-BCA32BB04FB2} = {470F14DD-0489-4BE5-BB4B-421EDB4021AC}
|
||||||
|
{C588C2B9-83F9-4DB8-AE82-BD9FDF2E9308} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
|
||||||
|
{B93521C9-4570-41FC-BA15-09C34F2DFACE} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
|
||||||
|
{7AF18BEB-5E48-4D28-8BAB-1FC7B7AFC8D4} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {4FFAF324-5FC4-4AAF-A0D7-BAA0D81C2B4C}
|
SolutionGuid = {4FFAF324-5FC4-4AAF-A0D7-BAA0D81C2B4C}
|
||||||
|
|||||||
+1
-1
Submodule libs/MicrosoftIris updated: 453a8e8b29...1ab545d4e2
Reference in New Issue
Block a user