2008-08-11 109 views
19

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

  • 多页面打印将是一个非常头疼的问题。
  • 还是要用的PrintDocument打印内存流,这是在Windows服务不支持(虽然它可能工作 - 还没有得到那么远与原型还)
  • 如果对面来的变化数据,我有更改数据集以及数据被反序列化到的类。坏坏坏。

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

所有帮助表示赞赏。

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

回答

13

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

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

1

这可能不是你在找什么,但如果我需要做这个快速&脏,我会:

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

你也许也可以跳过这个从你从服务运行的web浏览器打印(虽然我建议你构建你自己的shell IE,而不是使用完整的浏览器)。

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

8

从Windows服务打印真的很痛苦。它似乎有效......有时候......但最终它不时地发生异常或抛出异常,没有任何明确的理由。这真的没有希望。正式的,这甚至是not supported,没有任何解释,也没有任何替代解决方案的建议。

最近,我一直面临的问题,并经过几次不成功的试验及尝试,我终于来了有两个可行的解决方案:

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

GDI +从未在服务环境中设计/测试过。这就是为什么它不起作用。你应该使用GDI和它的功能来绘制。请参阅此文档以查找等效的Win32调用:http://msdn.microsoft.com/en-us/library/aa302340.aspx#win32map_printingfunctions – Signcodeindie 2010-07-16 23:58:11

0

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

4

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

最好的选择是让服务存储数据并让用户启动的应用程序通过向服务请求数据来执行打印。或者是数据存储的常见位置,如数据库。

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

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

3

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

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

但是,如果您要下载PDF路径,最简单的方法是将PDF输出发送到支持直接PDF打印的打印机(许多现在可以)。在这种情况下,您只需将PDF发送到设备并将其打印出来。

另一种选择是启动Ghostscript,它应该免费为您的需要(检查许可证,因为他们有一些不同的版本,一些GNU,一些GPL等),并使用它内置的打印功能或只是转换为后记并发送到设备。我在服务应用程序中多次使用过Ghostscript,但不是一个巨大的粉丝,因为您基本上将会脱壳并执行一个命令行应用程序来执行转换。这就是说,这是一个稳定的应用程序,倾向于优雅地失败

5

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

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

您最大的长期头痛问题将是打印驱动程序。如果您在没有登录用户的情况下作为服务运行,某些打印驱动程序喜欢不时弹出对话框。当您的打印机没有墨粉时会发生什么?或缺纸?驱动程序可能会弹出一个永远不会被看到的对话框,并且会阻止打印机队列,因为没有人登录!

1

如果您可以输出到发布脚本,某些打印机将打印任何获取到FTP的特定目录。

我们用这个来获得我们大学给我们带来的打印信用,但是如果你的服务输出到ps那么你可以把ps文件ftp到打印机。

0

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

我依然热衷于寻找的高质量报告,可以从Web服务器输出的好办法...

0

打印使用System.Drawing.Printing不被微软支持,按照晏Trevin的回应。但是,您可以使用基于WPF的新System.Printing(我认为)

1

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