Need More Info
Last Updated: 03 Jul 2025 10:56 by ADMIN
Olivier
Created on: 26 Jun 2025 13:12
Type: Bug Report
0
ReportProcessor.RenderReport() crashes with a 'System.ExecutionEngineException' when using SkiaSharp on Windows

Hi,

I'm working on a multiplatform project, using Telerik Reporting to generate PDF reports. The development is taking place on Windows.

The report is loaded programmatically (ReportPackager.Unpackage(...)), and the data is injected directly into the reports.

Some reports requires specific charts that are created as images and inserted into the PictureBox elements of the report before rendering. We are using SkiaSharp to generate these images, and I'm now trying to inject these images into the PictureBox elements.

For my first attempt, I have used the Gdi by first converting the SKImage to a System.Drawing.Image and it worked fine although it does not seem optimal.

Now I'm trying to write directly the SKImage to the PictureBox :

        public bool SetPictureBoxImage(string pictureBoxName, SKImage image)
        {
            PictureBox? pictureBox = (PictureBox?)_telerikReport.Items.Find(pictureBoxName, true).FirstOrDefault();
            if (pictureBox is null) return false;

            DrawingFactory.CurrentGraphicsEngine = GraphicsEngine.Skia;
            using var bitmap = SKBitmap.FromImage(image);
            IImage tlkImage = DrawingFactory.CreateImage(bitmap);
            pictureBox.Value = tlkImage;

            return true;
        }

However, when calling 'ReportProcessor.RenderReport(...)', a 'System.ExecutionEngineException' is thrown (no call stack, no additional details available).

I have tried to move the call 'DrawingFactory.CurrentGraphicsEngine = GraphicsEngine.Skia' before loading the report with no luck.

 

Is the 'Skia' rendering not available on Windows?

 

Please note that I cannot rely on the 'appsettings.json' file to configure the graphic engine.

I have tried to set the configuration programmatically through a custom implementation of 'Microsoft.Extensions.Configuration.IConfiguration' passed as an argument to 'ReportProcessor' constructors, but it had no effect. I have searched your code to find another way to set the configuration but it does not seem possible as everything is static and internal.

 

Kind regards

1 comment
ADMIN
Todor
Posted on: 03 Jul 2025 10:56

Hello Olivier,

Thank you for the code snippet.

The PictureBox Value supports particular types. Based on the code, you assign Telerik.Drawing.IImage, and I would expect it to work. You may also try with Byte[] or Base64String, or use Telerik.Drawing.ImageBase, as elaborated in the Note of the KB article How to Resolve the "You can assign System.String, IImage, System.Drawing.Image" Error in Telerik Reporting.

I confirm that we support Skia on Windows. You need to specify explicitly that you would like to use the Skia graphics engine in the processing Element of the Telerik Reporting Configuration. The graphics engine used by Telerik Reportion may be changed only with the configuration, and settings in the code won't be respected. Note that the Value of the PictureBox doesn't depend on the graphics engine, as the report definitions are platform-independent.

I tested locally with the following code, which works locally and generates the expected PDF:

using SkiaSharp;
using System;
using System.IO;
using System.Linq;
using Telerik.Drawing;
using Telerik.Drawing.Contract;
using Telerik.Reporting;

namespace CSharp.Net9.WinFormsIntegrationDemo
{
    public class RenderSKImageInReport
    {
        public static void RenderReport()
        {
            const string imagePath = @"C:\Tickets\images\reporting.png";
            const string reportPath = "C:\\Program Files (x86)\\Progress\\Telerik Reporting 2025 Q2\\Examples\\CSharp\\.NET 9\\WinFormsIntegrationDemo\\Report1.trdx";

            using var image = GetImage(imagePath);
            SetPictureBoxImage(image, reportPath);
        }

        static SKImage GetImage(string imagePath)
        {
            if (!File.Exists(imagePath)) return null;
            using var inputStream = File.OpenRead(imagePath);
            using var skData = SKData.Create(inputStream);
            var skImage = SKImage.FromEncodedData(skData);

            return skImage;
        }

        static void SetPictureBoxImage(SKImage image, string reportPath)
        {
            if (image is null)
            {
                throw new ArgumentNullException(nameof(image), "Image cannot be null.");
            }

            var _telerikReport = GetReport(reportPath);
            var pictureBox = (PictureBox)_telerikReport.Items.Find("pictureBox1", true).FirstOrDefault();
            if (pictureBox is null) throw new NullReferenceException();

            DrawingFactory.CurrentGraphicsEngine = GraphicsEngine.Skia;
            using var bitmap = SKBitmap.FromImage(image);
            IImage tlkImage = DrawingFactory.CreateImage(bitmap);
            pictureBox.Value = tlkImage;

            RenderReport(_telerikReport);
        }

        static void RenderReport(Report telerikReport)
        {
            var reportProcessor = new Telerik.Reporting.Processing.ReportProcessor();

            var reportSource = new InstanceReportSource();

            reportSource.ReportDocument = telerikReport;

            Telerik.Reporting.Processing.RenderingResult result = reportProcessor.RenderReport("PDF", reportSource, null);

            if (!result.HasErrors)
            {
                string fileName = result.DocumentName + "." + result.Extension;
                string filePath = Path.Combine("C:\\test", fileName);

                using (FileStream fs = new FileStream(filePath, FileMode.Create))
                {
                    fs.Write(result.DocumentBytes, 0, result.DocumentBytes.Length);
                }
            }
        }

        static Report GetReport(string reportPath)
        {
            System.Xml.XmlReaderSettings settings = new System.Xml.XmlReaderSettings();
            settings.IgnoreWhitespace = true;

            using (System.Xml.XmlReader xmlReader = System.Xml.XmlReader.Create(reportPath, settings))
            {
                var xmlSerializer = new Telerik.Reporting.XmlSerialization.ReportXmlSerializer();
                var report = (Report)xmlSerializer.Deserialize(xmlReader);

                return report;
            }
        }
    }
}

You need to adjust the paths to the report, the image, the generated document, and the PictureBox name.

You may indeed pass the IConfiguration with the second overload of the ReportProcessor constructor, as explained in the KB article How to pass configuration settings to ReportProcessor in ASP.NET Core application that does not use REST Service. Based on the available information, I have no clue why this doesn't work.

I suggest testing the code above, and if the problems persist, consider sending a minimal runnable project replicating them we may use to troubleshoot further.

Regards,
Todor
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.