我有一个应用程序,它使用一种方法来创建包括 SciChart-Control 的报告。这在 WPF 和控制台应用程序中都有效。 但是,当我需要在 Windows 服务中自动创建此类报告时,该服务似乎在调用报告方法时挂起。
二手包:
我想,如果我实际上在报告中包含 SciChart-Control 并不重要。重要的是,如果我在打印报告之前创建 SciChart-Control 的实例。 LocalReport.Render() 方法似乎会阻止进一步执行。
我创建了一个最小的工作示例,其中
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);
}
}
我在服务的启动方法中调用它:
Test.TestReport("AutoPrintTest_Service", instantiateSciChart: true); // or false to succeed
我使用
sc create
创建并测试服务。
我希望在输出路径中生成一个 pdf 文件,但这只有在没有实例化 SciChart 的情况下才有效。否则服务将挂起。停止服务时,服务的某个进程实际上还在运行,需要终止。
也许我遗漏了一些东西,比如 Windows 服务的一些配置。 非常感谢任何帮助,非常感谢!
这在 Windows 服务应用程序中不起作用。服务应用程序没有交互式用户会话,并且无法使用 GDI。引用:
服务始终在会话 0 中运行。在 Windows Vista 之前,第一个登录的用户也被分配给会话 0。现在,会话 0 专门为与交互式用户会话无关的服务和其他应用程序保留。 (第一个登录的用户连接到会话 1,第二个登录的用户连接到会话 2,依此类推。)会话 0 不支持与用户交互的进程。 此更改意味着服务无法向应用程序发送或发送消息,并且应用程序也无法向服务发送或发送消息。此外,服务无法直接显示用户界面项(例如对话框)。服务可以使用 WTSSendMessage 函数在另一个会话中显示对话框。 (https://learn.microsoft.com/en-us/windows/win32/services/service-changes-for-windows-vista)
您需要一个在当前登录用户下运行的应用程序,但如果没有用户登录到系统,则不能有这样的用户。
您必须找到一种方法将这项工作委托给一个在用户登录时工作的交互式应用程序,或者找到一个不依赖于 WPF / GDI 的替代报告工具。