Sicos1977 / ChromiumHtmlToPdf

Convert HTML to PDF with a Chromium based browser

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Converter.ConvertToImage Stuck at 'Getting page frame tree'

jackyb43 opened this issue · comments

Hello, thanks for this project. I really need it.
I need to convert a html code (which it's inside a stringbuilder) with this structure:

<html>
<head>
<style>
    table style...
</style
</head>
    <body>
        <table>...</table>
    </body>
</html>

The html is well built because I can render it on https://codebeautify.org/htmlviewer (but not indented since It's created runtime) This is my code:

                var logger = !string.IsNullOrWhiteSpace("logg.txt")
                  ? new ChromeHtmlToPdfLib.Loggers.Stream(File.OpenWrite(@"c:\users\jbalducci\desktop\asd.txt"))
                  : new ChromeHtmlToPdfLib.Loggers.Console();
                MemoryStream stream = new();
                using (ChromeHtmlToPdfLib.Converter converter = new())
                {
                    converter.ConvertToImage(sbHtml.ToString(), stream, new 
                    ChromeHtmlToPdfLib.Settings.PageSettings(ChromeHtmlToPdfLib.Enums.PaperFormat.FitPageToContent), logger: logger);
                }
                var imageBytes = stream.ToArray();
                stream.Dispose();

The method ConvertToImage doesn't do its job, the program is stuck, in the log file I have these lines:

2021-12-16T23:53:10.672 - Starting Chrome from location 'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe' with working directory 'C:\Program Files (x86)\Google\Chrome\Application'
2021-12-16T23:53:10.693 - "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --headless --disable-gpu --hide-scrollbars --mute-audio --disable-background-networking --disable-background-timer-throttling --disable-default-apps --disable-extensions --disable-hang-monitor --disable-prompt-on-repost --disable-sync --disable-translate --metrics-recording-only --no-first-run --disable-crash-reporter --remote-debugging-port="0" --window-size="1366,768"
2021-12-16T23:53:10.718 - Chrome process started
2021-12-16T23:53:11.525 - Received Chrome error data: 'DevTools listening on ws://127.0.0.1:49528/devtools/browser/9a9c5b58-755f-4ca1-b4a9-86e4b82a16f1'
2021-12-16T23:53:11.525 - Connecting to dev protocol on uri 'ws://127.0.0.1:49528/devtools/browser/9a9c5b58-755f-4ca1-b4a9-86e4b82a16f1'
2021-12-16T23:53:11.559 - Creating new websocket connection to url 'ws://127.0.0.1:49528/devtools/browser/9a9c5b58-755f-4ca1-b4a9-86e4b82a16f1'
2021-12-16T23:53:11.569 - Opening websocket connection with a timeout of 30 seconds
2021-12-16T23:53:11.714 - Websocket opened
2021-12-16T23:53:11.926 - Creating new websocket connection to url 'ws://127.0.0.1:49528/devtools/page/1509782EA4467F24112ABA2A90976106'
2021-12-16T23:53:11.926 - Opening websocket connection with a timeout of 30 seconds
2021-12-16T23:53:11.928 - Websocket opened
2021-12-16T23:53:11.928 - Connected to dev protocol
2021-12-16T23:53:11.929 - Chrome started
2021-12-16T23:53:11.929 - Getting page frame tree

I opened visual studio ad administrator.
Can you please help me fixing this? Thanks!

commented

I tried your code in a somewhat different way but it works here without any problems, are you sure that Chrome gets started in the background and that there are no plugins that are avoiding it from working correctly?

            using (var ms = new MemoryStream())
            using (Converter converter = new())
            {
                converter.ConvertToImage("Test", ms, new PageSettings(PaperFormat.FitPageToContent));
                File.WriteAllBytes("d:\\test.png", ms.ToArray());
            }

image

I tried your code in a somewhat different way but it works here without any problems, are you sure that Chrome gets started in the background and that there are no plugins that are avoiding it from working correctly?

            using (var ms = new MemoryStream())
            using (Converter converter = new())
            {
                converter.ConvertToImage("Test", ms, new PageSettings(PaperFormat.FitPageToContent));
                File.WriteAllBytes("d:\\test.png", ms.ToArray());
            }

image

Yes the browser starts because I see the new process everytime I run it.
I don't have any plugin but EditThisCookie and IDM, I don't think they do anything because when I open chrome the start is smooth without any impediment

commented

My only advice is to clone my repo and use the console app and then see why it get's stuck on the getting page frame tree, does it get response from Chrome or not? It is really hard for me to figure out why it does not work for you because it works for me.

What you can do is add some extra logging to see what kind of response you get for the message that is asking for the page frame tree. Does Chrome give a response or not?

Add a breakpoint over here

image

I just did it and it works fine, the frameTree variable has value and the output file content is good

commented

So does the program continue to run then?

The clone of your project yes, my program no, I am using .net framework 6.0 for my project and
ChromeHtmlToPdf 2.5.19

commented

What happens if you upgrade the console project to .net 6?

commented

Nevermind I already did it and then also everything seems to be running without any problems.

image

image

The only option I see it to add the ChromeHtmlToPdfLib project to your solution and set the breakpoint again on the line I mentioned before and see what you get back, almost seems like something in your project is blocking something.

commented

Use this method

        /// <summary>
        ///     Converts the given <paramref name="inputUri" /> to an image (png)
        /// </summary>
        /// <param name="inputUri">The webpage to convert</param>
        /// <param name="outputStream">The output stream</param>
        /// <param name="pageSettings"><see cref="PageSettings"/></param>
        /// <param name="waitForWindowStatus">Wait until the javascript window.status has this value before
        ///     rendering the PDF</param>
        /// <param name="waitForWindowsStatusTimeout"></param>
        /// <param name="conversionTimeout">An conversion timeout in milliseconds, if the conversion fails
        ///     to finished in the set amount of time then an <see cref="ConversionTimedOutException"/> is raised</param>
        /// <param name="mediaLoadTimeout">When set a timeout will be started after the DomContentLoaded
        ///     event has fired. After a timeout the NavigateTo method will exit as if the page has been completely loaded</param>
        /// <param name="logger">When set then this will give a logging for each conversion. Use the logger
        ///     option in the constructor if you want one log for all conversions</param>
        /// <exception cref="ConversionTimedOutException">Raised when <paramref name="conversionTimeout"/> is set and the 
        /// conversion fails to finish in this amount of time</exception>
        /// <remarks>
        ///     When the property <see cref="CaptureSnapshot"/> has been set then the snapshot is saved to the
        ///     property <see cref="SnapshotStream"/>
        /// </remarks>
        public void ConvertToImage(
            ConvertUri inputUri,
            Stream outputStream,
            PageSettings pageSettings,
            string waitForWindowStatus = "",
            int waitForWindowsStatusTimeout = 60000,
            int? conversionTimeout = null,
            int? mediaLoadTimeout = null,
            ILogger logger = null)
        {
            Convert(
                OutputFormat.Image,
                inputUri,
                outputStream,
                pageSettings,
                waitForWindowStatus,
                waitForWindowsStatusTimeout,
                conversionTimeout,
                mediaLoadTimeout,
                logger);
        }

And input the source through inputUri file like this file://WhereEverYouSavedYourfile.txt

This does not use the page tree method

It would be a perfect workaround solution. Will try soon! Anyway yes, the console app still works with .net framework 6.0 like you said!

Now It's stucked at Disabling caching
LOG:
2021-12-18T16:18:48.232 - Starting Chrome from location 'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe' with working directory 'C:\Program Files (x86)\Google\Chrome\Application' 2021-12-18T16:18:48.700 - "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --headless --disable-gpu --hide-scrollbars --mute-audio --disable-background-networking --disable-background-timer-throttling --disable-default-apps --disable-extensions --disable-hang-monitor --disable-prompt-on-repost --disable-sync --disable-translate --metrics-recording-only --no-first-run --disable-crash-reporter --remote-debugging-port="0" --window-size="1366,768" 2021-12-18T16:18:48.772 - Chrome process started 2021-12-18T16:18:49.676 - Received Chrome error data: 'DevTools listening on ws://127.0.0.1:65488/devtools/browser/4d5e5562-92c5-4f56-abca-c55f129548f1' 2021-12-18T16:18:49.691 - Connecting to dev protocol on uri 'ws://127.0.0.1:65488/devtools/browser/4d5e5562-92c5-4f56-abca-c55f129548f1' 2021-12-18T16:18:49.730 - Creating new websocket connection to url 'ws://127.0.0.1:65488/devtools/browser/4d5e5562-92c5-4f56-abca-c55f129548f1' 2021-12-18T16:18:49.756 - Opening websocket connection with a timeout of 30 seconds 2021-12-18T16:18:49.954 - Websocket opened 2021-12-18T16:18:50.316 - Creating new websocket connection to url 'ws://127.0.0.1:65488/devtools/page/62B6AD8E66B3226D148169FE7AA7EB28' 2021-12-18T16:18:50.316 - Opening websocket connection with a timeout of 30 seconds 2021-12-18T16:18:50.328 - Websocket opened 2021-12-18T16:18:50.328 - Connected to dev protocol 2021-12-18T16:18:50.328 - Chrome started 2021-12-18T16:18:50.328 - Loading file C:\Users\jbalducci\Desktop\TBSM\TBSM\TBSM\bin\Debug\net6.0-windows\eu.htm 2021-12-18T16:18:50.331 - Disabling caching

commented

On wat kind of operating system are you running your code? Windows server?

Windows 10 pro connected to a company domain

commented

Windows 11 here, I know Chrome sometimes has issues when running on Windows Server 2016 but that is not your case. So I really have no idea why you are getting these problems.

I also use ChromeHtmlToPdfLib at the company where I'm working and there it runs on Windows 2012/2016 and 2019 servers in a multithreaded environment with up to 25 to 50 conversions simultaneously without any problems.

commented

Do you have Chrome installed or are you using the portable version? And are you using Chrome in a Windows Service?

commented

Did you also check the event viewer if Chrome or Windows reports an issue overthere? It almost looks like you have some kind of issue with security rights because Chrome tries to write Cache and temporary files and it almost looks like it can't do that and then freezes.

Chrome is installed, no portable version. I'm not using Chrome in a windows service.
I was thinking if it could be Webroot SecureAnywhere? The thing is I cannot disable it because it says to contact the network administrator to do so.
WIll check the events

commented

Try to set the userprofile directory to a location where you got enough rights and see if that makes a difference. This will force Chrome to write all it's caching and temporary files to another location

commented

Also don't run your service under the System account, this forces all kind of restictions on what an application can do that is started under this account. Using the system account on a service makes a sandbox with a lott of restrictions.

Should I create a new user in Windows and move everything there?

commented

You can use the userProfile param on the Converter constructor to specify another userProfile dir if you need it

        /// <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)
commented

Create whatever user you want, if you are later installing this on a server then make sure that the account has service logon right otherwise you are not allowed to use it with a service.

The first time you can start the service but when policies get pushed to the server then probably your service logon rights will be gone. But this depends on how your domain is configured and if policies are pushed from domain controllers.

I get this event message when calling the conversion method :
Le impostazioni delle autorizzazioni impostazioni specifiche dell'applicazione non concedono l'autorizzazione di Attivazione in Locale per l'applicazione server COM con CLSID
{2593F8B9-4EAF-457C-B68A-50F6B8EA6B54}
e APPID
{15C20B67-12E7-4BB6-92BB-7AFF07997402}
all'utente VENTIS\SID () dall'indirizzo LocalHost (tramite LRPC) in esecuzione nel SID del contenitore di applicazioni Non disponibile (Non disponibile). Per modificare tale autorizzazione di sicurezza, è possibile utilizzare lo strumento amministrativo Servizi componenti.

Thanks anyway for everything, I think we can close the question!

commented

I guess that is Italian?

Yes

commented

Did you lookup the CLSID id's in the registry to see what program it is?

commented

2593F8B9-4EAF-457C-B68A-50F6B8EA6B54 = C:\Windows\System32\RuntimeBroker.exe

That has nothing to do with Crome, Chrome is not an COM based application

commented

Also don't post your AD security ID or network name in a post (I removed it) that is bad practice and a give away for hackers on your coorporate network. Always sanitize things like this when posting something on the internet where everybody can read it.

Ok, thanks.
It's PerAppRuntimeBroker, I don't know if it has to do with the program but everytime I run the method this event show up, at exact same time

commented

Weird, did you already try to run the service under a different account?

Not yet, because this is the only account I use. I will try to make another one later and post again, for the last time hopefully. haha
thanks

commented

Getting things like this to work is sometimes difficult, certainly when security pushes all kind of policies that make live for a developer hard... trust me I know from experience.