diff --git a/Transversal/Services/PuppeteerPdfGeneratorService.cs b/Transversal/Services/PuppeteerPdfGeneratorService.cs index c2b71ee..d339427 100644 --- a/Transversal/Services/PuppeteerPdfGeneratorService.cs +++ b/Transversal/Services/PuppeteerPdfGeneratorService.cs @@ -1,6 +1,7 @@ using System.Runtime.InteropServices; -using PuppeteerSharp.Media; +using Microsoft.Extensions.Configuration; using PuppeteerSharp; +using PuppeteerSharp.Media; using Transversal.Interfaces; using Transversal.Models; @@ -9,30 +10,49 @@ namespace Transversal.Services public class PuppeteerPdfGeneratorService : IPdfGeneratorService, IAsyncDisposable { private readonly Browser _browser; - public PuppeteerPdfGeneratorService() + + public PuppeteerPdfGeneratorService(IConfiguration config) { string? executablePath = RuntimeInformation.IsOSPlatform(OSPlatform.Linux) - ? "/usr/bin/chromium" // Docker/Linux - : null; // Windows local → que use Chrome instalado + ? "/usr/bin/chromium" // Docker/Linux (NO TOCAR) + : ResolveWindowsBrowserPath(config); // Windows local + + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + if (string.IsNullOrWhiteSpace(executablePath) || !File.Exists(executablePath)) + throw new InvalidOperationException( + $"No se encontró un navegador. Verifique Puppeteer:ExecutablePath. Path evaluado: '{executablePath}'."); + } _browser = Puppeteer.LaunchAsync(new LaunchOptions { Headless = true, ExecutablePath = executablePath, - Args = new[] { "--no-sandbox", "--disable-setuid-sandbox" } + Args = RuntimeInformation.IsOSPlatform(OSPlatform.Linux) + ? new[] { "--no-sandbox", "--disable-setuid-sandbox" } + : Array.Empty() }).GetAwaiter().GetResult(); } - - //public PuppeteerPdfGeneratorService() - //{ - // // NO USAR BrowserFetcher NUNCA en entorno productivo Docker - // _browser = Puppeteer.LaunchAsync(new LaunchOptions - // { - // Headless = true, - // ExecutablePath = "/usr/bin/chromium", // ruta de chromium en la imagen docker - // Args = new[] { "--no-sandbox", "--disable-setuid-sandbox" } - // }).GetAwaiter().GetResult(); - //} + + private static string? ResolveWindowsBrowserPath(IConfiguration config) + { + // 1) appsettings: "Puppeteer:ExecutablePath" + var configured = config["Puppeteer:ExecutablePath"]; + if (!string.IsNullOrWhiteSpace(configured)) + return configured; + + // 2) fallbacks típicos (Chrome/Edge) + var candidates = new[] + { + @"C:\Program Files\Google\Chrome\Application\chrome.exe", + @"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe", + @"C:\Program Files\Microsoft\Edge\Application\msedge.exe", + @"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe", + }; + + return candidates.FirstOrDefault(File.Exists); + } + public async Task GeneratePdfFromHtmlAsync(string htmlContent, PdfGenerationOptions options = null) { options ??= new PdfGenerationOptions(); @@ -55,6 +75,7 @@ namespace Transversal.Services return await page.PdfDataAsync(pdfOptions); } + public async ValueTask DisposeAsync() { if (_browser != null) diff --git a/phronCare.API/appsettings.json b/phronCare.API/appsettings.json index fa2867e..be3e164 100644 --- a/phronCare.API/appsettings.json +++ b/phronCare.API/appsettings.json @@ -29,5 +29,8 @@ "ValidIssuer": "http://phroncare-bio-d7e9h0-api.saludlab.com.ar:9000", "ValidAudience": "http://phroncare-bio-d7e9h0-api.saludlab.com.ar:9000", "Secret": "8f96cb2c6eac839349f783369690eb368411359afbaa8de6c6c2b30927d2f9fe6222fc6911348eb88c235cf393cb808ce80b5498de31e37090ba06482eca93ecbf31b8e1d97209d9ae4ba01d4e285af64bc9758b70decfb385bf96e74f2b6c61d00cc80b8fbfd999d5902e2ca58f2f7a3ee574280d776ba61a5b1cbd0180689577b02fc8ec26297a501c4409f8529b338814f629a2b8fcba21dc0e15f408969dbc4b7f14b43a19b46a41bc288ddf207c16d50b11e1039ffd131c312ddf10df6fd65d8bc3f898a14294cd32366269bee53f84e94f45de80e8b5ddaa1a3b4aa288a7cb35eacaf9c2005d65237210c14843af022177be2f6e93764c3b4030b59f24" + }, + "Puppeteer": { + "ExecutablePath": "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" } } \ No newline at end of file