Click here to Skip to main content
Click here to Skip to main content

Reading Data Directly from the Printer

By , 13 Jun 2006
 

Sample Image

Introduction

This code will help you to directly fetch information from a network printer using the Printer Job Language. Here, you will have to provide the IP address of your printer and connect to the printer. Once done, you can send commands and retrieve information from the printer directly without using the Windows Spooler. This article will help you in knowing the basics about how to get configuration information, change printer settings, page count, status, toner level etc. from the printer directly.

Background

It started when a need aroused in my organization for some project where we wanted to get the settings and status of a printer directly from the printer, without the use of the Windows Spooler as it has many drawbacks. Also, the accuracy of data is not satisfactory when using the Windows Spooler. So a need aroused to look for different options. At that time, I came to know about this language called PJL (Printer Job Language) which is supported by almost all printer brands in the market. During that time, I wrote this code as an experiment to test its feasibility for implementation. My greatest inspiration behind this code was: Fun With C# and HP Laserjets, which had a funny code written which changes the display message on the printer screen.

Using the code

To understand the code and to execute it, you must have a basic knowledge about IP addresses, socket programming, and PJL (Printer Job Language). You can get the technical reference manuals for PJL from the links given below:

Follow these steps in order to execute this code properly:

  • Enter the IP address of the printer in the textbox provided.
  • Check the printer port number of your network computer and then change it. The default port number of a printer is 9100.
  • Press Connect. It will return no error messages if connected successfully, also the Close and Send Command buttons will be enabled.
  • Once connected, press on the Send Command button, and it will retrieve the printer configuration data and show it in textbox given below the Send Command button.
  • Do not forget to press the Close button once the execution is done, in order to close the connection, else it may happen sometimes that your connection will remain active and other users on the network won't be able to access the printer.

These are few of the PJL commands, and you can execute them one by one. Each command has a specific usage, and throws unique data from the printer. Also, you will have to learn the exact syntax of sending PJL commands to the printer else no data will be received. You can refer the functionality of all the commands from the links provided above.

sendString = String.Format("\x1B%-12345X@PJL INFO PAGECOUNT \r\n\x1B%-12345X\r\n");
sendString = String.Format("\x1B%-12345X@PJL INQUIRE" + 
                           " RESOLUTION \r\n\x1B%-12345X\r\n");
sendString = String.Format("\x1B%-12345X@PJL INQUIRE LPARM :" + 
                           " PCL PITCH \r\n\x1B%-12345X\r\n");
sendString = String.Format("\x1B%-12345X@PJL INFO USTATUS \r\n\x1B%-12345X\r\n");
sendString = String.Format("\x1B%-12345X@PJL INFO STATUS \r\n\x1B%-12345X\r\n");
sendString = String.Format("\x1B%-12345X@PJL INFO MEMORY \r\n\x1B%-12345X\r\n");
sendString = String.Format("\x1B%-12345X@PJL INFO FILESYS \r\n\x1B%-12345X\r\n");
sendString = String.Format("\x1B%-12345X@PJL " + 
                           "DINQUIRE LOWTONER \r\n\x1B%-12345X\r\n");
sendString = String.Format("\x1B%-12345X@PJL INFO CONFIG \r\n\x1B%-12345X\r\n");

Note: PJL can even be destructive; if not properly used, it may change the whole printer setting due to which the printer may give some weird results, and pages may not be printed properly.

Methods

I will give you a basic overview of all the methods in the order they are called.

Connect

The method named cmdConnect_Click is called on pressing the Connect button which tries to connect to the IP address provided, and on failure, it returns an exception message. If successful, then the WaitForData() method is called.

EnableCommands(true);
//Creating instance of Socket
m_socClient = new Socket (AddressFamily.InterNetwork, 
              SocketType.Stream ,ProtocolType.Tcp );

// retrieve the remote machines IP address
IPAddress ip = IPAddress.Parse (txtIPAddr.Text);
//A printer has open port 9100 which 
//can be used to connect to printer
int iPortNo = System.Convert.ToInt16 ( txtPort.Text);
//create the end point 
IPEndPoint ipEnd = new IPEndPoint (ip.Address,iPortNo);
//connect to the remote host
m_socClient.Connect ( ipEnd );
EnableCommands(false);
//wait for data to arrive 
WaitForData();

Wait For Data

The method named WaitForData() keeps on checking for data arrival from the connected port.

if  ( pfnCallBack == null ) 
{
    pfnCallBack = new AsyncCallback (OnDataReceived);
}
CSocketPacket theSocPkt = new CSocketPacket ();
theSocPkt.thisSocket = m_socClient;
// now start to listen for any data which arrives
m_asynResult = m_socClient.BeginReceive (theSocPkt.dataBuffer ,0, 
               theSocPkt.dataBuffer.Length, SocketFlags.None, 
               pfnCallBack,theSocPkt);

Send

The method named cmdSend_Click sends the PJL command to the connected printer after encoding it in the proper format.

string sendString;
sendString = String.Format("\x1B%-12345X@PJL" + 
                           " INFO CONFIG \r\n\x1B%-12345X\r\n");
Object objData = txtDataSend.Text;
byte[] byData = System.Text.Encoding.ASCII.GetBytes(sendString); 
m_socClient.Send (byData);

Receive

The method OnDataReceived is called as soon as the WaitForData method detects any incoming data, and then the received data is decoded and appended byte by byte and displayed in the data-received textbox.

CSocketPacket theSockId = (CSocketPacket)asyn.AsyncState ;
//creating object of the class

//end receive of data
int iReceive  = 0 ;
iReceive = theSockId.thisSocket.EndReceive (asyn);
char[] chars = new char[iReceive +  1];
//creating object for decoding
System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder();
int charLen = d.GetChars(theSockId.dataBuffer, 0, iReceive, chars, 0);
System.String szData = new System.String(chars);
txtDataReceive.Text = txtDataReceive.Text + szData;
//as data arrives the bytes are appended to the existing 
//string printer throws data in an ASCII format 1 byte at a time

WaitForData();

Close

The method cmdClose_Click closes the socket connection.

string sendString;
sendString = String.Format("\x1B%-12345X@PJL INFO " + 
                           "CONFIG \r\n\x1B%-12345X\r\n");

Object objData = txtDataSend.Text;
byte[] byData = System.Text.Encoding.ASCII.GetBytes(sendString);
m_socClient.Send (byData);

Points of Interest

It was great fun writing this code and I learnt many unknown characteristics of printers and Windows. I even wrote a small code which made our network printer go crazy: for every page which was being sent for printing, it printed 40 pages. I also learnt many things about the Windows Spooler which also uses a DLL called PJLMON.dll which has an inbuilt PJL command, INFO CONFIG, which gives all the details of a printer which you can see in the Control Panel Printers option.

Currently, I am trying to retrieve data from a printer connected to a local PC via parallel port. Many of my attempts were unsuccessful, but I am still trying. If anyone has any suggestions on it, please mail me at sandeepk31@yahoo.com.

History

This version only works on network printers and also lacks validation, which, if possible, I will implement in the next version.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

sandeep Kumtakar
Web Developer
India India
Member
I have done my Masters in Computer Application and currently working with an MNC as a software engineer.Working on .NET technology and Databases.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Questionwhere do I insert my new command jpl?memberblueobsession22 Mar '12 - 22:50 
but where can i insert my new command pjl? there is only command button
QuestionNo data being returned.memberbryan halterman28 Dec '11 - 11:18 
I've ran this straight from the download, but I'm not getting any return data. Frown | :( After i hit send, the program closes itself. Could this be because of differences in VC#2010 and .NET 4?
AnswerRe: No data being returned.membersandeep Kumtakar13 Feb '12 - 19:44 
Did you connect to network printer or a local Printer??? it wont work on local printer.
"Success is 1% Inspiration and 99% Perspiration"

GeneralNo data is recieved upon clicking Send Command buttonmembersk.sangita19 Oct '10 - 7:47 
I am able to connect to the printer Canon iR5050 PCL6 present in my network using the IP and port 9010. No data is displayed when i click on "Send Command". What could be the reason? How can i get it work?
GeneralRe: No data is recieved upon clicking Send Command buttonmemberbryan halterman28 Dec '11 - 11:19 
I'm having the same issue. Cry | :((
GeneralRe: No data is recieved upon clicking Send Command buttonmembersandeep Kumtakar13 Feb '12 - 19:45 
Hey have you verified the LED screen of printer if there the data is changing or not.
"Success is 1% Inspiration and 99% Perspiration"

QuestionHow to send PJL Commands to a local printer connected on a USB port or a COM Port ?memberrabii4 May '10 - 3:50 
Hello,
Thanks for this article. I want to ask, how shall i do to send PJL commands to a local printer connected on a USB port or a COM port?
Can a little modification in the code that has been posted over here lead me to communicate with this local printer.
 
Also, i would like to know if PJL commands will allow me to retreive the printer Serial Number ?
 
Thanks for your answers.
GeneralQuestionmember427748021 Mar '10 - 11:10 
Is it possible to get the user, computer name, ip, doucment info using this approach?
GeneralWorks greatmemberjellifer10 Feb '10 - 12:41 
This works great for what I'm doing - sending PCL data straight to the printer. Thanks a ton Smile | :)
GeneralToner levelmemberThomas Wopienka12 Nov '09 - 4:03 
Hello!
 
Your code is really helpful, but I couldn't find a way to query the remaining toner level in % from the printer.
Should the printer just give the information by using @PJL INFO CONFIG? I tried it with several HP printers but without success.
 
If PJL does not support querying the level - do you know any other way to get the level via USB?
 
Thank you for your help!
 
Thomas
GeneralNo information displayedmembermatusa_14022 Sep '08 - 0:16 
Hi, I have tested your program with Panasonic DP-265 PCL6 network printer.
 
The commection is OK (IP address and Port number are right) but not information are displayed when I click on send Command button.
 
Can you help me plaese!
Generalprint spoolermembermamtayg7 Sep '08 - 18:26 
Hi,
 
I need brief explanation on how print spooler service works. I know basics, but I need more advanced, in detail explanation answer. So I will ask same question, but also please include your own answers if you think that they are important.
 
1. When user send document to printer, what is happen?
2. I have noticed that some files are created in \system32\spool\printers folder. What about those files, which format is that, etc?
3. What is happening if user print same document again?
4. What is happening if user print another document again? (I have noticed that files are same in \printers folder)
5. When spooler service remove those files (from \printers folder)?
6. How OS act if you have more then one printer?
 
also give some source code so i can retrive printing information directly from print spooler.
 
Thanks!
GeneralReading data directly from printermembersnehal7773 Sep '08 - 23:27 
hi sandeep,
 

i used the code given in article but data is not fetch from printer.
give me some solution .
 
ganu
Question" No connection could be made because the target machine actively refuse it"membermamtayg2 Sep '08 - 1:28 
hi
 
i have problem in connecting with printer..
 
follwing error occurs when i presses a connect button.
 
ERROR -:
 
" No connection could be made because the target machine actively refuse it"
 

i already refer ur code which is given in codeproject site for reading data from print spooler...
 
plz help meee
 

thanks in advance..
 
mamta
GeneralPrinters acting using C#.netmemberbalu1234530 Jul '08 - 7:50 
Hi,
 
Iam developing an application/service for printers.The scenario is as follows
 
1. When a user selects a document and then he says the print command(no through my application...he selects normal print in file menu)then i have to catch some details like printername,no.of pages,document name..and so on...This action should be done before it get out from spooler.
 
2. As all of you that after printing data from spooler will be deleted..but in general for example for HP printer 3 files like lpr1234.tmp,shockwaveobject file ,.shd are generated. In this I have take take required files and keep them in my own spooler.

On my extensive search I came to know that by using WMI and WindowsAPI functions I can get to this goal...
 
But Iam unable to get into the right way....
If I have to use APIs then kindly tell what are the method I have to implement(if possible give me documentation link)
 
If through WMI....kindly guide me for the same
 
ALL these should be act as a service.....
 
thanks in Advance
GeneralGetting status Out-Of-Paper from USB PrintermemberDLauwers14 Feb '08 - 21:48 
Hello,
 
Nice article, any idea on how to get the Out-of-Paper status of an USB connected printer ? I need the realtime status, not the one from the print spooler, so I need to make a direct connection to the printer.
 
If it does not work via USB, would your code work to detect Out-of-paper of a network printer ?
 
Thanks
Danny
GeneralRe: Getting status Out-Of-Paper from USB Printermembersandeep Kumtakar14 Feb '08 - 23:27 
Go to this link : "http://lprng.sourceforge.net/DISTRIB/RESOURCES/DOCS/pjltkref.pdf"
There go to page 270 I suppose that part of this book will solve your purpose
 
Regards
Sandeep Kumtakar
 
"Success is 1% Inspiration and 99% Perspiration"

QuestionHow to reset printer?memberkvijayajyothy16 Dec '07 - 19:19 
i want to reset printer.
i want print cheques. i insert check in printer. the printer cursor should stay/reside in the first line (pay to ) and specified Column position. After each printing of cheque it should be placed in the same position( 1st line and 10th col). How to do this?
 
Thank you
vijaya

AnswerRe: How to reset printer? [modified]membersandeep Kumtakar14 Feb '08 - 23:11 
Your requirement can be solved using postscript language or there is one more language called as PCL (printer control language) but these languages are tough to understand.
 
There is a reset command in PJL u can use that to reset. You can use the PJL along with embedded code of PCL or Postscript to set what you want. I haven't tried the above things but I think this logic should work.
 
Regards
Sandeep Kumtakar
 
"Success is 1% Inspiration and 99% Perspiration"
modified on Friday, February 15, 2008 5:17 AM

Generalsend commands to printermemberkatz4523 May '07 - 10:08 
I am trying to access the printers internal hard drive to upload some macros that are stored on the printer to my computer. how do i use this program to send the copmmands to the printer?
GeneralRe: send commands to printermembersandeep Kumtakar14 Feb '08 - 23:40 
There is a command in PJL called as FSDOWNLOAD which can be used to copy the files in to Printer drive. Try using this. For details download the pdf specified below and check page no 169.
"http://lprng.sourceforge.net/DISTRIB/RESOURCES/DOCS/pjltkref.pdf
 
I have attached a demo application in this post it is to be sent the same way.
 
Regards
Sandeep Kumtakar
 
"Success is 1% Inspiration and 99% Perspiration"

GeneralSending PJL commands to Printer using USB port and Reading data from PrintermemberRamWebReg18 Apr '07 - 2:51 
Smile | :) I need to send PJL commands to printer and read some data from USB printer. Any suggestion how do I do it?
 
Thanks
 
Thanks
 
Ram

GeneralRe: Sending PJL commands to Printer using USB port and Reading data from Printermembersandeep Kumtakar26 Apr '07 - 0:10 
If your printer supports two way communication and printer is PJL command compatible then you can send the commands to printer.
 

 
"Success is 1% Inspiration and 99% Perspiration"

GeneralZPLmemberjagger_mack11 Mar '07 - 21:19 
do you know how to read data from zebra printers
 
(",)

GeneralRe: ZPLmembersandeep Kumtakar26 Apr '07 - 0:06 
No i haven't tried anything on that printer but i know only this much that some PJL commands are supported by the Zebra printers
 
"Success is 1% Inspiration and 99% Perspiration"

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130523.1 | Last Updated 13 Jun 2006
Article Copyright 2006 by sandeep Kumtakar
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid