2012-09-02 18 views
7

Estoy usando WkhtmltoPdf en mi aplicación web C# ejecutándose en .NET 4.0 para generar archivos PDF a partir de archivos HTML. En general, todo funciona bien, excepto cuando el tamaño del archivo HTML es inferior a 250 KB. Una vez que el tamaño del archivo HTML aumenta más allá de eso, el proceso que ejecuta wkhtmltopdf.exe da una excepción como la siguiente. En el Administrador de tareas, he visto que el valor de Memoria para el proceso wkhtmltopdf.exe no aumenta más allá de un valor de 40.096 K, que creo que es la razón por la cual el proceso se abandona en el medio.Límite de memoria para ejecutar ejecutables externos dentro de Asp.net

¿Cómo podemos configurarlo para que se pueda aumentar el límite de memoria para los archivos externos? ¿Hay alguna otra forma de resolver este problema?

Más información:
Cuando ejecuto directamente la conversión desde la línea de comandos, el PDF se genera correctamente. Por lo tanto, es poco probable que sea un problema con WkhtmlToPdf.

El error es de localhost. He intentado lo mismo en el servidor DEV, con el mismo resultado.

EDIT:

mensaje de excepción más específica: - Para la propiedad MainModule del objeto Proceso, dice el error - { "Sólo una parte de una solicitud ReadProcessMemory o WriteProcessMemory se completó"}, con el valor NativeErrorCode - 299.

Excepción:

> [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 [==================================>     
> ] 

Código que utilizo:

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(); 

depurador Captura de pantalla de WkHtmlToPdf.exe proceso:

enter image description here

+0

Quizás esto ayude: http://stackoverflow.com/a/9270159/135007 – ZippyV

+0

¿De dónde ve algo de hecho es un problema de falta de memoria? –

+0

@SimonMourier: Del hecho de que, mientras se ejecuta la aplicación, el valor de la memoria para wkhtmltopdf.exe no aumenta después de un cierto límite fijo en el Administrador de tareas. Mientras que mientras ejecuta lo mismo a través del símbolo del sistema, la ejecución está bien. Además, si el archivo HTML de entrada es de menor tamaño, a través de la aplicación simplemente funciona bien. Después de un tamaño fijo del archivo HTML, incluso un único carácter adicional no funciona. ¿Crees que podría ser algún otro problema además de la memoria? – itsbalur

Respuesta

0

Esto es lo que busca:

http://jobobjectwrapper.codeplex.com/

I no pude encontrar nada más que pertenezca t o "aumentar" el límite de memoria para un proceso, aunque he oído que las personas limitan la memoria de proceso con MaxWorkingSet, pero creo que esto es solo para la memoria virtual después de que la aplicación haya utilizado todo lo que pueda.

El objeto de trabajo es un buen lugar para comenzar, son solo una colección de procesos que son fácilmente controlables.

"Con esta biblioteca puede crear objetos de trabajo, crear y asignar un proceso al trabajo, proceso de control y límites de trabajo, y registrarse para los diversos eventos de notificación de proceso y relacionados con el trabajo."

Esto podría ser de utilidad también:

Calling wkhtmltopdf to generate PDF from HTML

+0

Gracias por su respuesta. Traté de alterar el MaxWorkingSet, pero como sugieres, parece que no funciona. Leí en alguna otra publicación SO, que siempre se recorta a un valor mucho menor durante la ejecución. Tengo que probar el contenedor de objetos de trabajo, aunque parece un poco complicado para empezar. :-) – itsbalur

+0

Sí, déjame saber cómo funciona. –

0

Tenga una mirada en this para ver si los subprocesos por límite de proceso pueden venir a jugar aquí Es una posibilidad muy remota (y. No conozco ningún límite de memoria impuesto por IIS en procesos externos), pero tenga en cuenta esto de la documentación:

Porque esta propiedad define el número máximo de solicitudes ASP que puede ejecutar simultáneamente, esta configuración debe permanecer en el valor predeterminado a menos que sus aplicaciones ASP realicen llamadas extendidas a los componentes externos . En este caso, puede aumentar el valor de Threads Per Processor Limit. Al hacerlo, permite que el servidor cree más hilos para manejar más solicitudes simultáneas.

+0

Gracias por su respuesta. No estoy seguro de que esté relacionado con IIS porque, traté de ejecutar código similar desde una aplicación de Windows, y existe el mismo problema. – itsbalur

+0

Hmm. Dos ideas el. Compruebe si esto podría ser un problema de 32/64 bits. Intente orientar explícitamente su ejecutable a 32 o 64 bits para ver si esto cambia las cosas. (Consulte http://stackoverflow.com/questions/10986486/c-sharp-only-part-of-a-readprocessmemory-or-writeprocessmemory-request-was-compl) En segundo lugar, observo que está redirigiendo la salida de la generó un proceso, pero no está procesando esa salida. Quizás hay un buffer de salida que se está agotando. Intente agregar un controlador de eventos para Process.OutputDataReceived para manejar el resultado. O deshabilite la redirección. – Olly

Cuestiones relacionadas