}
if (useHelpBuilder)
{
- var helpBuilder = new HelpBuilder(_console, maxWidth: Console.WindowWidth);
+ var helpBuilder = new HelpBuilder(_console, maxWidth: LocalConsole.ToConsoleService(_console).WindowWidth);
helpBuilder.Write(command);
}
}
/// </summary>
class LocalConsole : IConsole
{
- public static IServiceProvider ToServices(IConsole console) => ((LocalConsole)console).Services;
+ public static IServiceProvider ToServices(IConsole console) => ((LocalConsole)console)._services;
- public readonly IServiceProvider Services;
+ public static IConsoleService ToConsoleService(IConsole console) => ((LocalConsole)console)._console;
+ private readonly IServiceProvider _services;
private readonly IConsoleService _console;
public LocalConsole(IServiceProvider services)
{
- Services = services;
+ _services = services;
_console = services.GetService<IConsoleService>();
Debug.Assert(_console != null);
Out = new StandardStreamWriter((text) => _console.Write(text));
/// Cancellation token for current command
/// </summary>
CancellationToken CancellationToken { get; set; }
+
+ /// <summary>
+ /// Screen or window width or 0.
+ /// </summary>
+ int WindowWidth { get; }
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
CancellationToken IConsoleService.CancellationToken { get; set; }
+ int IConsoleService.WindowWidth
+ {
+ get
+ {
+ try
+ {
+ return Console.WindowWidth;
+ }
+ catch (Exception ex) when (ex is ArgumentOutOfRangeException || ex is IOException)
+ {
+ return int.MaxValue;
+ }
+ }
+ }
+
#endregion
}
}
using Microsoft.Diagnostics.DebugServices;
using Microsoft.Diagnostics.Runtime.Interop;
+using System;
using System.Threading;
namespace SOS.Extensions
public CancellationToken CancellationToken { get; set; }
+ int IConsoleService.WindowWidth => _debuggerServices.GetOutputWidth();
+
#endregion
}
}
}
}
+ public int GetOutputWidth() => (int)VTable.GetOutputWidth(Self);
+
[StructLayout(LayoutKind.Sequential)]
private readonly unsafe struct IDebuggerServicesVTable
{
public readonly delegate* unmanaged[Stdcall]<IntPtr, byte*, uint, out uint, HResult> GetSymbolPath;
public readonly delegate* unmanaged[Stdcall]<IntPtr, int, ulong, byte*, int, out uint, out ulong, HResult> GetSymbolByOffset;
public readonly delegate* unmanaged[Stdcall]<IntPtr, int, byte*, out ulong, HResult> GetOffsetBySymbol;
+ public readonly delegate* unmanaged[Stdcall]<IntPtr, uint> GetOutputWidth;
}
}
}
return m_symbols->GetOffsetByName(symbolName.c_str(), offset);
}
+ULONG
+DbgEngServices::GetOutputWidth()
+{
+ // m_client->GetOutputWidth() always returns 80 as the width under windbg, windbgx and cdb so just return the max.
+ return INT_MAX;
+}
+
//----------------------------------------------------------------------------
// IRemoteMemoryService
//----------------------------------------------------------------------------
PCSTR name,
PULONG64 offset);
+ ULONG STDMETHODCALLTYPE GetOutputWidth();
+
//----------------------------------------------------------------------------
// IRemoteMemoryService
//----------------------------------------------------------------------------
ULONG moduleIndex,
PCSTR name,
PULONG64 offset) = 0;
+
+ virtual ULONG STDMETHODCALLTYPE GetOutputWidth() = 0;
};
#ifdef __cplusplus
return hr;
}
+ULONG
+LLDBServices::GetOutputWidth()
+{
+ return m_debugger.GetTerminalWidth();
+}
+
//----------------------------------------------------------------------------
// Helper functions
//----------------------------------------------------------------------------
PCSTR name,
PULONG64 offset);
+ ULONG STDMETHODCALLTYPE GetOutputWidth();
+
//----------------------------------------------------------------------------
// LLDBServices (internal)
//----------------------------------------------------------------------------