2010-08-17 13 views
11

Tengo un archivo PCL que generé usando "imprimir en archivo".Cómo imprimir un archivo pcl en C#?

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

(Dado que la impresora a la que estoy imprimiendo admite PCL).

sé que desde el indicador puedo imprimir mediante la invocación:

copy filename.pcl //location/printername 

así que me imagino que yo también podría hacer lo mismo mediante programación (con copia) .. Me pregunto si hay una forma más limpia de haz esto, digamos usando PrintDocument.

Tenga en cuenta que cuando uso PrintDocument:

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


pd.Print(); 

siempre me dan una página en blanco impreso.

+2

DocumentName es el nombre para mostrar del trabajo de impresión. Sin relación con el nombre del archivo en el disco. – dthorpe

Respuesta

2

utilizamos los siguientes métodos por DLL importación:

[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); 
2

Siento 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 utilizar el código, agregue el DLL resultante como una referencia a su proyecto, a continuación, llamar a las funciones a medida que los necesite. Este es 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.

+0

Intenté enviar un documento pcl completo a un controlador laserjet 4 que se configuró para imprimir en un archivo. El estado en el archivo solo dice "Error - Impresión" – Jeremy

+1

Creo que el problema es que está intentando imprimir en un archivo . El código anterior requiere un archivo que contiene solo código PCL, y desea enviarlo directamente a una impresora sin que interfiera Windows. En otras palabras, parece que está intentando imprimir para archivar un archivo que ya se imprimió en un archivo. –

Cuestiones relacionadas