NReco.PdfGenerator 1.1.7不能在托管环境中工作

NReco.PdfGenerator 1.1.7 does not work in hosted environment

本文关键字:环境 工作 PdfGenerator 不能 NReco      更新时间:2023-10-16

我花了一些时间创建一组由PdfCreator生成的报告。我喜欢用HTML定义内容,然后生成PDF文件,可以在WPF客户端和MVC站点中使用。

它在本地工作得很好。但是当将网站发布到托管环境时,PDF生成突然崩溃……为什么! ! ?

网页上的错误输出不是很有帮助:

(exit code: -1073741701)
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 
Exception Details: NReco.PdfGenerator.WkHtmlToPdfException: (exit code: -1073741701)
Source Error: 
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace: 

[WkHtmlToPdfException:  (exit code: -1073741701)]
   NReco.PdfGenerator.HtmlToPdfConverter.CheckExitCode(Int32 exitCode, String lastErrLine, String outputFilePath) +123
   NReco.PdfGenerator.HtmlToPdfConverter.GeneratePdfInternal(String[] htmlFiles, Byte[] inputBytes, String coverHtml, String outputPdfFilePath, Stream outputStream) +2481
[Exception: Cannot generate PDF:  (exit code: -1073741701)]
   NReco.PdfGenerator.HtmlToPdfConverter.GeneratePdfInternal(String[] htmlFiles, Byte[] inputBytes, String coverHtml, String outputPdfFilePath, Stream outputStream) +2819
   NReco.PdfGenerator.HtmlToPdfConverter.GeneratePdf(String htmlContent, String coverHtml, Stream output) +87
   NReco.PdfGenerator.HtmlToPdfConverter.GeneratePdf(String htmlContent, String coverHtml) +42
   SongService.Report.DomainServices.ReportCompiler.GeneratePdf(String templateName, T model) +704
   SongServiceWeb.Controllers.PresentationController.GetReport(Guid presentationId) +261
   lambda_method(Closure , ControllerBase , Object[] ) +122
   System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +14
   System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +156
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +27
   System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState) +22
   System.Web.Mvc.Async.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult) +29
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +32
   System.Web.Mvc.Async.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d() +50
   System.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +225
   System.Web.Mvc.Async.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +34
   System.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c() +26
   System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +100
   System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27
   System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +13
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +36
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +54
   System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +39
   System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) +12
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +28
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +54
   System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +29
   System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
   System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +21
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +36
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +54
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +31
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9651796
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

这个问题有一个有趣的建议:NReco。ASP中的PdfGenerator。. NET停止在服务器上工作

在NReco的版本历史中。PdfGenerator它说1.1.6有一个依赖于c++包的新部署。

引用自Nuget:v1.1.6变化:WkHtmlToPdf工具升级到0.12.2.1版本(2015年1月19日发布)。注意:此版本的wkhtmltopdf需要VS 2013 (x86)的Visual c++可重新分发包。WkHtmlToPdf工具升级到0.12.2.1版本(2015年1月19日发布)。注意:此版本的wkhtmltopdf需要VS 2013 (x86)的Visual c++可重新分发包。

即使我的错误是不同的,我试图添加丢失的文件。我包括msvcp120.dll和msvcr120.dll,但它没有区别。只是为了确保我添加了vccorlib120.dll和wkhtmltopdf.exe以及。仍无差异

我的下一个想法是,我需要指出一个具有写权限的临时目录,可以在内部工作中使用。但是我在文档中没有找到任何参考。

编辑:

我发现了一个名为TempFilesPath的HtmlToPdfConverter属性。那看起来真的很有希望!所以我很快创建了一个目录,并设置了所需的写权限。

converter.TempFilesPath = HttpContext.Server.MapPath(@"~/_temp");

我验证了这个目录在主机上的代码是可读可写的。但是PdfCreator的错误仍然是相同的…

关于系统需求,我在这个页面http://www.nrecosite.com/pdf_generator_net.aspx上找到了一段话:

  • PdfGenerator适用于Azure Web角色/Worker角色/普通虚拟机。
  • Azure网站不支持,因为GDI WinAPI限制,阻止WkHtmlToPdf工作。

我想这可能也适用于我的情况。我没有在Azure中运行,但仍然在"云服务"环境中运行,因此它们很可能具有GDI WinAPI的相同限制。

这真的很可悲。这个想法很好:同样的报告在网络和客户端。

我们有类似的错误提示:Cannot generate PDF:(exit code: -1073741819)

如果有人需要的话,我把我们的解决方案放在这里。从控制台中执行wkhtmltopdf.exe并检查错误。在我们的例子中,它说一些dll丢失了,比如api-ms-win-core-localization-l1-2 .dll, api-ms-win-core-timezone-l1-2 .dll等等。我不知道为什么这些dll不在服务器上。根据操作系统,我们在system32或sysWOW64文件夹下找到了正确的位置,并将这些dll复制到这些文件夹中,问题解决了。

例如如何修复api-ms-win-core-timezone-l1-2-0.dll问题,下面的链接将提供帮助:https://www.youtube.com/watch?v=s5N0jmYyy34