从.NET服务打印[关闭]
Posted
技术标签:
【中文标题】从.NET服务打印[关闭]【英文标题】:Printing from a .NET Service [closed] 【发布时间】:2010-09-05 16:45:57 【问题描述】:我现在正在处理一个项目,该项目涉及从另一个应用程序接收消息、格式化该消息的内容并将其发送到打印机。选择的技术是 C# windows 服务。我想,输出可以称为报告,但报告引擎不是必需的。一个简单的模板引擎,如 StringTemplate,甚至输出 html 的 XSLT 都可以。我遇到的问题是找到一种从服务打印这种输出的免费方法。因为它似乎可以工作,所以我正在使用 Microsoft 的 RDLC 制作原型,填充本地报告,然后将其作为图像呈现到内存流中,然后我将打印出来。问题是:
多页打印会很头疼。 仍然必须使用 PrintDocument 来打印内存流,这在 Windows 服务中不受支持(尽管它可能有效 - 原型还没有达到那么远) 如果遇到的数据发生变化,我必须更改数据集和数据反序列化到的类。很糟糕很糟糕。有没有人不得不远程做这样的事情?有什么建议吗?我已经发布了一个关于在没有用户输入的情况下打印 HTML 的问题,在浪费了大约 3 天之后,我得出的结论是它无法完成,至少不能使用任何免费提供的工具。
感谢所有帮助。
编辑:我们使用的是 .NET 框架的 2.0 版。
【问题讨论】:
【参考方案1】:相信我,与购买第三方组件相比,您将花费更多的钱来为此搜索/开发解决方案。不要重新发明***,而是选择付费解决方案。
打印是一个复杂的问题,我希望有一天能够为此添加更好的框架支持。
【讨论】:
【参考方案2】:从 Windows 服务打印真的很痛苦。它似乎工作......有时......但最后它不时崩溃或抛出异常,没有任何明确的原因。真是没救了。官方甚至是not supported,没有任何解释,也没有任何替代解决方案的建议。
最近,我遇到了这个问题,经过几次不成功的试验和实验,我终于有了两个可行的解决方案:
使用 Win32 API(例如在 C/C++ 中)编写您自己的打印 DLL,然后通过 P/Invoke 从您的服务中使用它(工作正常) 编写您自己的打印 COM+ 组件,然后从您的服务中使用它。我最近成功地选择了这个解决方案(但它是第三方 COM+ 组件,不是自己编写的)它也工作得很好。【讨论】:
GDI+ 从未被设计/测试为在服务环境中工作。这就是为什么它不起作用。您应该使用 GDI 和它的功能来绘制。请参阅此文档以查找等效的 Win32 调用:msdn.microsoft.com/en-us/library/… @Yann Trevin,我正在处理类似的要求,能否请您建议您使用了哪个第三方 COM+ 组件。会很棒【参考方案3】:我已经做到了。这是A *的痛苦。问题是打印需要 GDI 引擎就位,这通常意味着您必须拥有桌面,该桌面仅在您登录时加载。如果您尝试从服务器上的服务执行此操作,那么你通常没有登录。
因此,首先您不能以普通服务用户身份运行,而是以具有交互式登录权限的真实用户身份运行。然后你必须调整服务注册表项(我现在忘记了,如果你真的感兴趣,我必须找到今晚我可以做的代码)。最后,你必须祈祷。
您长期最头疼的问题是打印驱动程序。如果您在没有登录用户的情况下作为服务运行,则某些打印驱动程序喜欢不时弹出对话框。当您的打印机碳粉用完时会发生什么?还是缺纸?驱动程序可能会弹出一个永远不会看到的对话框,并因为没有人登录而阻塞了打印机队列!
【讨论】:
【参考方案4】:要回答您的第一个问题,这可能相当简单,具体取决于数据。我们有多种基于服务的应用程序可以完全满足您的要求。通常,我们解析传入的文件并将我们自己的 Postscript 或 PCL 包裹在它周围。如果您的布局相当简单,那么您可以使用一些非常基本的 PCL 代码对其进行包装,以提供您想要的字体/打印布局(我很乐意在此离线为您提供一些指导)。
如果您有打印就绪文件,您可以将其发送到共享的 UNC 打印机、直接发送到本地安装的打印机,甚至发送到设备的 IP(RAW 或 LPR 类型数据)。
但是,如果您要使用 PDF 路径,最简单的方法是将 PDF 输出发送到支持直接 PDF 打印的打印机(现在很多人都这样做了)。在这种情况下,您只需将 PDF 发送到设备并打印出来。
另一种选择是启动Ghostscript,它应该可以免费满足您的需求(检查许可,因为它们有几个不同的版本,一些 GNU,一些 GPL 等)并使用它内置的打印功能或简单地转换到 Postscript 并发送到设备。我在服务应用程序中使用过 Ghostscript 很多次,但不是一个忠实的粉丝,因为您基本上会使用并执行命令行应用程序来进行转换。话虽如此,它是一个稳定的应用程序,但往往会优雅地失败
【讨论】:
【参考方案5】:从服务打印是个坏主意。网络打印机是“按用户”连接的。您可以将服务标记为以特定用户身份运行,但我认为这是一种不好的安全做法。您也许可以连接到本地打印机,但在走这条路线之前我仍然会犹豫。
最好的选择是让服务存储数据并让用户启动的应用程序通过向服务请求数据来进行打印。或存储数据的公共位置,如数据库。
如果您需要定期打印数据,请通过任务计划程序设置任务事件。从服务启动进程需要知道用户名和密码,这又是一种不好的安全做法。
至于打印本身,使用第三方工具生成报告将是最简单的。
【讨论】:
【参考方案6】:这可能不是您想要的,但如果我需要快速而肮脏地进行此操作,我会:
-
创建一个单独的 WPF 应用程序(这样我就可以使用内置的文档处理)
为服务提供与桌面交互的能力(请注意,您实际上不必在桌面上显示任何内容,也无需登录即可使用)
让服务运行应用程序,并为其提供要打印的数据。
您可能还可以将其从您从该服务运行的网络浏览器中打印出来(尽管我建议您构建自己的 shell IE,而不是使用完整的浏览器)。
对于更详细(也是免费)的解决方案,您最好的选择可能是自己手动格式化文档(使用 GDI+ 为您进行布局)。这是乏味的、容易出错的、耗时的,并且在开发过程中会浪费大量的纸张,但也让您可以最大程度地控制打印机的内容。
【讨论】:
【参考方案7】:如果您可以输出到 post 脚本,一些打印机将打印任何通过 FTP 传输到其特定目录的内容。
我们用它来消除我们大学向我们公开的打印学分,但如果您的服务输出到 ps,那么您只需将 ps 文件 ftp 到打印机。
【讨论】:
【参考方案8】:我们正在使用DevExpress' XtraReports 从服务打印,没有任何问题。它们的报表模型类似于 Windows 窗体,因此您可以动态插入文本元素,然后发出打印命令。
【讨论】:
【参考方案9】:我认为我们将走第三方路线。我喜欢 XSL -> HTML -> PDF -> 打印机流程... Winnovative 的HTML to PDF 在第一部分看起来不错,但我遇到了一个寻找好的 PDF 打印解决方案的障碍...有什么建议吗?理想情况下,许可证将基于开发人员,而不是基于部署的运行时。
【讨论】:
【参考方案10】:在回答您有关 PDF 打印的问题时,我还没有找到一个优雅的解决方案。我正在向 Adobe 发出“shell”,这是不可靠的,并且需要用户始终登录。为了解决这个特定问题,我要求将我们处理的文件(发票)格式化为多页 Tiff 文件,而不是使用本机 .NET 打印功能进行拆分和打印。 Adobe 的立场似乎是“让用户在 Adobe Reader 中查看文件,他们可以点击打印”。没用。
我仍然渴望找到一种生成可以从网络服务器输出的高质量报告的好方法...
【讨论】:
【参考方案11】:根据 Yann Trevin 的回复,MS 不支持使用 System.Drawing.Printing 进行打印。但是,您也许可以使用新的、基于 WPF 的 System.Printing(我认为)
【讨论】:
以上是关于从.NET服务打印[关闭]的主要内容,如果未能解决你的问题,请参考以下文章
在 asp.net 核心服务器中处理关闭的 websocket 连接