2

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!

kef
  • 21
  • 3

1 Answers1

3

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.

Nick
  • 4,787
  • 2
  • 18
  • 24
  • Hi Nick, thanks for your quick reply, but I am not sure if your answer can be applied to my problem. If I understand that correctly, it would be sufficient to set the "Log on as" property of the service to my user account. This doesn't change the behavior of my test app. Apart from that, I do not send messages to other applications. Instantiating a Control with SciChart alone works, as well as rendering reports without using SciChart. I only get the problem when I combine those two, without even using scichart in the report. – kef Aug 08 '23 at 12:27
  • @kef, I am afraid setting the service to work under another user, i.e. "log on as", will not solve your problem. Your problem does not have a reliable solution. Again, you need an alternative reporting tool, which does not use GDI and WPF. – Nick Aug 08 '23 at 12:46
  • I understand that "log on as" will not solve my problem. But I don't understand why only the combination of those two lead to an error? Especially, since I can create any pdf-reports as long as I do not simply instantiate SciChart. Maybe you have a reference for me which explains the background? Thanks anyways! – kef Aug 08 '23 at 12:55
  • Hi there, scichart owner here – we can do generation of chart screenshots on a server (used to verify expected vs actual chart visual in unit tests), we had to instantiate this in a console application in a VM permanently logged on as user, not a window service for the exact same reasons. Windows services not only lose GDI but also any hardware acceleration. Limitations of technology! Perhaps a conversation with scichart team about the requirements? – Dr. Andrew Burnett-Thompson Aug 09 '23 at 14:05
  • Hi, appreciate your input very much. I will look out for a workaround, probably using our UI to automatically generate reports. It's not a killer feature, more of a nice-to-have request. – kef Aug 10 '23 at 08:34
  • Can @Nick 's answer be marked as accepted? Because I am still not convinced this alone is the reason (I do not interact with any user session), but it was definitely helpful for me and guided into the right direction. More out of curiosity, I played around with the services a bit. I was always able to print reports, or export scichart as an image, unless i combined those two inside the same service. – kef Aug 10 '23 at 08:39