net mandar imprimir documento desde abrirlo c# printing printer-control-language

mandar - Cómo imprimir un archivo pcl en c#?



mandar a imprimir un pdf desde c# (3)

Usamos los siguientes métodos por importación de 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);

Tengo un archivo PCL que generé usando "imprimir en archivo".

¿Cuál es la mejor manera de imprimir este archivo mediante programación en C #.

(Dado por supuesto que la impresora que estoy imprimiendo admite PCL).

Lo sé desde el momento en que puedo imprimir invocando:

copy filename.pcl //location/printername

Entonces me imagino que también podría hacer lo mismo programáticamente (usando copia). Me pregunto si hay una manera más limpia de hacerlo, digamos usando PrintDocument.

Tenga en cuenta que cuando uso PrintDocument:

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

Siempre obtengo una página en blanco impresa.



Lamento haber llegado tan tarde a esta pregunta, pero tengo un código que hará el trabajo. No fue escrito por mí originalmente. Recibí el código del sitio de ayuda de otro programador, pero no recuerdo cuál. Funciona maravillosamente. Aquí está el proyecto, que crea un dll. Para hacerlo usted mismo, seleccione Crear: / Proyecto / Biblioteca de clases (seleccione Visual C # debajo de los tipos de proyectos).

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; } } }

Ahora, para usar este código, agregue el dll resultante como una referencia a su proyecto, luego llame a las funciones cuando las necesite. Aquí hay un código donde lo usé, solo hoy:

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); } } }

Este programa lee una fuente PCL de un archivo. Envuelve la fuente con código para asignarle una identificación de fuente de 32545, luego llama a la función dll SendStringToPrinter.