473,378 Members | 1,439 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,378 software developers and data experts.

Solution: PrintToFile Shortcoming In The Printing / PrinterSettings Class - Hope It Helps You

BJS
Sorry for the cross-posting, but based on the number of people I have
seen ask for a solution to this problem, I hope by cross-posting this,
that it will help a lot of people out of a common problem.

Have you ever wanted to use print to a file using the
System.Drawing.Printing namespace only to find out that the only way
to do it is by popping a dialog box through the PrintDialog? What if
you want to print to file without user interaction, say in an
unattended application like a Windows Service or on a web server?
Well, according to the SDK documentation and KB article 820644, you
can't do it: "The PrinterSettings.PrintToFile property can only be set
by the System.Windows.Forms.Printing.PrintDialog class . . . for more
information, see the KB article 'PrintDocument Class Does Not
Implement The PrintToFile Feature (820644)'."

Many people have run into this problem. The newsgroups are full of
references to the issue, but there aren't many solutions. I needed
this functionality and I think I came up with a good solution. And
because I know other people have had this issue in the past, and
others will have it in the future, I figured I would share it with
everyone.

I wrote a simple multi-threaded listener that acts as a TCP/IP
printer. The output of the printer is directed to the listener, which
then saves the data to a file of your choosing. If you are interested
in getting the code, drop me an email.

Here is how it works:

1. Install a new TCP/IP printer port. Configure it to point to the IP
address of the machine where you will install the listener. Use port
9100 (the default.)
2. Install a postscript printer. Any of the ones that come with the OS
are fine. I needed color output that I could convert to Acrobat / PDF
using GhostScript, so I installed the HP Color LaserJet 8550-PS.
Configure the printer to use the port created in step 1.
3. Write your code and configure your PrintDocument object to print to
the printer created in step 2.
4. VERY IMPORTANT: Set the PrintDocument.DocumentName property to the
complete absolute file path of the file where you want the data to be
saved. This should include the file extension. It can be a UNC name if
you like. ex: C:\myoutputfile.prn or
\\MYSERVER\MYSHARE\myoutputfile.ps or whatever - just make sure it is
the complete file path and that the listener has permission to write
the location
5. Call the Print method of the PrintDocument object.
6. Handle the PrintPage event.
7. Compile your code
8. Start the listener.
9. Run your code.

That's it! Your document is spooled to printer driver specified in #2
by the framework. The printer driver then forwards the data over the
TCP/IP port specified in #1. The listener accepts the data being
forwarded by the driver and saves it to the file you specified in the
DocumentName property. Then you can whatever you need to do with the
outputed file.

The listener is implemented as a command line application, but it
could easily be modifed to run as a service. It is written in VB.NET.
It is multi-threaded and seems to work decently enough. Combined with
Ghostscript this is a great way of generating PDF documents on the fly
without any user interaction.

Caveats:

- It's a hack compared to Microsoft just including the damn
functionality in the framework to begin with - why they chose not to
expost that feature, I have no idea. It is obviously there in the
framework since PrintDialog uses it. grrr.
- Hasn't been tested too much
- Code isn't commented.
- Could use better error handling.
- No instrumentation, logging, or other status notifications.
- Only works with postscript printer drivers
- Contains a kludge: gets the location to which to save the file (that
you specified in the DocumentName property) using RegEx on the
%%Title: postscript comment (%% is comment indicator in postscript)
that is outputed with each postscript document. It's a potential that
not all PS drivers would output this information, but the couple that
I tested all worked. YMMV.

Obviously it would be better if this support was in the framework, but
it isn't. So this is a fairly decent (and free) solution as opposed to
some of the other ones that are possible alternatives: use unmanaged
GDI calls through PInvoke, use Office automation, use a local port
with a fixed file name, use Distiller, use FILE: and hire someone to
enter in the file name each time, etc.

If you'd like the code, drop me an email. It's free.

I'll send you a Zip file with the compiled command line application
and the VB.NET source code. You can play around with the source and
implement it in a different way if you like or just fire up the .exe
and starting printing.

Be sure to give me feedback. Let me know what you think.

Thanks,
Brian

hi*******@hotmail.com
Nov 20 '05 #1
1 2936
Sounds to me like a well thought out work around that could be used for may
purposes.

"BJS" <hi*******@hotmail.com> wrote in message
news:6c*************************@posting.google.co m...
Sorry for the cross-posting, but based on the number of people I have
seen ask for a solution to this problem, I hope by cross-posting this,
that it will help a lot of people out of a common problem.

Have you ever wanted to use print to a file using the
System.Drawing.Printing namespace only to find out that the only way
to do it is by popping a dialog box through the PrintDialog? What if
you want to print to file without user interaction, say in an
unattended application like a Windows Service or on a web server?
Well, according to the SDK documentation and KB article 820644, you
can't do it: "The PrinterSettings.PrintToFile property can only be set
by the System.Windows.Forms.Printing.PrintDialog class . . . for more
information, see the KB article 'PrintDocument Class Does Not
Implement The PrintToFile Feature (820644)'."

Many people have run into this problem. The newsgroups are full of
references to the issue, but there aren't many solutions. I needed
this functionality and I think I came up with a good solution. And
because I know other people have had this issue in the past, and
others will have it in the future, I figured I would share it with
everyone.

I wrote a simple multi-threaded listener that acts as a TCP/IP
printer. The output of the printer is directed to the listener, which
then saves the data to a file of your choosing. If you are interested
in getting the code, drop me an email.

Here is how it works:

1. Install a new TCP/IP printer port. Configure it to point to the IP
address of the machine where you will install the listener. Use port
9100 (the default.)
2. Install a postscript printer. Any of the ones that come with the OS
are fine. I needed color output that I could convert to Acrobat / PDF
using GhostScript, so I installed the HP Color LaserJet 8550-PS.
Configure the printer to use the port created in step 1.
3. Write your code and configure your PrintDocument object to print to
the printer created in step 2.
4. VERY IMPORTANT: Set the PrintDocument.DocumentName property to the
complete absolute file path of the file where you want the data to be
saved. This should include the file extension. It can be a UNC name if
you like. ex: C:\myoutputfile.prn or
\\MYSERVER\MYSHARE\myoutputfile.ps or whatever - just make sure it is
the complete file path and that the listener has permission to write
the location
5. Call the Print method of the PrintDocument object.
6. Handle the PrintPage event.
7. Compile your code
8. Start the listener.
9. Run your code.

That's it! Your document is spooled to printer driver specified in #2
by the framework. The printer driver then forwards the data over the
TCP/IP port specified in #1. The listener accepts the data being
forwarded by the driver and saves it to the file you specified in the
DocumentName property. Then you can whatever you need to do with the
outputed file.

The listener is implemented as a command line application, but it
could easily be modifed to run as a service. It is written in VB.NET.
It is multi-threaded and seems to work decently enough. Combined with
Ghostscript this is a great way of generating PDF documents on the fly
without any user interaction.

Caveats:

- It's a hack compared to Microsoft just including the damn
functionality in the framework to begin with - why they chose not to
expost that feature, I have no idea. It is obviously there in the
framework since PrintDialog uses it. grrr.
- Hasn't been tested too much
- Code isn't commented.
- Could use better error handling.
- No instrumentation, logging, or other status notifications.
- Only works with postscript printer drivers
- Contains a kludge: gets the location to which to save the file (that
you specified in the DocumentName property) using RegEx on the
%%Title: postscript comment (%% is comment indicator in postscript)
that is outputed with each postscript document. It's a potential that
not all PS drivers would output this information, but the couple that
I tested all worked. YMMV.

Obviously it would be better if this support was in the framework, but
it isn't. So this is a fairly decent (and free) solution as opposed to
some of the other ones that are possible alternatives: use unmanaged
GDI calls through PInvoke, use Office automation, use a local port
with a fixed file name, use Distiller, use FILE: and hire someone to
enter in the file name each time, etc.

If you'd like the code, drop me an email. It's free.

I'll send you a Zip file with the compiled command line application
and the VB.NET source code. You can play around with the source and
implement it in a different way if you like or just fire up the .exe
and starting printing.

Be sure to give me feedback. Let me know what you think.

Thanks,
Brian

hi*******@hotmail.com

Nov 20 '05 #2

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Meenakshi | last post by:
Hello everyone Can anybody help me out. i want to print two pages per single sheet. a book like printing. that is first page as well as last page of the document print on same side of the single...
1
by: BJS | last post by:
Sorry for the cross-posting, but based on the number of people I have seen ask for a solution to this problem, I hope by cross-posting this, that it will help a lot of people out of a common...
9
by: Jody Gelowitz | last post by:
I am trying to find the definition of "Safe Printing" and cannot find out exactly what this entitles. The reason is that I am trying to print contents from a single textbox to no avail using the...
4
by: manofbluz | last post by:
I have two complex Word templates that also contain some Bookmarks for receiving database data dynamically. I'm using Word automation code within VB.NET to manipulate the template. I don't need to...
3
by: RBisch | last post by:
I am finding that some of the properties off of the PrinterSettings object are misleading For example, When I test the CanDuplex on a printer I know duplexes, the property is false. Another one...
1
by: NickB | last post by:
Please could someone tell me what is wrong. Ther error is: An unhandled exception of type 'System.NullReferenceException' occurred in microsoft.visualbasic.dll Additional information: Object...
3
by: DJ Pomeroy | last post by:
I just can't seem to get it... I have a form. On this form is a panel. In this panel is a bunch of objects - graphics, text, and so on. I want to be able to print what's in the panel to a...
4
by: MLM450 | last post by:
I have an unmanaged C++ program that displays a printer dialog and then asks my C# program to perform the printing operation. What printer info do I pass to my C# program? It looks like I need...
4
by: sachin | last post by:
Hi I am working on report using print preview dialog control in windows application. Report is displayed properly in control. With paper size 850X1350 (Legal)(Lanscape mode=true) . But when...
7
by: Iain Wilson | last post by:
I am pulling my hair out trying to print various objects from a .net web page My apologies for cross posting but I need an answer and my previous post has attracted no interest. ASP.Net 2.0...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.