如何在 Windows 中控制打印机的打印机托盘选择
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/165567/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you control printer tray selection for printer in Windows
提问by Kevin Day
We need to be able to change the default selected print tray of a given printer. Does anyone have VC++/win32 code for doing this?
我们需要能够更改给定打印机的默认选择打印托盘。有没有人有这样做的 VC++/win32 代码?
In case it matters, I believe we have to change the default setting for the printer. Our print jobs are executed by an application other than ours, so we can't make these kinds of changes in the context of a print operation originating from inside our application. Unless there is some way to modify the default print settings in a different application, I think we are stuck changing the user's defaults for the printer, initiating our print job, then setting the defaults back to the original values.
万一重要,我相信我们必须更改打印机的默认设置。我们的打印作业由不同于我们的应用程序执行,因此我们无法在源自应用程序内部的打印操作的上下文中进行这些类型的更改。除非有某种方法可以在不同的应用程序中修改默认打印设置,否则我认为我们无法更改用户的打印机默认值,启动我们的打印作业,然后将默认值设置回原始值。
We'd really prefer to have the defaults change for the current user only, and not require any special UAC elevation, etc...
我们真的希望只为当前用户更改默认值,而不需要任何特殊的 UAC 提升等...
I suspect that it will use something similar to what is shown in this MSDN article, and involve setting fields in the DEVMODE structure (either dmDefaultSource or dmFormName or both).
我怀疑它将使用类似于此 MSDN 文章中显示的内容,并涉及在 DEVMODE 结构中设置字段(dmDefaultSource 或 dmFormName 或两者)。
Any takers? Or does anyone have any gotchas they'd like to share?
有接班人吗?或者有人有什么要分享的问题吗?
EDIT: Here is a link for DEVMODE documentation DEVMODE documentation
编辑:这是 DEVMODE 文档DEVMODE 文档的链接
EDIT: I should also point out that we are looking for a general solution - not something specific to a particular printer (we deploy in many, many environments)
编辑:我还应该指出,我们正在寻找一个通用的解决方案——而不是特定于特定打印机的东西(我们部署在很多很多环境中)
采纳答案by Kevin Day
FYI - the solution we wound up using was to capture the DEVMODE structure. We have a small win32 app that presents the printer settings dialog (via DocumentPropertieswith fMode set to DM_IN_PROMPT). The resultant DEVMODE is then saved to disk. When we do our printing, we capture the current DEVMODE, set the stored DEVMODE, initiate the print, then restore the original DEVMODE.
仅供参考 - 我们最终使用的解决方案是捕获 DEVMODE 结构。我们有一个小的Win32应用程序,呈现打印机设置对话框(通过DocumentProperties与FMODE设置为DM_IN_PROMPT)。然后将生成的 DEVMODE 保存到磁盘。当我们进行打印时,我们捕获当前的 DEVMODE,设置存储的 DEVMODE,启动打印,然后恢复原始 DEVMODE。
This actually works quite well. Occasionally, the print drivers will update and cause the stored DEVMODE to break, but that doesn't happen very often and it's easy enough for users to fix.
这实际上效果很好。有时,打印驱动程序会更新并导致存储的 DEVMODE 中断,但这种情况并不经常发生,而且用户可以轻松修复。
As an extra bonus, this approach allows us to capture ALL of the printer settings (not just the output tray) - so we were able to support advanced settings like stapling, collating, etc...
作为额外的好处,这种方法允许我们捕获所有打印机设置(不仅仅是输出托盘) - 因此我们能够支持高级设置,如装订、整理等......
Tip: If you try this, be sure to write to disk as a binary output stream. In my initial evaluation of this approach, I accidentally set the output stream up as a text output stream. Things would work fine for many cases, then suddenly break for some printers (that used high order bytes in their DEVMODE private data). A dumb, but easy, mistake to make - and one that took a very nice solution off the table for awhile.
提示:如果您尝试此操作,请确保以二进制输出流的形式写入磁盘。在我对这种方法的初步评估中,我不小心将输出流设置为文本输出流。在许多情况下一切正常,然后突然中断某些打印机(在其 DEVMODE 私有数据中使用高位字节)。一个愚蠢但容易犯的错误 - 并且有一段时间从桌面上拿走了一个非常好的解决方案。
回答by Douglas Anderson
Setting features like this can be tricky, especially if the driver doesn't follow Microsoft's print guidelines. That being said, we've had some success with System.Drawing.Printing.PrinterSettings. You can set PaperSource but I'm not sure you can set the defaults.
设置这样的功能可能很棘手,特别是如果驱动程序不遵循 Microsoft 的打印指南。话虽如此,我们在 System.Drawing.Printing.PrinterSettings 方面取得了一些成功。您可以设置 PaperSource,但我不确定您是否可以设置默认值。
If you haven't seen this example you may want to look further at it. It describes a method to store and reload printer settings. One of my guys pointed it to me: PrinterSettings - Changing, Storing and Loading Printer Settings
如果你还没有看过这个例子,你可能想进一步了解它。它描述了一种存储和重新加载打印机设置的方法。我的一个人向我指出: PrinterSettings - 更改、存储和加载打印机设置
Another method, that could work but might not work for you, is to determine your the handful of setups you need. Install a printer with each of these (ie: Tray 1, Tray 2) setups. Then simply switch the default printer on print. Not what you are looking for but it may help.
另一种可能对您有用但可能对您不起作用的方法是确定您需要的少数设置。安装具有这些(即:纸盘 1、纸盘 2)设置的打印机。然后只需在打印时切换默认打印机。不是您正在寻找的,但它可能会有所帮助。
What we typically do in these situations is have the 3rd party app write the data to a folder that we are monitoring, we then pick up the file and parse the Postscript or PCL ourselves and change the paper tray and then send onto the destination device. A lot simpler then it may sound.
在这些情况下,我们通常做的是让第 3 方应用程序将数据写入我们正在监控的文件夹,然后我们拿起文件并自己解析 Postscript 或 PCL,更换纸盒,然后发送到目标设备。听起来可能要简单得多。
回答by Stimy
dmDefaultSource controls the tray. Unfortunately the values you'll want to set this to differs depending on your driver as this is a bin number and not necessarily the same number as the tray# printed on your printer.
dmDefaultSource 控制托盘。不幸的是,您希望将其设置为不同的值取决于您的驱动程序,因为这是一个 bin 编号,不一定与打印机上打印的托盘编号相同。
The following link provides some VB6 code for gathering information about your printers tray/bin assignments. You can use that information to programatically assign dmDefaultSource to the appropriate bin # for a tray. You basically need to use DeviceCapabilities to return information about your printers and then search for a string (like "Tray 1") to get the associated bin number.
以下链接提供了一些 VB6 代码,用于收集有关您的打印机托盘/垃圾箱分配的信息。您可以使用该信息以编程方式将 dmDefaultSource 分配给托盘的适当 bin #。您基本上需要使用 DeviceCapabilities 来返回有关您的打印机的信息,然后搜索一个字符串(如“Tray 1”)以获取相关联的 bin 编号。
回答by SmacL
I had to do something very similar recently on a specific printer driverand it required a vendor specific SDK. The tray doesn't seem to appear in DEVMODE or any of the other PRINTINFO_* structures so I guess I'd drop an email to the printer vendor.
我最近不得不在特定的打印机驱动程序上做一些非常相似的事情,它需要供应商特定的 SDK。托盘似乎没有出现在 DEVMODE 或任何其他 PRINTINFO_* 结构中,所以我想我会向打印机供应商发送电子邮件。
As a last resort, I can think of two possible hacks. One is to automate the driver at GUI level using a scripted tool such as AutoIT. Second is to dump the registry to file, change the driver setting, dump the registry again, and compare the differences (may or may not work).
作为最后的手段,我可以想到两种可能的黑客攻击。一种是使用诸如AutoIT 之类的脚本工具在 GUI 级别自动执行驱动程序。其次是将注册表转储到文件,更改驱动程序设置,再次转储注册表,然后比较差异(可能有效,也可能无效)。
回答by Citrone
As far as I know, printers are controlled by the printer driver by sending them SNMP or PJL commands. But not all printers implement completely these sets of commands.
据我所知,打印机是由打印机驱动程序通过向它们发送 SNMP 或 PJL 命令来控制的。但并非所有打印机都完全执行这些命令集。
For HP printers I found at: http://h20000.www2.hp.com/bizsupport/TechSupport/Document.jsp?lang=en&cc=us&objectID=bpl07282&jumpid=reg_R1002_USENsome PJL commands (there are some related to the tray too).
对于 HP 打印机,我在以下位置找到:http: //h20000.www2.hp.com/bizsupport/TechSupport/Document.jsp?lang=en&cc=us&objectID=bpl07282&jumpid = reg_R1002_USEN一些 PJL 命令(也有一些与托盘相关)。
I'm not sure this help, but take it as a hint for future searches...
我不确定这是否有帮助,但可以将其作为未来搜索的提示......