如何在C#中打印PCL文件?

我有一个使用“print to file”生成的PCL文件。

在C#中以编程方式打印此文件的最佳方法是什么?

(当然,我打印的打印机支持PCL。)

我知道我可以通过调用提示进行打印:

copy filename.pcl //location/printername 

所以我想我也可以通过编程方式做同样的事情(使用copy)…我想知道是否有更简洁的方法来做这个,比如使用PrintDocument。

请注意,当我使用PrintDocument时:

 var pd = new PrintDocument { DocumentName = @"filename.pcl"; PrinterSettings = {PrinterName = @"\\location\printername"} }; pd.Print(); 

我总是打印一个空白页。

本文适用于Visual Basic ,但我认为很容易将其应用于C#。 否则,我很乐意帮助您解决任何有问题的部分。

如果打印机在网络上, 这里有一个如何直接与它对话的有趣例子 。 如果您只是将PCL的字节发送到打印机,则不确定它是否也有效。

很抱歉这个问题来得太晚了,但我有一些代码可以完成这个工作。 它本来不是我写的。 我收到了另一个程序员帮助网站的代码,但我不记得是哪一个。 它工作得很漂亮。 这是项目,它创建一个DLL。 要自己动手,选择Create:/ Project / Class Library(在项目类型下选择Visual C#)。

 using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.IO; namespace PrintRaw { public class RawFilePrint { // Structure and API declarions: [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public class DOCINFOA { [MarshalAs(UnmanagedType.LPStr)] public string pDocName; [MarshalAs(UnmanagedType.LPStr)] public string pOutputFile; [MarshalAs(UnmanagedType.LPStr)] public string pDataType; } [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd); [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool ClosePrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di); [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool EndDocPrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool StartPagePrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool EndPagePrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten); // SendBytesToPrinter() // When the function is given a printer name and an unmanaged array // of bytes, the function sends those bytes to the print queue. // Returns true on success, false on failure. public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount) { Int32 dwError = 0, dwWritten = 0; IntPtr hPrinter = new IntPtr(0); DOCINFOA di = new DOCINFOA(); bool bSuccess = false; // Assume failure unless you specifically succeed. di.pDocName = "RAW Document"; di.pDataType = "RAW"; if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero)) { if (StartDocPrinter(hPrinter, 1, di)) { if (StartPagePrinter(hPrinter)) { bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten); EndPagePrinter(hPrinter); } EndDocPrinter(hPrinter); } ClosePrinter(hPrinter); } if (!bSuccess) { dwError = Marshal.GetLastWin32Error(); } return bSuccess; } public static bool SendFileToPrinter(string szPrinterName, string szFileName) { FileStream fs = new FileStream(szFileName, FileMode.Open); BinaryReader br = new BinaryReader(fs); Byte[] bytes = new Byte[fs.Length]; bool bSuccess = false; IntPtr pUnmanagedBytes = new IntPtr(0); int nLength; nLength = Convert.ToInt32(fs.Length); bytes = br.ReadBytes(nLength); pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength); Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength); bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength); Marshal.FreeCoTaskMem(pUnmanagedBytes); return bSuccess; } public static bool SendStringToPrinter(string szPrinterName, string szString) { IntPtr pBytes; Int32 dwCount; dwCount = szString.Length; // Assume that the printer is expecting ANSI text, and then convert // the string to ANSI text. pBytes = Marshal.StringToCoTaskMemAnsi(szString); SendBytesToPrinter(szPrinterName, pBytes, dwCount); Marshal.FreeCoTaskMem(pBytes); return true; } } } 

现在,要使用此代码,请将生成的dll添加为项目的引用,然后根据需要调用函数。 这是我使用它的一些代码,就在今天:

 using System; using System.Collections.Generic; using System.Text; using System.IO; namespace PclFontTest { class Program { static void Main(string[] args) { string szPrinterName = @"\\printserver\LaserJet 2420"; StreamReader sr = new StreamReader(@"C:\Fonts\US20HP.FNT"); string line = (char)27 + "*c32545D"; line += sr.ReadToEnd(); line += (char)27 + "*c5F"; PrintRaw.RawFilePrint.SendStringToPrinter(szPrinterName, line); } } } 

该程序从文件中读取PCL字体。 它用字母包装字体,为其分配字体ID 32545,然后调用dll函数SendStringToPrinter。

我们对每个DLL导入使用以下方法:

  [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd); [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool ClosePrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] RawPrinter di); [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool EndDocPrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool StartPagePrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool EndPagePrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten);