In a Windows service, Microsoft report generation fails when SciChart-Control was instantiated before

79 Views Asked by At

I have an application, which uses a method to create reports including a SciChart-Control. This does work both in WPF and Console applications. But when I needed to create such report automatically in a windows service, the service just seems to hang upon calling the report-method.

Used packages:

  • SciChart, testet with Version 6 and 7
  • Microsoft.ReportViewer.WinForms, Version 10.0.40219.1

I figured, that it doesn't matter if I actually include the SciChart-Control in the report. What matters is, if I create an instance of the SciChart-Control before printing the report. The LocalReport.Render() method seems to block further execution then.

I created a minimal working example, where

  • SciChartControl is an blank WPF control, only containing a SciChartSurface-Element
  • Report1.rdlc is a blank report, containing just a textbox-element.
public class Test
{
    private const string PathOfReport = @"Path\to\report\Report1.rdlc";
    private const string OutputPath = @"Path\to\output";
    private const string DeviceInfo = "<DeviceInfo><SimplePageHeaders>True</SimplePageHeaders></DeviceInfo>";

    public static void TestReport(string outputName, bool instantiateSciChart)
    {
        var t = new Thread(() =>
        {
            if (instantiateSciChart)
                _ = new SciChartTestControl();

            byte[] data = DoRenderReport();
            File.WriteAllBytes(@$"{OutputPath}\{outputName}.pdf", data);
        });
        t.SetApartmentState(ApartmentState.STA);
        t.Start();
    }

    private static byte[] DoRenderReport()
    {
        LocalReport localReport = new() { ReportPath = PathOfReport };
        // Blocks both at GetParameters() and localReport.Render()
        //localReport.GetParameters();
        return localReport.Render("PDF", DeviceInfo);
    }
}

And I call it in Startup-Method of service:

Test.TestReport("AutoPrintTest_Service", instantiateSciChart: true); // or false to succeed

I create and test the service using sc create.

I expect that a pdf-file is generated in the output-path, but this does only work if no SciChart is instantiated. Otherwise the service hangs. When stopping the service, a process of the service keeps actually running, which needs to be terminated.

Maybe I am missing something, like some configuration for the windows service. Any help is very appreciated, thanks a lot!

1

There are 1 best solutions below

6
Nick On

This will not work in a Windows service application. Service applications do not have an interactive user session and cannot use GDI. Quote:

Services have always run in session 0. Before Windows Vista, the first user to log on was also assigned to session 0. Now, session 0 is reserved exclusively for services and other applications not associated with an interactive user session. (The first user to log on is connected to session 1, the second user to log on is connected to session 2, and so on.) Session 0 does not support processes that interact with the user. This change means that a service cannot post or send a message to an application and an application cannot send or post a message to a service. In addition, services cannot display a user interface item such as a dialog box directly. A service can use the WTSSendMessage function to display a dialog box in another session. (https://learn.microsoft.com/en-us/windows/win32/services/service-changes-for-windows-vista)

You need an application that runs under the currently logged user, but there can be none such user, if no user has logged on to the system.

You must find a way to delegate this work to an interactive application that works when the user is logged in, or find an alternative reporting tool, which does not rely on WPF / GDI.