 |
|
 |
Are you aware of any print drivers/processors for windows that could accept a PDF over LPR. The drivers I am using (HP drivers) throw two errors before dropping it from the queue:
Failed to set information to the print job received from client at IP address 10.0.12.214. The specified datatype is invalid.
Failed to set data type 'TEXT' to the print job received from...
So they obviously do not recognize the PDF format. Any ideas?
|
|
|
|
 |
|
 |
Nevermind. It seems to be the way this code is encoding the data. I'll have to look more closely but when I use the command line LPR.exe util in binary mode, it works just fine.
|
|
|
|
 |
|
 |
I love this article because it is very close as I'm looking for.
I'd like to know if is it possible to use as a webservice, where an application will get the response of one webpage, and then, will print a page without user commands ?
Thanks in advance,
Best regards
|
|
|
|
 |
|
 |
Hi Malukinho,
Don't know your requirements in detail but to keep things nicely separated I propose to make one class that generates the file to be printed. When the file is generated it can be offered to the LPR class. Similar to the thread "Printing contents of a textbox to a Network printer using ASP.net" just below.
If you don't have high performance requirements you can store the file as a temporary file and use the LPR class to print it. Note that most of the time the speed of the printer will be the performance bottleneck. This way you can use the LPR client class just as is.
If you need more performance the class should be rewritten so it exposes lower level methods so you can open the printer, fill a buffer, send, ...., and close printer yourself.
Hopes this helps,
regards,
Rob Tillaart
|
|
|
|
 |
|
 |
Hi Rob,
The class was excellent it works great for a windows application. Can you please help me implement it for a web application. The Description for the Project i'm doing is as below:
I have to print a label to a Datamax printer by a ASP.Net web application (C#). The contents to be printed will be given in a Text box.
The Datamax label printer is a Network shared printer whose IP address is known to the web application Developer.
The Web application should use this IP address to communicate to the printer, so that later when the printer is changed we need to change only the IP address in the Web app.
Any one in the network who opens this web application and clicks Print should be able to print a label to that particular printer without any change in printer settings or any installations.
It is a single web application no extra forms can be added.
Kindly Help me in this issue.
Thanks in Advance
|
|
|
|
 |
|
 |
Hi Member4088318,
Excuses for the long delay for the answer. Many threads ask for high priority
The simplest way to solve the problem is to store the text to print in a temporary file and print this file. This could also be part of the printer class. I have made a first implementation which stores the text in a file with a random name to minimize the chance of collisions. Then this temporary file is printed as usual. Because it is a temporary file I give the flag deleteafterprint the value true. Setting this flag to false may help to debug it.
Just include the code snippet below in the printer class. Change the value of temppath to fit your need & system. Temppath should be a property of the printer class ...
public void LPRtext(string text)
{
Random r = new Random();
string temppath = @"C:\";
string fn = temppath + "lpr" + r.Next(999999999).ToString();
StreamWriter sw = new StreamWriter(fn);
sw.Write(text);
sw.Close();
LPR(fn, true);
}
Hopes this solves your need.
regards,
rob
|
|
|
|
 |
|
 |
First off, thank you for the code--it's an excellent LPR implementation.
Any idea how to implement a "real" status request (i.e. query the printer for current state, errors, etc.) Perhaps I missed this in RFC 1179.
Thanks.
Michael Shearer
|
|
|
|
 |
|
 |
Hi Michael,
In RFC 1179 there is no printer state defined, only the queue state by means of the LPQ (short or long) command. The data and its formatting LPQ returns is not specified. This makes it hard to parse output from different printers or devices behaving like printers e.g. print server (windows/linux/..), fax server etc.
My preferred way to interrogate printers about their state is SNMP (Simple Network Management Protocol) and to use the printer Mib RFC 3805 (replaces 1759). With this one can see if the device is idle or running or in error, also the number of papertrays and the amount of paper in them can be requested. But be aware that this only works for printers that support the printer MIB. Note that some printers support the PM partially.
There are several articles about using SNMP in C# e.g. http://www.codeproject.com/useritems/SNMPDLL.asp[^].
Additional to SNMP one can use the PING command to see if the printer is reachable in the first place.
Succes,
Rob Tillaart
|
|
|
|
 |
|
 |
Your code was really great!
but, in my work, i have to print in text mode only (just send txt file to the printer).
can you give me some comment?
ps. sorry if this is the stupid question.
thx in adv
vinai
-:I'm a really Newbie:-
|
|
|
|
 |
|
 |
Hi Vinai,
Look for the follow piece of code in the file lprdemo.cs: (approx line 250)
void Button1Click(object sender, System.EventArgs e)
{
if ((HostName.Text == "") || (QueueName.Text == "") || (UserName.Text == ""))
{
MessageBox.Show("Please fill in host, queue and username");
return;
}
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
textBox1.Text = DateTime.Now.ToString() + " busy";
Printer printer1 = new Printer(HostName.Text,QueueName.Text,UserName.Text);
printer1.LogFile = @"c:\lpr.log";
string fname = openFileDialog1.FileName;
if (fname.EndsWith(".ps") || fname.EndsWith(".pdf"))
{
printer1.LPR(fname, false);
textBox1.Text = DateTime.Now.ToString();
textBox1.Text += printer1.ErrorMsg;
}
else
{
// error message
textBox1.Text = "File does not end with .ps or .pdf.";
}
}
}
Change the line that tests the extention:
if (fname.EndsWith(".ps") || fname.EndsWith(".pdf"))
in
if (fname.EndsWith(".ps") || fname.EndsWith(".pdf") || fname.EndsWith(".txt"))
and you can select *.txt files too and print them. You can also restrict the LPR client to ".txt" only. Then the line should become:
if (fname.EndsWith(".txt"))
Except for the end of the name you could also restrict files to be printed in other ways. E.g. you could only restrict printing to filenames matching some regular expression, or if the files are at least 2 days old, have a filesize > 0, etc.
You should also edit the errormessage. In theory you can send all filetypes by means of the LPR client (adapt changes of Karl Fleishman for binary files, see forum) but be aware that the receiving device should support the fileformat. There are PostScript printers that does not support .txt. Printers that support PCL will print .txt files as plain text is a subset of PCL.
Succes,
Rob
PS, There exist no stupid questions only stupid answers
|
|
|
|
 |
|
 |
Hi Rob,
Can you also through some light how to write the server side of the code as well.
jayprakashshetty@hotmail.com
CANADA
|
|
|
|
 |
|
 |
Hi Jay,
Sorry it took some time to answer. Currently I am busy writing a prototype of an LPD server and it will be posted as a separate article to CP soon. Do you need special functionality? Let me know and maybe I can include it.
regards,
Rob
|
|
|
|
 |
|
 |
Hi,
I have submitted my LPD article last week but something went wrong I guess as it appeared under another author's name. But nevertheless a prototype LPD daemon can be found here. Or search for "Line Printer Daemon in C#" or "LPD" and you will find it.
http://www.codeproject.com/csharp/_inePrinterDaemon.asp[^]
Regards,
Rob
|
|
|
|
 |
|
 |
I guess I'm missing something. Exactly which scenario I would want to use this code?
Regards,
Shital.
http://www.ShitalShah.com
|
|
|
|
 |
|
 |
Hi Shital,
The LPR class can be used when you want to send a print-ready file to a printer. This file can be a PostScript, PDF, PCL or even a txt file depending on the capabilities of the (network)printer. One might have created this file by means of the 'print to file' option in a printerdriver dialog.
With this class one could build a simple commandline tool that e.g. sends all PDF files in a directory (CD) to a printer.
The class can also be used when you generate the PostScript yourself from within your application. OK, with the current implementation you need to write the PostScript to a file first. A stream interface would be a very nice enhancement.
Major problem for the stream interface is that the size of the data file is unknown and therefor the SubCommand 3 'RECEIVE DATA FILE' cannot give a correct filesize as parameter. In this case one should give 0xFFFFFFFF as filesize, but some printers do not cope with this very well as they allocate memory for the datafile in one chunk => an alloc of 4GB => POOOF!!
A well known way to circumvent this problem is to make a local copy of the PostScript on disk first and only send the file to the printer when the stream is closed. Then the size is known and the memory problem does not occur. OK, when the PostScript file is very large the problem still exists, but these are rare. FYI the largest PostScript file I encountered was approx. 1.2 GB.
Hopes this answers your question,
Regards,
Rob Tillaart
|
|
|
|
 |
|
 |
Hey Rob, Great class, I'm using it quite a bit and it's been working great. However recently we experienced a problem with the byte streaming portion of the class. Here's what we discovered and how we worked around it.
It appears that if the file your trying to print has a byte that can't convert into a character the "while (br.PeekChar() > -1)" line in the LPD.Printer.SendFile() method will throw a "Conversion Buffer Overflow" exception. To work around this you can use the following code which is an alternative way to stream the bytes over the NetworkStream without the conversion error. The commented code is the way it was originally.
// use BinaryReader as print files may contain non ASCII characters.
long totalbytes = 0;
int bytesRead=0;
byte[] buff = new Byte[2048];
FileStream fstream = new FileStream(fname, FileMode.Open);
while ( (readed=fstream.Read(buffer, 0, BUFSIZE)) > 0 )
{
totalbytes += bytesRead;
nws.Write(buffer, 0, bytesRead);
nws.Flush();
}
fstream.Close();
//FileStream fs = new FileStream(fname, FileMode.Open, FileAccess.Read);
//long totalbytes = 0;
//BinaryReader br = new BinaryReader(fs);
//while (br.PeekChar() > -1)
//{
// int n = br.Read(buffer, 0, BUFSIZE);
// totalbytes += n;
// nws.Write(buffer, 0, n);
// nws.Flush();
//}
//br.Close();
//fs.Close();
Here's the web page where we found the solution to this problem.
http://www.codecomments.com/message507645.html[^]
Have a Great Day!
www.karlfleischmann.com
It's better out here.
|
|
|
|
 |
|
 |
Hi Karl,
It is good to hear the project is used. As I used only text files I didn't encounter this problem.
Thanx for the patch, when I find some time I will update it in the source. Think the 'readed' variable in the while loop should be bytesRead otherwise no bytes are written. So it becomes:
long totalbytes = 0;
int bytesRead = 0;
byte[] buff = new Byte[2048];
FileStream fstream = new FileStream(fname, FileMode.Open);
while ( (bytesRead = fstream.Read(buffer, 0, BUFSIZE)) > 0 )
{
totalbytes += bytesRead;
nws.Write(buffer, 0, bytesRead);
nws.Flush();
}
fstream.Close();
Thanx again for the patch,
rob tillaart
|
|
|
|
 |
|
 |
It limits the size of lines with 80.
If I have a file which has some lines exceed 80 characters, it prints left of the line (after 80th chr.) into new line.
Is there any way that I can customize formats of the documents
-- modified at 14:47 Friday 21st April, 2006
|
|
|
|
 |
|
 |
Hi nkabiloglu,
Is this problem still unsolved?
I do not understand your problem in context of the LPR class as it does not truncate lines. However some applications like NotePad do truncate lines (wordwrap) in their window and therefor the lines will appear truncated when printed. Also some ascii to PostScript converters do this.
Which application do you use? Has it a wordwrap option?
You might try to 'debug' this problem by printing from the application to PostScript file and read it with GhostScript - GhostView. If lines are truncated on screen the problem lies in the application or the printerdriver and not in the printer or the LPR class.
Regards,
Rob Tillaart
|
|
|
|
 |
|
 |
This one seems to be missing a little. Like maybe the whole article.
Paul Kennedy
Father/Son/Husband/C Programmer
What else could you ask for?
|
|
|
|
 |
|
 |
Hi Paul,
The article is available at this moment, or are you still missing something?
I saw that the demo app must be updated as you cannot fill in the hostname and queuename in the app. Will try to fix this this weekend. I will save the old code in the My Mistakes folder
regards,
rob
|
|
|
|
 |
|
 |
Rob,
you probably need to bulk up the article with some insides on have the LPR protocol works (diagrams etc) and maybe show how you're code implements it.
Blogless
|
|
|
|
 |