Sicos1977 / ChromiumHtmlToPdf

Convert HTML to PDF with a Chromium based browser

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Running ChromeHtmltoPDF in Windows Container

Shashankkt opened this issue · comments

Can it run in Windows Container? If yes, can you share the dockerfile set to run it in windows container?

I get this error when I deploy my code to windows container -

An unhandled exception was thrown by the application.
2023-04-04 18:31:40 ChromeHtmlToPdfLib.Exceptions.ChromeException: Chrome exited unexpectedly, 0xC0000135
2023-04-04 18:31:40
2023-04-04 18:31:40 at ChromeHtmlToPdfLib.Converter.StartChromeHeadless()
2023-04-04 18:31:40 at ChromeHtmlToPdfLib.Converter.Convert(OutputFormat outputFormat, Object input, Stream outputStream, PageSettings pageSe2023-04-04 18:31:40 eout, ILogger logger)

Code:

var output = new MemoryStream();
var converter = new Converter();
converter.AddChromeArgument("--no-sandbox");
Console.WriteLine("Converter");
converter.ConvertToPdf(html, output, new ChromeHtmlToPdfLib.Settings.PageSettings()); --------- fails at this line
Console.WriteLine("Converted");

In docker I am simply copying chrome.exe-

FROM FROM mcr.microsoft.com/dotnet/aspnet:7.0
WORKDIR /app
COPY --from=publish /app/publish .
COPY chrome.exe /app/
ENTRYPOINT ["dotnet", "SampleDockerForTuesPechkin.dll"]

commented

Most of the times an error like this --> Chrome exited unexpectedly, 0xC0000135 has to do with rights. Try setting the user profile folder to a location where you are sure you have right through the object constructor

        /// <summary>
        ///     Creates this object and sets it's needed properties
        /// </summary>
        /// <param name="chromeExeFileName">When set then this has to be the full path to the chrome executable.
        ///     When not set then then the converter tries to find Chrome.exe by first looking in the path
        ///     where this library exists. After that it tries to find it by looking into the registry</param>
        /// <param name="userProfile">
        ///     If set then this directory will be used to store a user profile.
        ///     Leave blank or set to <c>null</c> if you want to use the default Chrome user profile location
        /// </param>
        /// <param name="logger">When set then logging is written to this ILogger instance for all conversions at the Information log level</param>
        /// <param name="useCache">When <c>true</c> (default) then Chrome uses it disk cache when possible</param>
        /// <exception cref="FileNotFoundException">Raised when <see cref="chromeExeFileName" /> does not exists</exception>
        /// <exception cref="DirectoryNotFoundException">
        ///     Raised when the <paramref name="userProfile" /> directory is given but does not exists
        /// </exception>
        public Converter(string chromeExeFileName = null,
                         string userProfile = null,
                         ILogger logger = null,
                         bool useCache = true)

I tried this, it doesn't work, it fails with the below error:

ail: Microsoft.AspNetCore.Server.Kestrel[13]
Connection id "0HMPL57K34GJV", Request id "0HMPL57K34GJV:00000001": An unhandled exception was thrown by the application.
ChromeHtmlToPdfLib.Exceptions.ChromeException: A timeout of '10000' milliseconds exceeded, the file 'C:\app\Data\profile\DevToolsActivePort' did not exist
at ChromeHtmlToPdfLib.Converter.ReadDevToolsActiveFile()
at ChromeHtmlToPdfLib.Converter.StartChromeHeadless()
at ChromeHtmlToPdfLib.Converter.Convert(OutputFormat outputFormat, Object input, Stream outputStream, PageSettings pageSettings, String waitForWindowStatus, Int32 waitForWindowsStatusTimeout, Nullable1 conversionTimeout, Nullable1 mediaLoadTim
eout, ILogger logger)
at ChromeHtmlToPdfLib.Converter.ConvertToPdf(String html, Stream outputStream, PageSettings pageSettings, String waitForWindowStatus, Int32 waitForWindowsStatusTimeout, Nullable1 conversionTimeout, Nullable1 mediaLoadTimeout, ILogger logger)
at SampleDockerForTuesPechkin.Controllers.WeatherForecastController.Get() in C:\src\Controllers\WeatherForecastController.cs:line 85
at lambda_method1(Closure, Object, Object[])

Updated code:

      var output = new MemoryStream();

        var chromeFilePath = AppContext.BaseDirectory + "\\chrome.exe";
        var chromeProfilePath = AppContext.BaseDirectory + "\\Data\\profile";
        var chromePath = AppContext.BaseDirectory + "\\chrome.exe";

        Console.WriteLine("ChromePath: " + chromeFilePath);
        Console.WriteLine("ChromeProfilePath: " + chromeProfilePath);

        var converter = new Converter(chromeFilePath, chromeProfilePath);
        Console.WriteLine("Adding arguments");
        converter.AddChromeArgument("--no-sandbox");
        converter.AddChromeArgument("--headless");
        converter.AddChromeArgument("--disable-extensions");
        converter.AddChromeArgument("--disable-gpu");
        converter.AddChromeArgument("--disable-dev-shm-usage");
        converter.AddChromeArgument("start-maximized");
        converter.AddChromeArgument("disable-infobars");
        converter.AddChromeArgument("--remote-debugging-port=9222");
        converter.AddChromeArgument("useAutomationExtension=false");
        

        Console.WriteLine("Converter");
        converter.ConvertToPdf(html, output, new ChromeHtmlToPdfLib.Settings.PageSettings());
        Console.WriteLine("Converted");

I tried to add arguments based on following this - https://stackoverflow.com/questions/50642308/webdriverexception-unknown-error-devtoolsactiveport-file-doesnt-exist-while-t, but no luck.

Just for the information, I am running this code on Windows Container, on my local machine without container below code works perfectly fine:

var output = new MemoryStream();
var converter = new Converter();
Console.WriteLine("Converter");
converter.ConvertToPdf(html, output, new ChromeHtmlToPdfLib.Settings.PageSettings());
Console.WriteLine("Converted");

File.WriteAllBytes(pdfPath, output.ToArray());
Console.WriteLine("Success");

commented

Does the user that is running the code have access to this location? C:\app\Data\profile\

When Chrome is started in headless mode ChromeHtmlToPdfLib needs to know the port on which Chrome is listening for commands. The port that Chrome uses is written to this file --> C:\app\Data\profile\DevToolsActivePort . If for any reason that the user that is running ChromeHtmlToPdfLib or Chrome itself has not read/write access to this location then you are getting the error you are getting now.

Did you check if the file is present overhere -> C:\app\Data\profile\ . If not then this is the reason.

As what I said in the first post... you have some kind if rights issue,

I used - https://portableapps.com/download#download_details to download GoogleChromePortable and used it's executable and profile in the Converter.

In the profile path I don't see any DevToolsActivePort file, I guess this is only created when Chrome's Developer Tool is enabled and actively used else this file won't exist. This should be anyways handled by the library itself if this is the case.

This still doesn't work, can you share a sample profile link which I can use?