1
public
class RawPrinterHelper
2 {
3
//
Structure and API declarions:
4
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
5
public
class DOCINFOA
6 {
7 [MarshalAs(UnmanagedType.LPStr)]
public
string pDocName;
8 [MarshalAs(UnmanagedType.LPStr)]
public
string pOutputFile;
9 [MarshalAs(UnmanagedType.LPStr)]
public
string pDataType;
10 }
11 [DllImport(
"
winspool.Drv
", EntryPoint=
"
OpenPrinterA
", SetLastError=
true, CharSet=CharSet.Ansi, ExactSpelling=
true, CallingConvention=CallingConvention.StdCall)]
12
public
static
extern
bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)]
string szPrinter,
out IntPtr hPrinter, IntPtr pd);
13
14 [DllImport(
"
winspool.Drv
", EntryPoint=
"
ClosePrinter
", SetLastError=
true, ExactSpelling=
true, CallingConvention=CallingConvention.StdCall)]
15
public
static
extern
bool ClosePrinter(IntPtr hPrinter);
16
17 [DllImport(
"
winspool.Drv
", EntryPoint=
"
StartDocPrinterA
", SetLastError=
true, CharSet=CharSet.Ansi, ExactSpelling=
true, CallingConvention=CallingConvention.StdCall)]
18
public
static
extern
bool StartDocPrinter( IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);
19
20 [DllImport(
"
winspool.Drv
", EntryPoint=
"
EndDocPrinter
", SetLastError=
true, ExactSpelling=
true, CallingConvention=CallingConvention.StdCall)]
21
public
static
extern
bool EndDocPrinter(IntPtr hPrinter);
22
23 [DllImport(
"
winspool.Drv
", EntryPoint=
"
StartPagePrinter
", SetLastError=
true, ExactSpelling=
true, CallingConvention=CallingConvention.StdCall)]
24
public
static
extern
bool StartPagePrinter(IntPtr hPrinter);
25
26 [DllImport(
"
winspool.Drv
", EntryPoint=
"
EndPagePrinter
", SetLastError=
true, ExactSpelling=
true, CallingConvention=CallingConvention.StdCall)]
27
public
static
extern
bool EndPagePrinter(IntPtr hPrinter);
28
29 [DllImport(
"
winspool.Drv
", EntryPoint=
"
WritePrinter
", SetLastError=
true, ExactSpelling=
true, CallingConvention=CallingConvention.StdCall)]
30
public
static
extern
bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount,
out Int32 dwWritten );
31
32
//
SendBytesToPrinter()
33
//
When the function is given a printer name and an unmanaged array
34
//
of bytes, the function sends those bytes to the print queue.
35
//
Returns true on success, false on failure.
36
public
static
bool SendBytesToPrinter(
string szPrinterName, IntPtr pBytes, Int32 dwCount)
37 {
38 Int32 dwError =
0, dwWritten =
0;
39 IntPtr hPrinter =
new IntPtr(
0);
40 DOCINFOA di =
new DOCINFOA();
41
bool bSuccess =
false;
//
Assume failure unless you specifically succeed.
42
43 di.pDocName =
"
My C#.NET RAW Document
";
44 di.pDataType =
"
RAW
";
45
46
//
Open the printer.
47
if( OpenPrinter( szPrinterName.Normalize(),
out hPrinter, IntPtr.Zero ) )
48 {
49
//
Start a document.
50
if( StartDocPrinter(hPrinter,
1, di) )
51 {
52
//
Start a page.
53
if( StartPagePrinter(hPrinter) )
54 {
55
//
Write your bytes.
56
bSuccess = WritePrinter(hPrinter, pBytes, dwCount,
out dwWritten);
57 EndPagePrinter(hPrinter);
58 }
59 EndDocPrinter(hPrinter);
60 }
61 ClosePrinter(hPrinter);
62 }
63
//
If you did not succeed, GetLastError may give more information
64
//
about why not.
65
if( bSuccess ==
false )
66 {
67 dwError = Marshal.GetLastWin32Error();
68 }
69
return bSuccess;
70 }
71
72
public
static
bool SendFileToPrinter(
string szPrinterName,
string szFileName )
73 {
74
//
Open the file.
75
FileStream fs =
new FileStream(szFileName, FileMode.Open);
76
//
Create a BinaryReader on the file.
77
BinaryReader br =
new BinaryReader(fs);
78
//
Dim an array of bytes big enough to hold the file's contents.
79
Byte []bytes =
new Byte[fs.Length];
80
bool bSuccess =
false;
81
//
Your unmanaged pointer.
82
IntPtr pUnmanagedBytes =
new IntPtr(
0);
83
int nLength;
84
85 nLength = Convert.ToInt32(fs.Length);
86
//
Read the contents of the file into the array.
87
bytes = br.ReadBytes( nLength );
88
//
Allocate some unmanaged memory for those bytes.
89
pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);
90
//
Copy the managed byte array into the unmanaged array.
91
Marshal.Copy(bytes,
0, pUnmanagedBytes, nLength);
92
//
Send the unmanaged bytes to the printer.
93
bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength);
94
//
Free the unmanaged memory that you allocated earlier.
95
Marshal.FreeCoTaskMem(pUnmanagedBytes);
96
return bSuccess;
97 }
98
public
static
bool SendStringToPrinter(
string szPrinterName,
string szString )
99 {
100 IntPtr pBytes;
101 Int32 dwCount;
102
//
How many characters are in the string?
103
dwCount = szString.Length;
104
//
Assume that the printer is expecting ANSI text, and then convert
105
//
the string to ANSI text.
106
pBytes = Marshal.StringToCoTaskMemAnsi(szString);
107
//
Send the converted ANSI string to the printer.
108
SendBytesToPrinter(szPrinterName, pBytes, dwCount);
109 Marshal.FreeCoTaskMem(pBytes);
110
return
true;
111 }
112 }
若要将这些类型和其他类型的原始数据发送到打印机中,您的代码必须使用 Win32 后台应用程序程序员接口 (api)。下面的代码演示如何以预先设好格式的文件的内容读入内存,然后通过使用 WritePrinter 将那些字节发送到打印机。
注: 不能使用这种方法相同的打印作业作为本机 PrintDocument 打印作业中。您必须使用.net 框架打印或发送您自己的打印作业字节。
1
//
Allow the user to select a file.
2
OpenFileDialog ofd =
new OpenFileDialog();
3
if( DialogResult.OK == ofd.ShowDialog(
this) )
4 {
5
//
Allow the user to select a printer.
6
PrintDialog pd =
new PrintDialog();
7 pd.PrinterSettings =
new PrinterSettings();
8
if( DialogResult.OK == pd.ShowDialog(
this) )
9 {
10
//
Print the file to the printer.
11
RawPrinterHelper.SendFileToPrinter(pd.PrinterSettings.PrinterName, ofd.FileName);
12 }
13 }
string s =
"
Hello
";
//
device-dependent string, need a FormFeed?
//
Allow the user to select a printer.
PrintDialog pd =
new PrintDialog();
pd.PrinterSettings =
new PrinterSettings();
if( DialogResult.OK == pd.ShowDialog(
this) )
{
//
Send a printer-specific to the printer.
RawPrinterHelper.SendStringToPrinter(pd.PrinterSettings.PrinterName, s);
}