从.NET服务打印

我正在开展一个项目,涉及从另一个应用程序接收消息,格式化该消息的内容,并将其发送到打印机。 选择的技术是C#windows服务。 我想,输出可以称为报告,但不需要报告引擎。 一个简单的模板引擎,如StringTemplate,甚至XSLT输出HTML都可以。 我遇到的问题是找到一种免费的方式从服务中打印这种输出。 由于它似乎可以工作,我正在使用Microsoft的RDLC工作原型,填充本地报告,然后将其作为图像渲染到内存流,然后我将打印。 问题是:

  • 多页打印将是一个很大的问题。
  • 仍然必须使用PrintDocument来打印内存流,这在Windows服务中是不受支持的(尽管它可能有用 – 但还没有得到原型的那么多)
  • 如果数据发生变化,我必须更改数据集,以及数据被反序列化的类。 坏坏。

有没有人像这样远程做任何事情? 任何建议? 我已经提出了一个关于在没有用户输入的情况下打印HTML的问题,在浪费了大约3天之后,我得出的结论是,它无法完成,至少没有任何免费提供的工具。

所有帮助表示赞赏。

编辑:我们在.NET框架的2.0版本。

相信我,与购买第三方组件相比,您将花更多的钱尝试搜索/开发此解决方案。 不要重新发明轮子并采用付费解决方案。

打印是一个复杂的问题,我很想看到为此添加更好的框架支持的那一天。

从Windows服务打印真的很痛苦。 它似乎有效……有时候……但最后它不时会出现exception情况,但没有任何明确的理由。 这真的没有希望了。 正式地说,它甚至没有得到任何解释的支持 ,也没有任何替代解决方案的建议。

最近,我遇到了这个问题,经过几次不成功的试验和试验后,我终于找到了两个可行的解决方案:

  • 使用Win32 API编写自己的打印DLL(例如在C / C ++中),然后使用P / Invoke从服务中使用它(工作正常)
  • 编写自己的打印COM +组件,然后从您的服务中使用它。 我最近选择了这个解决方案成功(但它是第三方COM +组件,不是自己编写的)它的工作原理也一样。

我做到了 这是A * s的痛苦。 问题是打印需要GDI引擎到位,这通常意味着您必须拥有桌面,只有在您登录时才会加载。如果您尝试从服务器上的服务执行此操作,那么你通常没有登录。

因此,首先您不能作为普通服务用户运行,而是作为具有交互式登录权限的真实用户运行。 然后你必须调整服务注册表项(我忘了现在如果你真的感兴趣的话,必须找到我今晚可以做的代码)。 最后,你必须祈祷。

您最大的长期头痛将是打印驱动程序。 如果您在没有登录用户的情况下作为服务运行,则某些打印驱动程序会不时弹出对话框。 打印机墨粉用完后会发生什么? 还是没纸了? 驱动程序可能会弹出一个永远不会看到的对话框,并因为没有人登录而占用打印机队列!

从服务打印是个坏主意。 网络打印机“按用户”连接。 您可以将服务标记为以特定用户身份运行,但我认为这是一种糟糕的安全措施。 您可以连接到本地打印机,但在走这条路线之前我还是会犹豫不决。

最好的选择是让服务存储数据并让用户启动的应用程序通过向服务询问数据来进行打印。 或者是存储数据的公共位置,如数据库。

如果您需要定期打印数据,请通过任务计划程序设置任务事件。 从服务启动进程将需要知道用户名和密码,这也是不好的安全措施。

至于打印本身,使用第三方工具生成报告将是最简单的。

要回答您的第一个问题,根据数据,这可以相当直接。 我们有各种基于服务的应用程序,可以完全按照您的要求进行操作。 通常,我们解析传入的文件并在其周围包装我们自己的Postscript或PCL。 如果布局相当简单,那么有一些非常基本的PCL代码可以用它来包装它以提供你想要的字体/打印布局(我会更乐意在这里给你一些指导离线)。

您有一个打印就绪文件,您可以将其发送到共享的UNC打印机,直接发送到本地安装的打印机,甚至发送到设备的IP(RAW或LPR类型数据)。

但是,如果您要沿着PDF路径走,最简单的方法是将PDF输出发送到支持直接PDF打印的打印机(许多人现在都这样做)。 在这种情况下,您只需将PDF发送到设备并打印即可。

另一个选择是启动Ghostscript ,它应该是免费的,以满足您的需求(检查许可,因为它们有一些不同的版本,一些GNU,一些GPL等),并使用它的内置打印function或只是转换为Postscript并发送到装置。 我在服务应用程序中多次使用Ghostscript,但不是一个巨大的粉丝,因为你基本上会炮轰并执行命令行应用程序来进行转换。 话虽这么说,它是一个稳定的应用程序,往往优雅地失败

这可能不是你想要的,但如果我需要快速和肮脏,我会:

  1. 创建一个单独的WPF应用程序(所以我可以使用内置的文档处理)
  2. 使服务能够与桌面交互(请注意,您实际上不必在桌面上显示任何内容,或者登录以使其工作)
  3. 让服务运行应用程序,并给它打印数据。

您可能还可以通过从服务运行的Web浏览器进行打印(虽然我建议您构建自己的shell IE,而不是使用完整的浏览器)。

对于更详细(也是免费)的解决方案,您最好的选择可能是自己手动格式化文档(使用GDI +为您进行布局)。 这是繁琐,容易出错,耗时,并且在开发过程中浪费了大量纸张,但也使您能够最大程度地控制打印机的内容。

如果您可以输出到后期脚本,某些打印机将打印任何FTP到其上的某个目录。

我们使用它来超过我们大学公开的印刷学分,但是如果你的服务输出到ps那么你可以将ps文件ftp到打印机。

我们正在使用DevExpress的XtraReports从服务中打印而没有任何问题。 他们的报表模型类似于Windows窗体,因此您可以动态插入文本元素,然后发出打印命令。

我想我们将走第三方路线。 我喜欢XSL – > HTML – > PDF – >打印机流程…… Winnovative的HTML到PDF看起来对第一部分看起来不错,但我遇到了一个块,找到了一个好的PDF打印解决方案……有什么建议吗? 理想情况下,许可证将基于开发人员,而不是基于部署的运行时。

在回答有关PDF打印的问题时,我还没有找到一个优雅的解决方案。 我对Adobe的“shell”是不可靠的,并且要求用户始终登录。 为了解决这个特定的问题,我要求将我们处理的文件(发票)格式化为多页Tiff文件,而不是可以拆分并使用本机.NET打印function打印。 Adobe的立场似乎是“让用户在Adobe Reader中查看文件,他们可以点击打印”。 无用。

我仍然希望找到一种可以从Web服务器输出的高质量报告的好方法……

根据Yann Trevin的回复,MS不支持使用System.Drawing.Printing进行打印。 但是,您可以使用新的基于WPF的System.Printing(我认为