【问题标题】:How do you control printer tray selection for printer in Windows如何在 Windows 中控制打印机的打印机托盘选择
【发布时间】:2023-03-27 00:08:01
【问题描述】:

我们需要能够更改给定打印机的默认选择打印托盘。有没有人有 VC++/win32 代码来做这个?

如果这很重要,我相信我们必须更改打印机的默认设置。我们的打印作业由我们以外的应用程序执行,因此我们不能在源自我们应用程序内部的打印操作的上下文中进行此类更改。除非有某种方法可以在不同的应用程序中修改默认打印设置,否则我认为我们无法更改用户对打印机的默认设置,启动我们的打印作业,然后将默认设置恢复为原始值。

我们真的希望只为当前用户更改默认值,而不需要任何特殊的 UAC 提升等...

我怀疑它会使用类似于this MSDN article 中显示的内容,并涉及在 DEVMODE 结构中设置字段(dmDefaultSource 或 dmFormName 或两者)。

有接受者吗?或者有没有人想分享任何问题?

编辑:这是 DEVMODE 文档的链接DEVMODE documentation

编辑:我还应该指出,我们正在寻找一种通用的解决方案——而不是特定于特定打印机的解决方案(我们部署在很多很多环境中)

【问题讨论】:

    标签: windows visual-c++ printing


    【解决方案1】:

    仅供参考 - 我们最终使用的解决方案是捕获 DEVMODE 结构。我们有一个小型 win32 应用程序,它显示打印机设置对话框(通过 DocumentProperties 将 fMode 设置为 DM_IN_PROMPT)。然后将生成的 DEVMODE 保存到磁盘。当我们进行打印时,我们捕获当前的 DEVMODE,设置存储的 DEVMODE,启动打印,然后恢复原始的 DEVMODE。

    这实际上效果很好。有时,打印驱动程序会更新并导致存储的 DEVMODE 中断,但这并不经常发生,用户很容易修复。

    作为额外的奖励,这种方法允许我们捕获所有打印机设置(不仅仅是输出托盘) - 因此我们能够支持高级设置,如装订、分页等...

    提示:如果您尝试这样做,请确保将其作为二进制输出流写入磁盘。在我对这种方法的初步评估中,我不小心将输出流设置为文本输出流。在许多情况下事情会正常工作,然后突然中断某些打印机(在其 DEVMODE 私有数据中使用高位字节)。一个愚蠢但容易犯的错误 - 并且在一段时间内放弃了一个非常好的解决方案。

    【讨论】:

    • 我想您不会有兴趣扩展您的答案吗?您如何捕获当前的 DEVMODE?怎么换成存储的?
    • 当然 - 您使用具有不同 fMode 值的 DocumentProperties
    • 此链接有更多描述和一些示例 C# 代码。 nicholas.piasecki.name/blog/2008/11/…
    【解决方案2】:

    dmDefaultSource 控制托盘。不幸的是,您要设置的值因驱动程序而异,因为这是一个 bin 编号,不一定与打印机上打印的托盘编号相同。

    以下链接提供了一些 VB6 代码,用于收集有关打印机托盘/纸盒分配的信息。您可以使用该信息以编程方式将 dmDefaultSource 分配给托盘的相应 bin #。您基本上需要使用 DeviceCapabilities 返回有关您的打印机的信息,然后搜索一个字符串(如“Tray 1”)以获取相关的 bin 编号。

    http://support.microsoft.com/kb/194789

    【讨论】:

    • 这看起来很有希望 - 我会在我能上来试一试时回帖 - 谢谢!
    【解决方案3】:

    设置这样的功能可能会很棘手,尤其是在驱动程序不遵循 Microsoft 的打印指南的情况下。话虽如此,我们在 System.Drawing.Printing.PrinterSettings 方面取得了一些成功。您可以设置 PaperSource,但我不确定您是否可以设置默认值。

    如果您还没有看过这个例子,您可能想进一步了解它。它描述了一种存储和重新加载打印机设置的方法。我的一个人向我指出: PrinterSettings - Changing, Storing and Loading Printer Settings

    另一种可能有效但可能不适合您的方法是确定您需要的少数设置。安装具有这些(即:纸盘 1、纸盘 2)设置的打印机。然后只需在打印时切换默认打印机。不是您要找的东西,但它可能会有所帮助。

    在这些情况下,我们通常会做的是让第 3 方应用程序将数据写入我们正在监控的文件夹,然后我们自己提取文件并解析 Postscript 或 PCL,并更改纸盘,然后发送到目标设备。听起来要简单得多。

    【讨论】:

    • 这是与当前应用相关的设置的一个很好的参考。如果我的应用程序正在启动打印作业,它将完美运行。但是我们正在指示另一个应用程序启动打印作业,因此我们要么需要更改另一个应用程序中的设置,要么更改默认的系统范围设置。
    【解决方案4】:

    据我所知,打印机是由打印机驱动程序通过发送 SNMP 或 PJL 命令来控制的。但并非所有打印机都能完全实现这些命令集。

    对于 HP 打印机,我在 http://h20000.www2.hp.com/bizsupport/TechSupport/Document.jsp?lang=en&cc=us&objectID=bpl07282&jumpid=reg_R1002_USEN 找到了一些 PJL 命令(也有一些与托盘相关的命令)。

    我不确定这是否有帮助,但可以将其作为未来搜索的提示...

    【讨论】:

      【解决方案5】:

      我最近不得不在specific printer driver 上做一些非常类似的事情,它需要一个供应商特定的 SDK。托盘似乎没有出现在 DEVMODE 或任何其他 PRINTINFO_* 结构中,所以我想我会向打印机供应商发送一封电子邮件。

      作为最后的手段,我可​​以想到两种可能的黑客攻击。一种是使用诸如AutoIT 之类的脚本工具在GUI 级别自动化驱动程序。二是将注册表转储到文件,更改驱动设置,再次转储注册表,比较差异(可能有效,也可能无效)。

      【讨论】:

      • DEVMODE 有两个参数(dmDefaultSource 和 dmFormName)似乎可以控制托盘。我是否误解了这些成员控制的内容?
      猜你喜欢
      • 2017-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-28
      • 1970-01-01
      • 1970-01-01
      • 2013-11-08
      相关资源
      最近更新 更多