473,473 Members | 1,963 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

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
Jul 21 '05 #1
1 5194
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

Jul 21 '05 #2

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

Similar topics

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...
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...
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...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 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 a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
0
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

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.