using System.Diagnostics; using AVSCartonShipmentVerifier.Configuration; using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.Hosting.Server.Features; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Options; namespace AVSCartonShipmentVerifier.Hosting; /// /// Opens the default browser once the web server has started (Windows desktop-style launch). /// internal sealed class LaunchBrowserHostedService : IHostedService { private readonly IHostApplicationLifetime _lifetime; private readonly IOptions _options; private readonly IServer _server; private readonly ILogger _logger; public LaunchBrowserHostedService( IServer server, IHostApplicationLifetime lifetime, IOptions options, ILogger logger) { _server = server; _lifetime = lifetime; _options = options; _logger = logger; } public Task StartAsync(CancellationToken cancellationToken) { var opts = _options.Value; if (!opts.LaunchBrowser) return Task.CompletedTask; _lifetime.ApplicationStarted.Register(OpenBrowser); return Task.CompletedTask; } private void OpenBrowser() { try { var url = ResolveUrl(); if (string.IsNullOrWhiteSpace(url)) { _logger.LogWarning("Could not determine URL to open in the browser."); return; } if (OperatingSystem.IsWindows()) { Process.Start(new ProcessStartInfo(url) { UseShellExecute = true }); } else if (OperatingSystem.IsMacOS()) { Process.Start("open", url); } else { Process.Start(new ProcessStartInfo("xdg-open", url) { UseShellExecute = true }); } } catch (Exception ex) { _logger.LogWarning(ex, "Failed to launch the default browser."); } } private string? ResolveUrl() { var configured = _options.Value.BrowserUrl; if (!string.IsNullOrWhiteSpace(configured)) return configured; var addresses = _server.Features.Get()?.Addresses; if (addresses is null || addresses.Count == 0) return null; return addresses.FirstOrDefault(static a => a.StartsWith("http://", StringComparison.OrdinalIgnoreCase)) ?? addresses.FirstOrDefault(static a => a.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) ?? addresses.FirstOrDefault(); } public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; }