Printing a PDF in c# using a stream ... can it be done ?

M

Microsoft News

Greetings community at large.

I have a c# app that generates a PDF file.
I have a printer that prints PDF natively.

But I cannot figure out how to programatically print in C# ... I can
generate the PDF as a file or a stream .. but cannot figure out how to send
either to the printer.

the only events I can use seem to be e.Graphics.DrawImage( ) or
e.Graphics.DrawString( )

is there a way to print a stream to a printer ? or a streamReader or
binaryStream ?

I thought that as a PDF is 'kind-of' a postscript file I could use
e.Graphics.DrawString( ) .. not surprisingly I got several pages of text ...

I can just drag and drop my PDF onto the printer it hops in the queue and
prints wonderfully ( no need to use acrobat reader to print) ..

Is perhaps this the way to go to 'programatically' push the file onto the
print queue ?

Regards.
 
J

JE

If you are looking to send a bitstream directly to a printer, use the
following code to open the port and print directly. The port can be
LPT1, COM1, etc or \\host\printershare.

using System;
using System.IO;
using System.Runtime.InteropServices;

[DllImport("Kernel32.dll")]
static extern IntPtr CreateFile(string filename,
[MarshalAs(UnmanagedType.U4)]FileAccess fileaccess,
[MarshalAs(UnmanagedType.U4)]FileShare fileshare, int
securityattributes, [MarshalAs(UnmanagedType.U4)]FileMode
creationdisposition, int flags, IntPtr template);

public static void PrintDirect(string port, byte[] doc){
FileStream fs = new FileStream(CreateFile(port, FileAccess.ReadWrite,
FileShare.ReadWrite, 0, FileMode.Create, 0, IntPtr.Zero),
FileAccess.ReadWrite);
fs.Write(doc,0,doc.Length);
fs.Close();
}
 
B

Bob

Thanks JE ... this looked quite hopeful .. when I pasted it in it compiles
and runs but doesnt seem to drive any printer.
I traced though it up to the fs.write( ) and doc is populated ..
what have I missed ????? at worst I hoped to get garbage out of the printer.

Below is my implimentation :

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;

namespace printing_directly_to_printer
{
class Program
{
[DllImport("Kernel32.dll")]
static extern IntPtr CreateFile(string filename,
[MarshalAs(UnmanagedType.U4)]FileAccess fileaccess,
[MarshalAs(UnmanagedType.U4)]FileShare fileshare, int
securityattributes, [MarshalAs(UnmanagedType.U4)]FileMode
creationdisposition, int flags, IntPtr template);

public static void PrintDirect(string port, byte[] doc)
{
FileStream fs = new FileStream(CreateFile(port,
FileAccess.ReadWrite,
FileShare.ReadWrite, 0, FileMode.Create, 0, IntPtr.Zero),
FileAccess.ReadWrite);
fs.Write(doc, 0, doc.Length);
fs.Close();
}

static void Main(string[] args)
{
string printerPort_Lexmark = "IP_10.254.1.90"; // ports
mapped on the local machine to the various printers
string printerPort_HPColor = "IP_10.254.1.11"; // the
lexmark will print PDF's natively, dont expect the HP
string printerPort_PDFCreator = "PDFCreator"; // to play
nicely .. but there for testing

FileStream myFS = new FileStream("c:\\document.pdf",
FileMode.Open, FileAccess.Read); // read in the PDF
BinaryReader myBR = new BinaryReader(myFS);

byte[] outData = new byte[myBR.BaseStream.Length];

for (int x = 0; x == myBR.BaseStream.Length; x++)
outData[x] = myBR.ReadByte();

PrintDirect(printerPort_Lexmark, outData);
}
}
}

regards Bob
 
B

Bob

Thanks Dave,

Yep I've seen these methods before ... they seem to require something to be
able to format the PDF and print it ... usually acrobat reader ... I'm
hoping that because I havea printer that can print PDF's natively I can
avoid this step and the various dark arts associated.

Acrpbat reader version 4 and below you could use and then be able to close
it afterwards but with the later version there is no easy way to shut down
acrobat reader once it has done its job.

cheers Bob
 
D

Dave Sexton

Hi,

I haven't tried using the Win32 APIs to do this myself, but here's a
reference that might help:

Printing and Print Spooler Functions
http://msdn2.microsoft.com/en-us/library/ms535737.aspx

I'm going to need this eventually too - if you figure something out that's
pretty simple, please post your findings. Thanks!

--
Dave Sexton
http://davesexton.com/blog
http://www.codeplex.com/DocProject (Sandcastle in VS IDE)

Bob said:
Thanks JE ... this looked quite hopeful .. when I pasted it in it compiles
and runs but doesnt seem to drive any printer.
I traced though it up to the fs.write( ) and doc is populated ..
what have I missed ????? at worst I hoped to get garbage out of the
printer.

Below is my implimentation :

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;

namespace printing_directly_to_printer
{
class Program
{
[DllImport("Kernel32.dll")]
static extern IntPtr CreateFile(string filename,
[MarshalAs(UnmanagedType.U4)]FileAccess fileaccess,
[MarshalAs(UnmanagedType.U4)]FileShare fileshare, int
securityattributes, [MarshalAs(UnmanagedType.U4)]FileMode
creationdisposition, int flags, IntPtr template);

public static void PrintDirect(string port, byte[] doc)
{
FileStream fs = new FileStream(CreateFile(port,
FileAccess.ReadWrite,
FileShare.ReadWrite, 0, FileMode.Create, 0, IntPtr.Zero),
FileAccess.ReadWrite);
fs.Write(doc, 0, doc.Length);
fs.Close();
}

static void Main(string[] args)
{
string printerPort_Lexmark = "IP_10.254.1.90"; // ports
mapped on the local machine to the various printers
string printerPort_HPColor = "IP_10.254.1.11"; // the
lexmark will print PDF's natively, dont expect the HP
string printerPort_PDFCreator = "PDFCreator"; // to play
nicely .. but there for testing

FileStream myFS = new FileStream("c:\\document.pdf",
FileMode.Open, FileAccess.Read); // read in the PDF
BinaryReader myBR = new BinaryReader(myFS);

byte[] outData = new byte[myBR.BaseStream.Length];

for (int x = 0; x == myBR.BaseStream.Length; x++)
outData[x] = myBR.ReadByte();

PrintDirect(printerPort_Lexmark, outData);
}
}
}

regards Bob

JE said:
If you are looking to send a bitstream directly to a printer, use the
following code to open the port and print directly. The port can be LPT1,
COM1, etc or \\host\printershare.

using System;
using System.IO;
using System.Runtime.InteropServices;

[DllImport("Kernel32.dll")]
static extern IntPtr CreateFile(string filename,
[MarshalAs(UnmanagedType.U4)]FileAccess fileaccess,
[MarshalAs(UnmanagedType.U4)]FileShare fileshare, int securityattributes,
[MarshalAs(UnmanagedType.U4)]FileMode creationdisposition, int flags,
IntPtr template);

public static void PrintDirect(string port, byte[] doc){
FileStream fs = new FileStream(CreateFile(port, FileAccess.ReadWrite,
FileShare.ReadWrite, 0, FileMode.Create, 0, IntPtr.Zero),
FileAccess.ReadWrite);
fs.Write(doc,0,doc.Length);
fs.Close();
}
 
B

Bob

Hi Dave,

well the solution to my problem was here
http://support.microsoft.com/default.aspx/kb/322091 Your posts plus EJ's
pointed me in the right direction.

This solution works for my printer as it can print PDF's ..

cheers Bob

Dave Sexton said:
Hi,

I haven't tried using the Win32 APIs to do this myself, but here's a
reference that might help:

Printing and Print Spooler Functions
http://msdn2.microsoft.com/en-us/library/ms535737.aspx

I'm going to need this eventually too - if you figure something out that's
pretty simple, please post your findings. Thanks!

--
Dave Sexton
http://davesexton.com/blog
http://www.codeplex.com/DocProject (Sandcastle in VS IDE)

Bob said:
Thanks JE ... this looked quite hopeful .. when I pasted it in it
compiles and runs but doesnt seem to drive any printer.
I traced though it up to the fs.write( ) and doc is populated ..
what have I missed ????? at worst I hoped to get garbage out of the
printer.

Below is my implimentation :

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;

namespace printing_directly_to_printer
{
class Program
{
[DllImport("Kernel32.dll")]
static extern IntPtr CreateFile(string filename,
[MarshalAs(UnmanagedType.U4)]FileAccess fileaccess,
[MarshalAs(UnmanagedType.U4)]FileShare fileshare, int
securityattributes, [MarshalAs(UnmanagedType.U4)]FileMode
creationdisposition, int flags, IntPtr template);

public static void PrintDirect(string port, byte[] doc)
{
FileStream fs = new FileStream(CreateFile(port,
FileAccess.ReadWrite,
FileShare.ReadWrite, 0, FileMode.Create, 0, IntPtr.Zero),
FileAccess.ReadWrite);
fs.Write(doc, 0, doc.Length);
fs.Close();
}

static void Main(string[] args)
{
string printerPort_Lexmark = "IP_10.254.1.90"; // ports
mapped on the local machine to the various printers
string printerPort_HPColor = "IP_10.254.1.11"; // the
lexmark will print PDF's natively, dont expect the HP
string printerPort_PDFCreator = "PDFCreator"; // to play
nicely .. but there for testing

FileStream myFS = new FileStream("c:\\document.pdf",
FileMode.Open, FileAccess.Read); // read in the PDF
BinaryReader myBR = new BinaryReader(myFS);

byte[] outData = new byte[myBR.BaseStream.Length];

for (int x = 0; x == myBR.BaseStream.Length; x++)
outData[x] = myBR.ReadByte();

PrintDirect(printerPort_Lexmark, outData);
}
}
}

regards Bob

JE said:
If you are looking to send a bitstream directly to a printer, use the
following code to open the port and print directly. The port can be
LPT1, COM1, etc or \\host\printershare.

using System;
using System.IO;
using System.Runtime.InteropServices;

[DllImport("Kernel32.dll")]
static extern IntPtr CreateFile(string filename,
[MarshalAs(UnmanagedType.U4)]FileAccess fileaccess,
[MarshalAs(UnmanagedType.U4)]FileShare fileshare, int
securityattributes, [MarshalAs(UnmanagedType.U4)]FileMode
creationdisposition, int flags, IntPtr template);

public static void PrintDirect(string port, byte[] doc){
FileStream fs = new FileStream(CreateFile(port, FileAccess.ReadWrite,
FileShare.ReadWrite, 0, FileMode.Create, 0, IntPtr.Zero),
FileAccess.ReadWrite);
fs.Write(doc,0,doc.Length);
fs.Close();
}
 
J

JE

Looks very good - I will definitely use this approach next time around.
We print a lot of raw stuff to our label printers and untill now the
..Net solution I used was similar to the old VB6 one we had before.

Hi Dave,

well the solution to my problem was here
http://support.microsoft.com/default.aspx/kb/322091 Your posts plus EJ's
pointed me in the right direction.

This solution works for my printer as it can print PDF's ..

cheers Bob

Dave Sexton said:
Hi,

I haven't tried using the Win32 APIs to do this myself, but here's a
reference that might help:

Printing and Print Spooler Functions
http://msdn2.microsoft.com/en-us/library/ms535737.aspx

I'm going to need this eventually too - if you figure something out that's
pretty simple, please post your findings. Thanks!

--
Dave Sexton
http://davesexton.com/blog
http://www.codeplex.com/DocProject (Sandcastle in VS IDE)

Bob said:
Thanks JE ... this looked quite hopeful .. when I pasted it in it
compiles and runs but doesnt seem to drive any printer.
I traced though it up to the fs.write( ) and doc is populated ..
what have I missed ????? at worst I hoped to get garbage out of the
printer.

Below is my implimentation :

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;

namespace printing_directly_to_printer
{
class Program
{
[DllImport("Kernel32.dll")]
static extern IntPtr CreateFile(string filename,
[MarshalAs(UnmanagedType.U4)]FileAccess fileaccess,
[MarshalAs(UnmanagedType.U4)]FileShare fileshare, int
securityattributes, [MarshalAs(UnmanagedType.U4)]FileMode
creationdisposition, int flags, IntPtr template);

public static void PrintDirect(string port, byte[] doc)
{
FileStream fs = new FileStream(CreateFile(port,
FileAccess.ReadWrite,
FileShare.ReadWrite, 0, FileMode.Create, 0, IntPtr.Zero),
FileAccess.ReadWrite);
fs.Write(doc, 0, doc.Length);
fs.Close();
}

static void Main(string[] args)
{
string printerPort_Lexmark = "IP_10.254.1.90"; // ports
mapped on the local machine to the various printers
string printerPort_HPColor = "IP_10.254.1.11"; // the
lexmark will print PDF's natively, dont expect the HP
string printerPort_PDFCreator = "PDFCreator"; // to play
nicely .. but there for testing

FileStream myFS = new FileStream("c:\\document.pdf",
FileMode.Open, FileAccess.Read); // read in the PDF
BinaryReader myBR = new BinaryReader(myFS);

byte[] outData = new byte[myBR.BaseStream.Length];

for (int x = 0; x == myBR.BaseStream.Length; x++)
outData[x] = myBR.ReadByte();

PrintDirect(printerPort_Lexmark, outData);
}
}
}

regards Bob

If you are looking to send a bitstream directly to a printer, use the
following code to open the port and print directly. The port can be
LPT1, COM1, etc or \\host\printershare.

using System;
using System.IO;
using System.Runtime.InteropServices;

[DllImport("Kernel32.dll")]
static extern IntPtr CreateFile(string filename,
[MarshalAs(UnmanagedType.U4)]FileAccess fileaccess,
[MarshalAs(UnmanagedType.U4)]FileShare fileshare, int
securityattributes, [MarshalAs(UnmanagedType.U4)]FileMode
creationdisposition, int flags, IntPtr template);

public static void PrintDirect(string port, byte[] doc){
FileStream fs = new FileStream(CreateFile(port, FileAccess.ReadWrite,
FileShare.ReadWrite, 0, FileMode.Create, 0, IntPtr.Zero),
FileAccess.ReadWrite);
fs.Write(doc,0,doc.Length);
fs.Close();
}
 
D

Dave Sexton

Hi Bob,

Great, thanks for posting the link.

--
Dave Sexton
http://davesexton.com/blog
http://www.codeplex.com/DocProject (Sandcastle in VS IDE)

Bob said:
Hi Dave,

well the solution to my problem was here
http://support.microsoft.com/default.aspx/kb/322091 Your posts plus EJ's
pointed me in the right direction.

This solution works for my printer as it can print PDF's ..

cheers Bob

Dave Sexton said:
Hi,

I haven't tried using the Win32 APIs to do this myself, but here's a
reference that might help:

Printing and Print Spooler Functions
http://msdn2.microsoft.com/en-us/library/ms535737.aspx

I'm going to need this eventually too - if you figure something out
that's pretty simple, please post your findings. Thanks!

--
Dave Sexton
http://davesexton.com/blog
http://www.codeplex.com/DocProject (Sandcastle in VS IDE)

Bob said:
Thanks JE ... this looked quite hopeful .. when I pasted it in it
compiles and runs but doesnt seem to drive any printer.
I traced though it up to the fs.write( ) and doc is populated ..
what have I missed ????? at worst I hoped to get garbage out of the
printer.

Below is my implimentation :

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;

namespace printing_directly_to_printer
{
class Program
{
[DllImport("Kernel32.dll")]
static extern IntPtr CreateFile(string filename,
[MarshalAs(UnmanagedType.U4)]FileAccess fileaccess,
[MarshalAs(UnmanagedType.U4)]FileShare fileshare, int
securityattributes, [MarshalAs(UnmanagedType.U4)]FileMode
creationdisposition, int flags, IntPtr template);

public static void PrintDirect(string port, byte[] doc)
{
FileStream fs = new FileStream(CreateFile(port,
FileAccess.ReadWrite,
FileShare.ReadWrite, 0, FileMode.Create, 0, IntPtr.Zero),
FileAccess.ReadWrite);
fs.Write(doc, 0, doc.Length);
fs.Close();
}

static void Main(string[] args)
{
string printerPort_Lexmark = "IP_10.254.1.90"; // ports
mapped on the local machine to the various printers
string printerPort_HPColor = "IP_10.254.1.11"; // the
lexmark will print PDF's natively, dont expect the HP
string printerPort_PDFCreator = "PDFCreator"; // to play
nicely .. but there for testing

FileStream myFS = new FileStream("c:\\document.pdf",
FileMode.Open, FileAccess.Read); // read in the PDF
BinaryReader myBR = new BinaryReader(myFS);

byte[] outData = new byte[myBR.BaseStream.Length];

for (int x = 0; x == myBR.BaseStream.Length; x++)
outData[x] = myBR.ReadByte();

PrintDirect(printerPort_Lexmark, outData);
}
}
}

regards Bob

If you are looking to send a bitstream directly to a printer, use the
following code to open the port and print directly. The port can be
LPT1, COM1, etc or \\host\printershare.

using System;
using System.IO;
using System.Runtime.InteropServices;

[DllImport("Kernel32.dll")]
static extern IntPtr CreateFile(string filename,
[MarshalAs(UnmanagedType.U4)]FileAccess fileaccess,
[MarshalAs(UnmanagedType.U4)]FileShare fileshare, int
securityattributes, [MarshalAs(UnmanagedType.U4)]FileMode
creationdisposition, int flags, IntPtr template);

public static void PrintDirect(string port, byte[] doc){
FileStream fs = new FileStream(CreateFile(port, FileAccess.ReadWrite,
FileShare.ReadWrite, 0, FileMode.Create, 0, IntPtr.Zero),
FileAccess.ReadWrite);
fs.Write(doc,0,doc.Length);
fs.Close();
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top