using System.Diagnostics; using Remiss.Core.Abstractions; namespace Remiss.Core.Printing; /// /// Tyst utskrift via buntad SumatraPDF. Retry-logik eftersom spooler/skrivare /// tidvis är otillgänglig. /// public sealed class SumatraPdfPrinter : IPrinter { private readonly string _exePath; private readonly int _retries; private readonly int _retryDelayMs; public SumatraPdfPrinter(string exePath, int retries = 3, int retryDelayMs = 2000) { _exePath = exePath; _retries = Math.Max(1, retries); _retryDelayMs = Math.Max(0, retryDelayMs); } /// /// Namngiven skrivare, eller tom/null för Windows standardskrivare. /// public void Print(string pdfPath, string? printerName) { if (!File.Exists(_exePath)) throw new FileNotFoundException( $"SumatraPDF hittades inte: {_exePath}. Lägg binären i tools/ (se tools/README.md).", _exePath); Exception? last = null; for (var attempt = 1; attempt <= _retries; attempt++) { try { RunOnce(pdfPath, printerName); return; } catch (Exception ex) { last = ex; if (attempt < _retries) Thread.Sleep(_retryDelayMs); } } throw new InvalidOperationException($"Utskrift misslyckades efter {_retries} försök.", last); } private void RunOnce(string pdfPath, string? printerName) { var psi = new ProcessStartInfo { FileName = _exePath, UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = true, RedirectStandardError = true, }; if (string.IsNullOrWhiteSpace(printerName)) { psi.ArgumentList.Add("-print-to-default"); } else { psi.ArgumentList.Add("-print-to"); psi.ArgumentList.Add(printerName); } psi.ArgumentList.Add("-silent"); psi.ArgumentList.Add(pdfPath); using var proc = Process.Start(psi) ?? throw new InvalidOperationException("Kunde inte starta SumatraPDF."); if (!proc.WaitForExit(60_000)) { try { proc.Kill(entireProcessTree: true); } catch { /* ignore */ } throw new TimeoutException("SumatraPDF svarade inte inom 60 sekunder."); } if (proc.ExitCode != 0) { var err = proc.StandardError.ReadToEnd().Trim(); throw new InvalidOperationException( $"SumatraPDF avslutades med kod {proc.ExitCode}." + (err.Length > 0 ? $" {err}" : "")); } } }