7

I am using WkhtmltoPdf in my C# web application running in .NET 4.0 to generate PDFs from HTML files. In general everything works fine except when the size of the HTML file is below 250KB. Once the HTML file size increases beyond that, the process which runs the wkhtmltopdf.exe gives an exception as below. On the Task Manager, I have seen that the Memory value for the wkhtmltopdf.exe process does not increase beyond a value of 40,096 K, which I believe is the reason why the process is abandoned in between.

How can we configure such that the memory limit for external exes can be increased? Is there any other way of solving this issue?

More info:
When I run the conversion from the command line directly, the PDF is generated fine. So, its unlikely to be a problem with WkhtmlToPdf.

The error is from localhost. I have tried the same on the DEV server, with the same result.

EDIT:

More specific exception message: - For the MainModule property of the Process object, the error says - {"Only part of a ReadProcessMemory or WriteProcessMemory request was completed"}, with the NativeErrorCode value - 299.

Exception:

> [Exception: Loading pages (1/6) [>                                    
> ] 0% [======>                                                     ]
> 10% [======>                                                     ] 11%
> [=======>                                                    ] 13%
> [=========>                                                  ] 15%
> [==========>                                                 ] 18%
> [============>                                               ] 20%
> [=============>                                              ] 22%
> [==============>                                             ] 24%
> [===============>                                            ] 26%
> [=================>                                          ] 29%
> [==================>                                         ] 31%
> [===================>                                        ] 33%
> [=====================>                                      ] 35%
> [======================>                                     ] 37%
> [========================>                                   ] 40%
> [=========================>                                  ] 42%
> [==========================>                                 ] 44%
> [============================>                               ] 47%
> [=============================>                              ] 49%
> [==============================>                             ] 51%
> [============================================================] 100%
> Counting pages (2/6)                                               
> [============================================================] Object
> 1 of 1 Resolving links (4/6)                                          
> [============================================================] Object
> 1 of 1 Loading headers and footers (5/6)                              
> Printing pages (6/6) [>                                               
> ] Preparing [=>                                                       
> ] Page 1 of 49 [==>                                                   
> ] Page 2 of 49 [===>                                                  
> ] Page 3 of 49 [====>                                                 
> ] Page 4 of 49 [======>                                               
> ] Page 5 of 49 [=======>                                              
> ] Page 6 of 49 [========>                                             
> ] Page 7 of 49 [=========>                                            
> ] Page 8 of 49 [==========>                                           
> ] Page 9 of 49 [============>                                         
> ] Page 10 of 49 [=============>                                       
> ] Page 11 of 49 [==============>                                      
> ] Page 12 of 49 [===============>                                     
> ] Page 13 of 49 [================>                                    
> ] Page 14 of 49 [==================>                                  
> ] Page 15 of 49 [===================>                                 
> ] Page 16 of 49 [====================>                                
> ] Page 17 of 49 [=====================>                               
> ] Page 18 of 49 [======================>                              
> ] Page 19 of 49 [========================>                            
> ] Page 20 of 49 [=========================>                           
> ] Page 21 of 49 [==========================>                          
> ] Page 22 of 49 [===========================>                         
> ] Page 23 of 49 [============================>                        
> ] Page 24 of 49 [==============================>                      
> ] Page 25 of 49 [===============================>                     
> ] Page 26 of 49 [=================================>                   
> ] Page 27 of 49 [==================================>                  
> ]

Code that I use:

    var fileName = " - ";
    var wkhtmlDir = ConfigurationManager.AppSettings[Constants.AppSettings.ExportToPdfExecutablePath];
    var wkhtml = ConfigurationManager.AppSettings[Constants.AppSettings.ExportToPdfExecutablePath] + "\\wkhtmltopdf.exe";
    var p = new Process();


    string switches = "";
    switches += "--print-media-type ";
    switches += "--margin-top 10mm --margin-bottom 10mm --margin-right 5mm --margin-left 5mm ";
    switches += "--page-size A4 ";
    switches += "--disable-smart-shrinking ";

    var startInfo = new ProcessStartInfo
    {
        CreateNoWindow = true,
        FileName = wkhtml,
        Arguments = switches + " " + url + " " + fileName,
        UseShellExecute = false,
        RedirectStandardOutput = true,
        RedirectStandardError = true,
        RedirectStandardInput=true,
        WorkingDirectory=wkhtmlDir
    };

    p.StartInfo = startInfo;
    p.Start();

Debugger Screenshot of WkHtmlToPdf.exe Process:

enter image description here

itsbalur
  • 953
  • 2
  • 17
  • 38
  • Maybe this helps: http://stackoverflow.com/a/9270159/135007 – ZippyV Sep 02 '12 at 09:44
  • Where do you see any fact it's an out of memory problem? – Simon Mourier Sep 11 '12 at 08:14
  • @SimonMourier: From the fact that while running through the app, the memory value for the wkhtmltopdf.exe doesn't increase after a certain fixed limit in the Task Manager. Whereas while running the same through command prompt the execution is just fine. Also, if the input HTML file is of lesser size, then through the app it just works fine. After a fixed size of the HTML file, even a single additional character doesn't work. Do you think it could be some other issue other than memory? – itsbalur Sep 11 '12 at 09:50
  • That could be something else, yes, because there is no evidence it's a memory issue, the exception is not clear, does not display anything about memory. It would be if you saw the process memory increase, like 1 or 2 Gb, but it does not seem to be the case. Are you sure it's not a bug in WkhtmlToPdf? – Simon Mourier Sep 11 '12 at 11:26
  • @SimonMourier: It works fine when I run WkhtmlToPdf through command prompt. So, I assume its not with WkhtmlToPdf. For the MainModule property of the Process object, the error says - {"Only part of a ReadProcessMemory or WriteProcessMemory request was completed"}, with the NativeErrorCode value - 299. – itsbalur Sep 12 '12 at 02:46
  • Ok, so this is not an out of memory problem. Have you tried to change your process's CPU Target to X64, or X86? – Simon Mourier Sep 12 '12 at 06:03
  • The platform and configuration target was x86. I changed it to "Any CPU" and still the same issue persists. I have attached a screenshot of the process values while debugging. I believe the values are in bytes. Which of it are relevant while running the process? – itsbalur Sep 12 '12 at 07:30
  • Have you got any solution for this issue. Am also struggling with the the same problem. – Sandeep Thomas Oct 29 '13 at 11:07

2 Answers2

0

This is what your looking for:

http://jobobjectwrapper.codeplex.com/

I couldn't find anything else that pertains to "increasing" the Memory Limit for a process, although I've heard of people limiting the Process Memory with MaxWorkingSet, but I believe this is only for virtual memory after the application has used all it can.

The Job Object is a good place to start, they're just a collection of processes that are easily controllable.

"With this library you can create job objects, create and assign a process to the job, control process and job limits, and register for the various process- and job-related notification events."

This might be of use too:

Calling wkhtmltopdf to generate PDF from HTML

Community
  • 1
  • 1
Nate-Wilkins
  • 5,158
  • 3
  • 42
  • 60
  • Thanks for your answer. I tried altering the MaxWorkingSet, but as you suggest it doesn't seem to work. I read in some other SO post, that it always get trimmed to a much lesser value while execution. I have to try the job object wrapper, looks a bit complicated for a start though. :-) – itsbalur Sep 12 '12 at 02:52
0

Have a look at this to see whether the Threads Per Process limit may be coming in to play here. It's a long shot (and I'm not aware of any memory limit imposed by IIS on external processes), but note this from the documentation:

Because this property defines the maximum number of ASP requests that can execute simultaneously, this setting should remain at the default value unless your ASP applications are making extended calls to external components. In this case, you may increase the value of Threads Per Processor Limit. Doing so allows the server to create more threads to handle more concurrent requests.

Olly
  • 5,716
  • 27
  • 57
  • Thanks for your answer. I am not sure it is related to IIS because, I tried to execute similar code from a Windows App, and the same issue exists. – itsbalur Sep 12 '12 at 02:49
  • Hmm. Two ideas the. Check whether this could be a 32/64 bit issue. Try explicitly targeting your executable at 32 or 64 bit to see if this changes things. (See http://stackoverflow.com/questions/10986486/c-sharp-only-part-of-a-readprocessmemory-or-writeprocessmemory-request-was-compl) Secondly, I notice that you're redirecting output from the spawned process, but you're not processing that output. Perhaps there is an output buffer that is being exhausted. Try adding an event handler for Process.OutputDataReceived to handle the output. Or disable the redirection. – Olly Sep 12 '12 at 12:21