在Azure WebApp上将ReportViewer报告打印为PDF。获取通用GDI错误

在Azure WebApp上将ReportViewer报告打印为PDF。获取通用GDI错误,azure,reportviewer,gdi,azure-web-app-service,Azure,Reportviewer,Gdi,Azure Web App Service,我有一段代码,可以获取ReportViewer报告并通过PrintDialog打印它。然而,当我将其移动到Azure WebApp时,我会得到一个通用GDI错误。我一直在寻找解决方案,但我发现Azure正在阻止大多数GDI调用。它在下面的导出方法上出了问题。有什么建议吗 private Stream CreateStream(string name, string fileNameExtension, Encoding encoding, string mimeType, bool wi

我有一段代码,可以获取ReportViewer报告并通过PrintDialog打印它。然而,当我将其移动到Azure WebApp时,我会得到一个通用GDI错误。我一直在寻找解决方案,但我发现Azure正在阻止大多数GDI调用。它在下面的导出方法上出了问题。有什么建议吗

    private Stream CreateStream(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek)
    {
        try
        {
            Stream stream = new MemoryStream();
            m_streams.Add(stream);
            return stream;
        }
        catch (Exception ex)
        {
            throw new Exception("CreateStream: " + ex.Message, ex.InnerException);
        }
    }

    public void Export(LocalReport report)
    {
        try
        {
            string deviceInfo =
              @"<DeviceInfo>
            <OutputFormat>EMF</OutputFormat>
            <PageWidth>8.5in</PageWidth>
            <PageHeight>11in</PageHeight>
            <MarginTop>0.25in</MarginTop>
            <MarginLeft>0.25in</MarginLeft>
            <MarginRight>0.25in</MarginRight>
            <MarginBottom>0.25in</MarginBottom>
        </DeviceInfo>";
            Warning[] warnings;
            m_streams = new List<Stream>();
            report.Render("Image", deviceInfo, CreateStream, out warnings);
            foreach (Stream stream in m_streams)
                stream.Position = 0;
        }
        catch (Exception ex)
        {
            throw new Exception("Export: " + ex.Message, ex.InnerException);
        }

    }
private Stream CreateStream(字符串名称、字符串文件名扩展名、编码编码、字符串mimeType、bool willSeek)
{
尝试
{
Stream=新的MemoryStream();
m_streams.Add(stream);
回流;
}
捕获(例外情况除外)
{
抛出新异常(“CreateStream:+ex.Message,ex.InnerException);
}
}
公共void导出(LocalReport)
{
尝试
{
字符串设备信息=
@"
电动势
8.5英寸
11英寸
0.25英寸
0.25英寸
0.25英寸
0.25英寸
";
警告[]警告;
m_streams=新列表();
report.Render(“Image”、deviceInfo、CreateStream、out警告);
foreach(m_streams中的流)
流位置=0;
}
捕获(例外情况除外)
{
抛出新异常(“导出:+ex.Message,ex.InnerException”);
}
}

所有Azure Web应用程序都在称为沙箱的安全环境中运行。每个应用程序都在自己的沙箱中运行,将其执行与同一台机器上的其他实例隔离开来,并提供了额外的安全性和隐私性,否则将无法使用

为了彻底减少攻击表面积,沙箱阻止了几乎所有的Win32k.sys API被调用,这实际上意味着大部分User32/GDI32系统调用被阻止。对于大多数应用程序,这不是问题,因为大多数Azure Web应用程序不需要访问Windows UI功能。但是,受影响的一种常见模式是PDF文件生成

如本文件所述-支持以下PDF生成器:

•SQL报告框架:要求站点以基本或更高版本运行 (请注意,这目前在消费模式下的功能应用程序中不起作用)

•EVOPDF:有关供应商解决方案,请参阅

•Telerik报告:要求站点以基本或更高版本运行

•Rotativa/wkhtmltopdf:要求网站以Basic或更高版本运行


•NReco PdfGenerator(wkhtmltopdf):需要订阅计划Basic或更高版本

事实上,我认为问题在于Azure的GDI不支持EMF,Telerik Reporting的桌面查看器和报表处理器在打印时使用EMF。但是,在中,问题得到了解决,并且可以调整打印格式,以便引擎使用位图而不是Azure支持的图元文件进行打印。将调用相关的呈现扩展名,并可通过应用程序的配置文件进行设置,如下所示:



这是一个基本的、标准的还是免费的应用程序服务计划?我认为这可能是ActiveX带来的问题——您可能需要考虑将其移动到云服务中的Web角色,或是严格的VMIt标准。我看过你提到的解决办法。还有其他选择吗?