This article presents a printer class that supports the LPR print protocol in C#. With this class, it is possible to send a print file in ASCII, PostScript, PCL, et cetera, directly to a network printer or print server that communicates by means of the LPR (LPD) protocol. The printer class also implements the LPQ, the LPRM, and the Restart request.
The LPR/LPD protocol is a 15 year old print protocol from the TCP/IP suite that is still important in the area of network printers and print servers. It is described in detail in RFC 1179. Augmented variations of the protocol exist, like LPRNG also known as LPR Next Generation.
In an application, I needed to send PostScript files to an LPD enabled printer. It was possible to use the command line lpr.exe which is included in Windows but I didn't want to be dependant on lpr.exe, so I searched for a free C# implementation of LPR. As I could not find one, it was time to build such a class myself.
How to use the code
The printer class is straightforward. The constructor is called with three parameters, the hostname, the queue name, and the username. As these parameters are reused again and again with every LPR and LPQ request, I decided to place them in the constructor. Just a choice.
To print a file, one only needs to call LPR with the filename as argument, and to get the content of the spool queue, just call LPQ. The boolean parameter of LPQ indicates a long or small listing. The output format of LPQ depends on the implementation of the LPD daemon in the printer so there might be no difference.
So the core code to print a postscript file could look like:
if (openFileDialog1.ShowDialog() == DialogResult.OK)
LPD.Printer printer1 =
string fname = openFileDialog1.FileName;
textBox1.Text = printer1.LPQ(false);
Points of interest
To use the printer class, one should have a network printer with an LPD daemon, or start the TCP/IP Print Service on a computer (print server). Then, you can send files to any Windows printer defined on the computer. Use the PC name as hostname and the name of the printer as queue name. Be aware that the name of the printers may not contain spaces as the LPR/LPD protocol uses spaces as separators.
LPR does not wait until the file is printed, it starts a thread in the background for every file. LPQ and LPRM do not use a background thread.
The Restart method seems not to be supported in the Windows LPD daemon as I get no acknowledge. Nevertheless, I kept it in the code (use at own risk :).
Some things to improve the class include: (no deadline)
- improve error handling
- implement status and some other properties
- fix some todo's in the code
- overload LPR to print from a stream
- call back when file prints (e.g. for progress indicator)
- refactor ad fundum
- 2006/12/24 - Version 1.06 - Added some comments, a status string,
- 2006/12/24 - Version 1.03 - Added delete flag (thanks to Dion Slijp).
- 2006/11/09 - Version 1.02 - Patched code with remarks of Karl Fleischmann.
- 2006/01/14 - Version 1.01 - Added host, queue + user name to demo
- 2006/01/02 - Version 1.00 - published on CodeProject.
- 2006/01/02 - Version 0.96 - added Restart, fixed minor bugs, updated CP page.
- 2005/12/31 - Version 0.92 - added
WriteLog, added LPRM.
- 2005/12/30 - Version 0.90 - refactoring protocode, writing initial CP page.
- 2005/??/?? - started with the Printer class.
Everybody is granted to use this code as long as you refer to the original work, and I would appreciate that enhancements are published at CodeProject too.