C#程序动态设定打印选项 [Programmatically selecting complex printer options in C#]
来源:互联网 发布:手机网络助手 编辑:程序博客网 时间:2024/05/22 20:58
Programmatically selecting complex printer options in C#
We print out a full-color eight page customized flyer for every one of our orders. As soon as the order is done being processed, our internal processing application generates the flyer and shoots it off to one of the copier machines. The copier machine prints out the flyer (duplex), folds it, and staples it. This all happens silently and automatically; the employee does not have to twiddle with printer configuration or driver settings.
Getting this to happen automatically, however, was not easy. If you’re used to using thePrinterSettings and PrintDocument classes in Windows Forms, you’ll know that you have some options like a Duplex option available. But in our case, using that Duplex property seemed to make no difference in the printed output; the ol’ copier stubbornly went simplex every single time. It Simply Did Not Work. Not to mention that the .NET-native API doesn’t even begin to provide support for specifying paper folding, saddle stitching, and stapling. In a quest to find out how I could automate the selection of all these settings, I learned a bit more about printer drivers on Windows than I cared to know.
To get down and dirty with printer settings, I had to get familiar with DEVMODE. Being a .NET weenie who really doesn’t know his way around the Windows API very well, discovering this was progress; this structure exposes some of the options that I needed (such as collation), but it still didn’t provide any programmatic way to access folding and stapling settings.
Let’s go into the Printers section of the Control Panel and look at the Printing Preferences for one of these copiers. It turns out that this is a good way to be able to tell where a configuration setting lives. Some of the universal, standard settings are displayed on the “Layout” and “Paper/Quality” tabs. But if I want to get to any of the fancy features such as folding or stapling, well, they’re specific to our unique printer driver (and indeed, they’re exposed on a custom tab called “Fiery Printing” that the printer driver provides). There’s approximately zero documentation out there for configuring Fiery printer drivers programmatically, so how the hell was I going to communicate with this black box?
I’m not sure if my solution is genius, expected, or insane, but it’s been working for over a year now. The secret is a curious little member of the DEVMODE structure calleddmDriverExtra. MSDN has the following to say about this little member:
Contains the number of bytes of private driver-data that follow this structure. If a device driver does not use device-specific information, set this member to zero.
Private driver data, I thought. How interesting. It’s perfectly logical to assume that since the stapling and folding features are unique to this printer, then the configuration for those features is stored in some unknown format. That data lives in a block of memory at the end of the DEVMODE structure. The size of that block of memory is the value given in thedmDriverExtra field.
Here’s a crazy idea, I continued. What if I configured the default printer settings via the Printer Preferences pane in the Control Panel to the exact settings that I want the fliers to print with. Then, I’ll write a program that dumps the default DEVMODE structure and its private data for the printer to a file. Then, I can revert the default printer settings in the Control Panel back to normal.
When I want to print the flyer, I’ll just obtain the default DEVMODE, overwrite its spot in memory with the version that I had saved to disk, and then send the document to the printer. That way, I can specify those proprietary folding and stapling settings without actually knowing exactly how they’re defined in memory!
It turns out that this ended up working quite well. Obviously, things will blow up if we ever change the version of the printer driver that’s installed on the server (since they’ll probably have changed the layout of their private data section). Luckily, though, we don’t really plan on changing things once they’re working.
Dumping the DEVMODE
So, first I went into the Control Panel and selected the duplexing, folding, and stapling options that I wanted in the print driver-supplied tab. Then I ran a quick and dirty console application like the following (I swiped the P/Invoke version of DEVMODE from pinvoke.net:
Using the saved DEVMODE for printing
Now what do I do when I want to crank these suckers out? I just take my saved DEVMODE and overwrite the one that I get in memory when I’m about to print. It’s something like this:
Is it insane? Probably. But watching it duplex, fold, and staple automatically is great. I love it when something Simply Works!
- C#程序动态设定打印选项 [Programmatically selecting complex printer options in C#]
- Capture Options(捕获选项)各项的含义与设定
- How to Programmatically Add/Delete Custom Options in Magento? - See more at: http://apptha.com/blog/
- Source Code Printer-Visualize and Print out complex C source code on Paper
- 函数式选项模式编程 Functional Options Pattern in Go
- C#程序设定开机启动
- printer 如何打印颜色
- 用PRINTER打印DBGRID
- Printer Queue打印队列
- 打印队列(Printer Queue)
- Programmatically add credentials to an ASMX Web Service that is password protected in C#
- C# C/S程序使用HTML文件作为打印模板
- 一个c#打印程序
- C#简单打印程序
- 菜单选项 Options Menu
- 编译选项:MIPS Options
- HP-UX 使用SAM进行Printer设定
- 用printer对象打印表格
- CPU与内存频率匹配问题
- ARM指令集详解2
- C和ARM汇编混合编程
- ARM协处理器指令
- MYSQL5
- C#程序动态设定打印选项 [Programmatically selecting complex printer options in C#]
- ARM中SP,LR,PC使用(转载)
- Vijos P1841(转圈游戏-快速幂)
- TTL电路和CMOS电路的区别和…
- 上拉电阻的作用
- bootloader的具体介绍
- MMU的介绍
- 将博客搬至CSDN
- Linux系统补丁工具patch AND diff