using System.Runtime.InteropServices; using ImageCatalog; using ImageCatalog_2.Services; using MaddoShared; using Microsoft.Extensions.DependencyInjection; using AutoMapper; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Console; using Microsoft.Extensions.Options; namespace ImageCatalog_2; static class Program { [DllImport("kernel32.dll", SetLastError = true)] private static extern bool AllocConsole(); [DllImport("kernel32.dll", SetLastError = true)] static extern IntPtr GetStdHandle(int nStdHandle); private const int STD_OUTPUT_HANDLE = -11; private const int STD_ERROR_HANDLE = -12; [DllImport("kernel32.dll", SetLastError = true)] static extern bool SetStdHandle(int nStdHandle, IntPtr handle); [DllImport("kernel32.dll", SetLastError = true)] static extern IntPtr GetConsoleWindow(); [DllImport("kernel32.dll", SetLastError = true)] static extern bool AttachConsole(int dwProcessId); [DllImport("kernel32.dll", SetLastError = true)] static extern IntPtr CreateFile( string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile); private const uint GENERIC_WRITE = 0x40000000; private const uint OPEN_EXISTING = 3; private static void RedirectConsoleOutput() { var stdOutHandle = CreateFile("CONOUT$", GENERIC_WRITE, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero); var safeFileHandle = new Microsoft.Win32.SafeHandles.SafeFileHandle(stdOutHandle, true); var fileStream = new FileStream(safeFileHandle, FileAccess.Write); var standardOutput = new StreamWriter(fileStream) { AutoFlush = true }; Console.SetOut(standardOutput); Console.SetError(standardOutput); } public static IServiceProvider ServiceProvider { get; private set; } [STAThread] static void Main() { Application.SetHighDpiMode(HighDpiMode.SystemAware); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); AllocConsole(); RedirectConsoleOutput(); var serviceCollection = new ServiceCollection(); ConfigureServices(serviceCollection); ServiceProvider = serviceCollection.BuildServiceProvider(); var mainForm = ServiceProvider.GetRequiredService(); //var mainViewModel = ServiceProvider.GetRequiredService(); //mainForm.Model = mainViewModel; Application.Run(mainForm); } private static void ConfigureServices(ServiceCollection services) { // Register AutoMapper (new AddAutoMapper overload — provide config and marker types) services.AddAutoMapper(cfg => { }, typeof(Program)); // Register your services here services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddSingleton(); services.AddSingleton(); // Register your forms services.AddTransient(); services.AddLogging(configure => { configure.AddCustomFormatter(); configure.AddConsole(); configure.SetMinimumLevel(LogLevel.Debug); }); } } public static class ConsoleLoggerExtensions { public static ILoggingBuilder AddCustomFormatter( this ILoggingBuilder builder) => builder.AddConsole(options => options.FormatterName = nameof(CustomLoggingFormatter)) .AddConsoleFormatter(); } public sealed class CustomLoggingFormatter : ConsoleFormatter, IDisposable { private readonly IDisposable _optionsReloadToken; private ConsoleFormatterOptions _formatterOptions; public CustomLoggingFormatter(IOptionsMonitor options) // Case insensitive : base(nameof(CustomLoggingFormatter)) => (_optionsReloadToken, _formatterOptions) = (options.OnChange(ReloadLoggerOptions), options.CurrentValue); private void ReloadLoggerOptions(ConsoleFormatterOptions options) => _formatterOptions = options; public override void Write( in LogEntry logEntry, IExternalScopeProvider scopeProvider, TextWriter textWriter) { string? message = logEntry.Formatter?.Invoke( logEntry.State, logEntry.Exception); if (message is null) { return; } textWriter.WriteLine($"{message}"); } public void Dispose() => _optionsReloadToken?.Dispose(); }