using System.Diagnostics; using System.Text; namespace AVSCartonShipmentVerifier.Hosting; internal static class DesktopBrowserLauncher { internal sealed record LaunchResult(Process? TrackedProcess, bool UsedAppMode); public static LaunchResult TryLaunch(string url, bool preferAppMode, string? userDataDir) { if (preferAppMode && OperatingSystem.IsWindows()) { var profileDir = ResolveProfileDirectory(userDataDir); foreach (var (fileName, arguments) in GetAppModeCandidates(url, profileDir)) { if (!File.Exists(fileName)) { continue; } try { var process = Process.Start(new ProcessStartInfo { FileName = fileName, Arguments = arguments, UseShellExecute = false }); if (process is not null) { return new LaunchResult(process, UsedAppMode: true); } } catch { // Try next browser. } } } try { 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 }); } return new LaunchResult(null, UsedAppMode: false); } catch { return new LaunchResult(null, UsedAppMode: false); } } private static string? ResolveProfileDirectory(string? userDataDir) { if (string.IsNullOrWhiteSpace(userDataDir)) { return null; } var profileDir = userDataDir.Trim(); Directory.CreateDirectory(profileDir); return profileDir; } private static IEnumerable<(string FileName, string Arguments)> GetAppModeCandidates(string url, string? profileDir) { var builder = new StringBuilder(); builder.Append("--app=").Append(url); builder.Append(" --new-window"); if (!string.IsNullOrWhiteSpace(profileDir)) { var escapedProfile = profileDir.Replace("\"", "\\\"", StringComparison.Ordinal); builder.Append(" --user-data-dir=\"").Append(escapedProfile).Append('"'); } var appArgs = builder.ToString(); foreach (var edgePath in EdgePaths()) { yield return (edgePath, appArgs); } foreach (var chromePath in ChromePaths()) { yield return (chromePath, appArgs); } } private static IEnumerable EdgePaths() { yield return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "Microsoft", "Edge", "Application", "msedge.exe"); yield return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "Microsoft", "Edge", "Application", "msedge.exe"); } private static IEnumerable ChromePaths() { yield return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "Google", "Chrome", "Application", "chrome.exe"); yield return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "Google", "Chrome", "Application", "chrome.exe"); } }