因为直接用PrintDocument.Pring()打印时,会出现一个"正在打印"的窗口,上面有一个取消按钮,用户一按回车就给取消了,该窗口又无法隐藏,故我想寻求其他方法,在CSDN上看到有人用下面的API方法实现打印:
using System;
using System.IO;
using System.Drawing.Printing;
using System.Runtime.InteropServices;namespace PrintTest
{
public class RawPrinterHelper
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DOCINFOW
{
[MarshalAs(UnmanagedType.LPWStr)]
public string pDocName;
[MarshalAs(UnmanagedType.LPWStr)]
public string pOutputFile;
[MarshalAs(UnmanagedType.LPWStr)]
public string pDataType;
} [DllImport("winspool.Drv", EntryPoint = "OpenPrinterW", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
public static extern bool OpenPrinter(string src, ref IntPtr hPrinter, long pd); [DllImport("winspool.Drv", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
public static extern bool ClosePrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterW", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
public static extern bool StartDocPrinter(IntPtr hPrinter, int level, ref RawPrinterHelper.DOCINFOW pDI); [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool EndDocPrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool StartPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool EndPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, int dwCount, ref int dwWritten); public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount)
{
IntPtr hPrinter = System.IntPtr.Zero;
Int32 dwError;
DOCINFOW di = new DOCINFOW();
Int32 dwWritten = 0;
bool bSuccess;
di.pDocName = "My Document";
di.pDataType = "RAW";
bSuccess = false;
if (OpenPrinter(szPrinterName, ref hPrinter, 0))
{
if (StartDocPrinter(hPrinter, 1, ref di))
{
if (StartPagePrinter(hPrinter))
{
bSuccess = WritePrinter(hPrinter, pBytes, dwCount, ref dwWritten);
EndPagePrinter(hPrinter);
}
EndDocPrinter(hPrinter);
}
ClosePrinter(hPrinter);
}
if (bSuccess == false)
{
dwError = Marshal.GetLastWin32Error();
}
return bSuccess; }
public static bool SendFileToPrinter(string szPrinterName, string szFileName)
{
FileStream stream1 = new FileStream(szFileName, FileMode.Open);
BinaryReader reader1 = new BinaryReader(stream1);
byte[] buffer1 = new byte[((int)stream1.Length) + 1];
buffer1 = reader1.ReadBytes((int)stream1.Length);
IntPtr ptr1 = Marshal.AllocCoTaskMem((int)stream1.Length);
Marshal.Copy(buffer1, 0, ptr1, (int)stream1.Length);
bool flag1 = RawPrinterHelper.SendBytesToPrinter(szPrinterName, ptr1, (int)stream1.Length);
Marshal.FreeCoTaskMem(ptr1);
return flag1; } public static void SendStringToPrinter(string szPrinterName, string szString)
{
IntPtr pBytes;
Int32 dwCount;
dwCount = szString.Length;
pBytes = Marshal.StringToCoTaskMemAnsi(szString);
SendBytesToPrinter(szPrinterName, pBytes, dwCount);
Marshal.FreeCoTaskMem(pBytes);
}
}
}
然后用下面的代码调用:
private void button1_Click(object sender, EventArgs e)
{
string sPrintStr = " test"; PrintDialog pd = new PrintDialog();
pd.PrinterSettings = new System.Drawing.Printing.PrinterSettings();
//if (pd.ShowDialog(this) > DialogResult.None)
//{
RawPrinterHelper.SendStringToPrinter(pd.PrinterSettings.PrinterName, sPrintStr);
//}
}
但运行时出现下面的错误:对 PInvoke 函数“PrintTest!PrintTest.RawPrinterHelper::OpenPrinter”的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。大家能否帮忙解决一下啊,或者隐藏掉printdocument.print()中的显示打印过程的窗口.
顶者有分.
using System;
using System.IO;
using System.Drawing.Printing;
using System.Runtime.InteropServices;namespace PrintTest
{
public class RawPrinterHelper
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DOCINFOW
{
[MarshalAs(UnmanagedType.LPWStr)]
public string pDocName;
[MarshalAs(UnmanagedType.LPWStr)]
public string pOutputFile;
[MarshalAs(UnmanagedType.LPWStr)]
public string pDataType;
} [DllImport("winspool.Drv", EntryPoint = "OpenPrinterW", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
public static extern bool OpenPrinter(string src, ref IntPtr hPrinter, long pd); [DllImport("winspool.Drv", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
public static extern bool ClosePrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterW", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
public static extern bool StartDocPrinter(IntPtr hPrinter, int level, ref RawPrinterHelper.DOCINFOW pDI); [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool EndDocPrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool StartPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool EndPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, int dwCount, ref int dwWritten); public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount)
{
IntPtr hPrinter = System.IntPtr.Zero;
Int32 dwError;
DOCINFOW di = new DOCINFOW();
Int32 dwWritten = 0;
bool bSuccess;
di.pDocName = "My Document";
di.pDataType = "RAW";
bSuccess = false;
if (OpenPrinter(szPrinterName, ref hPrinter, 0))
{
if (StartDocPrinter(hPrinter, 1, ref di))
{
if (StartPagePrinter(hPrinter))
{
bSuccess = WritePrinter(hPrinter, pBytes, dwCount, ref dwWritten);
EndPagePrinter(hPrinter);
}
EndDocPrinter(hPrinter);
}
ClosePrinter(hPrinter);
}
if (bSuccess == false)
{
dwError = Marshal.GetLastWin32Error();
}
return bSuccess; }
public static bool SendFileToPrinter(string szPrinterName, string szFileName)
{
FileStream stream1 = new FileStream(szFileName, FileMode.Open);
BinaryReader reader1 = new BinaryReader(stream1);
byte[] buffer1 = new byte[((int)stream1.Length) + 1];
buffer1 = reader1.ReadBytes((int)stream1.Length);
IntPtr ptr1 = Marshal.AllocCoTaskMem((int)stream1.Length);
Marshal.Copy(buffer1, 0, ptr1, (int)stream1.Length);
bool flag1 = RawPrinterHelper.SendBytesToPrinter(szPrinterName, ptr1, (int)stream1.Length);
Marshal.FreeCoTaskMem(ptr1);
return flag1; } public static void SendStringToPrinter(string szPrinterName, string szString)
{
IntPtr pBytes;
Int32 dwCount;
dwCount = szString.Length;
pBytes = Marshal.StringToCoTaskMemAnsi(szString);
SendBytesToPrinter(szPrinterName, pBytes, dwCount);
Marshal.FreeCoTaskMem(pBytes);
}
}
}
然后用下面的代码调用:
private void button1_Click(object sender, EventArgs e)
{
string sPrintStr = " test"; PrintDialog pd = new PrintDialog();
pd.PrinterSettings = new System.Drawing.Printing.PrinterSettings();
//if (pd.ShowDialog(this) > DialogResult.None)
//{
RawPrinterHelper.SendStringToPrinter(pd.PrinterSettings.PrinterName, sPrintStr);
//}
}
但运行时出现下面的错误:对 PInvoke 函数“PrintTest!PrintTest.RawPrinterHelper::OpenPrinter”的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。大家能否帮忙解决一下啊,或者隐藏掉printdocument.print()中的显示打印过程的窗口.
顶者有分.
System.Drawing.Printing.StandardPrintController PrintStandard = new System.Drawing.Printing.StandardPrintController();
prnDocument.PrintController = PrintStandard;
prnDocument.PrintController = new System.Drawing.Printing.StandardPrintController();