ringbuffer and statistics
This commit is contained in:
15
VisionBuilder.UI.Console/ModuleExtensions.cs
Normal file
15
VisionBuilder.UI.Console/ModuleExtensions.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using Ninject.Extensions.ChildKernel;
|
||||
using VisionBuilder.UI.Common;
|
||||
using VisionBuilder.UI.Console;
|
||||
|
||||
namespace VisionBuilder.UI.Statistics;
|
||||
|
||||
public static class ModuleExtensions
|
||||
{
|
||||
public static IChildKernel UseConsole(this IChildKernel self)
|
||||
{
|
||||
self.Bind<VisionBuilderConsoleSettings, ISettings>().ToConstant(new VisionBuilderConsoleSettings());
|
||||
self.RegisterModule<VisionBuilderConsole>();
|
||||
return self;
|
||||
}
|
||||
}
|
||||
17
VisionBuilder.UI.Console/VisionBuilder.UI.Console.csproj
Normal file
17
VisionBuilder.UI.Console/VisionBuilder.UI.Console.csproj
Normal file
@@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\VisionBuilder.UI.Common\VisionBuilder.UI.Common.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
36
VisionBuilder.UI.Console/VisionBuilderConsole.cs
Normal file
36
VisionBuilder.UI.Console/VisionBuilderConsole.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using Ninject;
|
||||
using Serilog;
|
||||
using VisionBuilder.UI.Common;
|
||||
|
||||
namespace VisionBuilder.UI.Console
|
||||
{
|
||||
public class VisionBuilderConsole: IVisionBuilderModule
|
||||
{
|
||||
private readonly VisionBuilderConsoleSettings _settings;
|
||||
|
||||
public VisionBuilderConsole(VisionBuilderConsoleSettings settings)
|
||||
{
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
public void InitializeModule()
|
||||
{
|
||||
if (_settings.CreateConsoleWindow)
|
||||
{
|
||||
WinConsole.Initialize();
|
||||
}
|
||||
// configure Serilog to use console
|
||||
if (_settings.UseConsole)
|
||||
{
|
||||
Serilog.Log.Logger = new Serilog.LoggerConfiguration()
|
||||
.MinimumLevel.Debug()
|
||||
.WriteTo.Console()
|
||||
.CreateLogger();
|
||||
|
||||
Log.Information("Console initialized");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
18
VisionBuilder.UI.Console/VisionBuilderConsoleSettings.cs
Normal file
18
VisionBuilder.UI.Console/VisionBuilderConsoleSettings.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using Inspectron.Settings;
|
||||
using Inspectron.Settings.Attributes;
|
||||
using Serilog;
|
||||
using VisionBuilder.UI.Common;
|
||||
|
||||
namespace VisionBuilder.UI.Console;
|
||||
|
||||
public class VisionBuilderConsoleSettings:ISettings
|
||||
{
|
||||
public bool UseConsole { get; set; } = false;
|
||||
[SettingDescription("Create a console window for non-console application")]
|
||||
public bool CreateConsoleWindow { get; set; }
|
||||
public void RegisterSettings(InspectronSettings settings)
|
||||
{
|
||||
settings.RegisterSimple(this, () => this.UseConsole, "Console", nameof(UseConsole));
|
||||
settings.RegisterSimple(this, () => this.CreateConsoleWindow, "Console", nameof(CreateConsoleWindow));
|
||||
}
|
||||
}
|
||||
118
VisionBuilder.UI.Console/WinConsole.cs
Normal file
118
VisionBuilder.UI.Console/WinConsole.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
||||
namespace VisionBuilder.UI.Console
|
||||
{
|
||||
public static class WinConsole
|
||||
{
|
||||
public static void Initialize(bool alwaysCreateNewConsole = true, bool minimizeWindow = false)
|
||||
{
|
||||
bool consoleAttached = true;
|
||||
if (alwaysCreateNewConsole
|
||||
|| (AttachConsole(ATTACH_PARRENT) == 0
|
||||
&& Marshal.GetLastWin32Error() != ERROR_ACCESS_DENIED))
|
||||
{
|
||||
consoleAttached = AllocConsole() != 0;
|
||||
}
|
||||
|
||||
if (consoleAttached)
|
||||
{
|
||||
InitializeOutStream();
|
||||
InitializeInStream();
|
||||
}
|
||||
|
||||
if (minimizeWindow)
|
||||
{
|
||||
const int SW_MINIMIZE = 6;
|
||||
var handle = GetConsoleWindow();
|
||||
ShowWindow(handle, SW_MINIMIZE);
|
||||
}
|
||||
}
|
||||
|
||||
public static void MinimizeWindow()
|
||||
{
|
||||
const int SW_MINIMIZE = 6;
|
||||
var handle = GetConsoleWindow();
|
||||
ShowWindow(handle, SW_MINIMIZE);
|
||||
}
|
||||
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
|
||||
[DllImport("kernel32.dll")]
|
||||
private static extern IntPtr GetConsoleWindow();
|
||||
private static void InitializeOutStream()
|
||||
{
|
||||
var fs = CreateFileStream("CONOUT$", GENERIC_WRITE, FILE_SHARE_WRITE, FileAccess.Write);
|
||||
if (fs != null)
|
||||
{
|
||||
var writer = new StreamWriter(fs) { AutoFlush = true };
|
||||
System.Console.SetOut(writer);
|
||||
System.Console.SetError(writer);
|
||||
}
|
||||
}
|
||||
|
||||
private static void InitializeInStream()
|
||||
{
|
||||
var fs = CreateFileStream("CONIN$", GENERIC_READ, FILE_SHARE_READ, FileAccess.Read);
|
||||
if (fs != null)
|
||||
{
|
||||
System.Console.SetIn(new StreamReader(fs));
|
||||
}
|
||||
}
|
||||
|
||||
private static FileStream CreateFileStream(string name, uint win32DesiredAccess, uint win32ShareMode,
|
||||
FileAccess dotNetFileAccess)
|
||||
{
|
||||
var file = new SafeFileHandle(CreateFileW(name, win32DesiredAccess, win32ShareMode, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero), true);
|
||||
if (!file.IsInvalid)
|
||||
{
|
||||
var fs = new FileStream(file, dotNetFileAccess);
|
||||
return fs;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
#region Win API Functions and Constants
|
||||
[DllImport("kernel32.dll",
|
||||
EntryPoint = "AllocConsole",
|
||||
SetLastError = true,
|
||||
CharSet = CharSet.Auto,
|
||||
CallingConvention = CallingConvention.StdCall)]
|
||||
private static extern int AllocConsole();
|
||||
|
||||
[DllImport("kernel32.dll",
|
||||
EntryPoint = "AttachConsole",
|
||||
SetLastError = true,
|
||||
CharSet = CharSet.Auto,
|
||||
CallingConvention = CallingConvention.StdCall)]
|
||||
private static extern UInt32 AttachConsole(UInt32 dwProcessId);
|
||||
|
||||
[DllImport("kernel32.dll",
|
||||
EntryPoint = "CreateFileW",
|
||||
SetLastError = true,
|
||||
CharSet = CharSet.Auto,
|
||||
CallingConvention = CallingConvention.StdCall)]
|
||||
private static extern IntPtr CreateFileW(
|
||||
string lpFileName,
|
||||
UInt32 dwDesiredAccess,
|
||||
UInt32 dwShareMode,
|
||||
IntPtr lpSecurityAttributes,
|
||||
UInt32 dwCreationDisposition,
|
||||
UInt32 dwFlagsAndAttributes,
|
||||
IntPtr hTemplateFile
|
||||
);
|
||||
|
||||
private const UInt32 GENERIC_WRITE = 0x40000000;
|
||||
private const UInt32 GENERIC_READ = 0x80000000;
|
||||
private const UInt32 FILE_SHARE_READ = 0x00000001;
|
||||
private const UInt32 FILE_SHARE_WRITE = 0x00000002;
|
||||
private const UInt32 OPEN_EXISTING = 0x00000003;
|
||||
private const UInt32 FILE_ATTRIBUTE_NORMAL = 0x80;
|
||||
private const UInt32 ERROR_ACCESS_DENIED = 5;
|
||||
|
||||
private const UInt32 ATTACH_PARRENT = 0xFFFFFFFF;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user