ASP.NET MVC - 生成PDF引发Win32Exception(0x80004005)

时间:2015-07-16 15:53:47

标签: c# asp.net-mvc pdf

我试图根据屏幕截图生成一些PDF。当我在本地启动该方法时,它没有任何问题。但是,当我在客户端计算机上部署它时,我收到了标题中提到的错误。这是方法:

public ActionResult GeneratePdf()
        {
            using (MemoryStream ms = new MemoryStream())
            {
                var bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);
                var gfxScreenshot = Graphics.FromImage(bmpScreenshot);
                gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
                bmpScreenshot.Save(Server.MapPath("~/Content/Images/Pdf/myscreenshot.png"), ImageFormat.Png);

                Document document = new Document(PageSize.A4, 25, 25, 30, 30);
                document.SetPageSize(iTextSharp.text.PageSize.A4.Rotate());
                PdfWriter writer = PdfWriter.GetInstance(document, ms);

                document.Open();
                DateTime dtNow = DateTime.Now;
                document.Add(new Paragraph(dtNow.ToString() + " - Impression de rendez-vous"));
                System.Drawing.Image myImage = System.Drawing.Image.FromFile(Server.MapPath("~/Content/Images/Pdf/myscreenshot.png"));
                iTextSharp.text.Image jpgImg = iTextSharp.text.Image.GetInstance(myImage, System.Drawing.Imaging.ImageFormat.Jpeg);
                jpgImg.ScaleAbsolute(800, 500);
                document.Add(jpgImg);
                document.Close();
                writer.Close();

                Response.ContentType = "pdf/application";
                Response.AddHeader("content-disposition", "attachment;filename =Impression_Qutenza.pdf");
                Response.OutputStream.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length);

            }
            return View();
        }

知道发生了什么事吗?

编辑:堆栈跟踪:

[Win32Exception (0x80004005): Descripteur non valide]
   System.Drawing.Graphics.CopyFromScreen(Int32 sourceX, Int32 sourceY, Int32 destinationX, Int32 destinationY, Size blockRegionSize, CopyPixelOperation copyPixelOperation) +512
   AstellasSchedulerV2.Controllers.HomeController.GeneratePdf() +232
   lambda_method(Closure , ControllerBase , Object[] ) +62
   System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +14
   System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +182
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +27
   System.Web.Mvc.Async.<>c__DisplayClass42.<BeginInvokeSynchronousActionMethod>b__41() +28
   System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +10
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +50
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +32
   System.Web.Mvc.Async.<>c__DisplayClass39.<BeginInvokeActionMethodWithFilters>b__33() +58
   System.Web.Mvc.Async.<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49() +225
   System.Web.Mvc.Async.<>c__DisplayClass37.<BeginInvokeActionMethodWithFilters>b__36(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +50
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +34
   System.Web.Mvc.Async.<>c__DisplayClass2a.<BeginInvokeAction>b__20() +24
   System.Web.Mvc.Async.<>c__DisplayClass25.<BeginInvokeAction>b__22(IAsyncResult asyncResult) +99
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +50
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27
   System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__18(IAsyncResult asyncResult) +14
   System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +23
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +55
   System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +39
   System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +23
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +55
   System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +29
   System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
   System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__3(IAsyncResult asyncResult) +25
   System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +23
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +55
   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() +9629708
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

2 个答案:

答案 0 :(得分:0)

您发布的代码不会截取您在网络浏览器中运行的网页的屏幕截图,它会截取当前屏幕的截图运行Web服务器的PC 。 “它在您的本地PC中运行”有两个原因:

1-您的开发PC同时在那里运行服务器和Web浏览器。

2-您用于开发的Web服务器未作为服务运行。

部署到Internet Information Server的Web应用程序将在IIS服务进程下运行,并且服务进程无法访问服务器屏幕,这就是您在堆栈跟踪中看到错误的原因。

可能的解决方案:

1-使用PDF处理库,使用与用于提供网页相同的数据,在服务器上从头开始生成PDF文件。

或者

2-使用HTML-to-PDF转换工具从服务器上本地请求的等效页面生成PDF文件。示例:WkhtmltopdfAmyuni WebkitPDF注意:我为Amyuni Technologies工作

答案 1 :(得分:0)

ASP.NET代码在服务器端运行,当您调用.CopyFromScreen()方法时,它会尝试访问服务器上的屏幕。并且不允许代码访问浏览器的屏幕。此安全限制是必须的,否则病毒和特洛伊木马将无法在未经用户许可的情况下窃取信息。

  1. 有一个commercial component可以从服务器端代码获取给定网址的截图(但网址应该是公开的)。
  2. 您可以使用实际获取HTML的this solution从客户端代码捕获屏幕截图(以显示最终用户看到的屏幕截图)并将其呈现为图像以模仿原始页面。
  3. 另一个解决方案是实施您自己的最终用户桌面实用程序(如this one)或插件/扩展程序(如Google Chrome的this one),它将安装在最终用户计算机上(使用最终用户的许可,将截图并将其发送回您的服务器。