从.NET服务打印

时间:2008-08-11 17:37:27

标签: c# .net windows-services printing

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

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

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

感谢所有帮助。

编辑:我们使用的是.NET框架的2.0版本。

11 个答案:

答案 0 :(得分:13)

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

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

答案 1 :(得分:9)

从Windows服务打印真的很痛苦。它似乎有效......有时候......但最后它不时会出现异常情况或没有任何明确原因。这真的没有希望了。正式地说,它甚至是not supported,没有任何解释,也没有提出替代解决方案的建议。

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

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

答案 2 :(得分:6)

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

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

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

答案 3 :(得分:4)

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

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

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

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

答案 4 :(得分:3)

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

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

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

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

答案 5 :(得分:1)

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

  1. 创建一个单独的WPF应用程序(因此我可以使用内置文档处理)
  2. 使服务能够与桌面交互(请注意,您实际上不必在桌面上显示任何内容,或登录以使其工作)
  3. 让服务运行应用程序,并为其提供要打印的数据。
  4. 您可能还可以通过从服务运行的Web浏览器进行打印(虽然我建议您构建自己的shell IE,而不是使用完整的浏览器)。

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

答案 6 :(得分:1)

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

答案 7 :(得分:1)

如果您可以输出到帖子脚本,某些打印机会打印任何FTP到其上某个目录的内容。

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

答案 8 :(得分:0)

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

答案 9 :(得分:0)

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

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

答案 10 :(得分:0)

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