2010-08-17 6 views
11

J'ai un fichier PCL que j'ai généré en utilisant "Imprimer dans un fichier".Comment imprimer un fichier pcl dans C#?

Quelle est la meilleure façon d'imprimer par programmation ce fichier en C#. (Bien entendu, l'imprimante que j'imprime supporte PCL).

Je sais que je peux partir de l'invite imprimer en invoquant:

copy filename.pcl //location/printername 

Je suppose que je pourrais aussi faire la même chose par programme (en utilisant copie) .. Je me demande s'il y a un moyen plus propre faites cela, par exemple en utilisant PrintDocument.

Notez que lorsque j'utilise PrintDocument:

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


pd.Print(); 

Je reçois toujours une page blanche imprimée.

+2

Aucune relation avec le nom de fichier sur le disque. – dthorpe

Répondre

2

Nous utilisons les méthodes suivantes par DLL d'importation:

[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

Je suis désolé d'être venu si tard à cette question, mais j'ai un code qui va faire le travail. Ce n'était pas écrit par moi à l'origine. J'ai reçu le code du site d'aide d'un autre programmeur, mais je ne me souviens plus lequel. Cela fonctionne magnifiquement. Voici le projet, qui crée une DLL. Pour le faire vous-même, sélectionnez Créer:/Project/Class Library (sélectionnez Visual C# sous types de projets).

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

Maintenant, pour utiliser ce code, ajoutez le dll résultant comme une référence à votre projet, puis appelez les fonctions que vous avez besoin. Voici un code où je l'ai utilisé, juste aujourd'hui:

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


     } 
    } 
} 

Ce programme lit une police PCL à partir d'un fichier. Il encapsule la police avec du code pour lui attribuer un identifiant de police 32545, puis appelle la fonction dll SendStringToPrinter. DocumentName est le nom d'affichage du travail d'impression.

+0

J'ai essayé d'envoyer un document pcl complet à un pilote laserjet 4 qui a été configuré pour imprimer dans le fichier, l'état sur le fichier dit simplement "Erreur - Impression" – Jeremy

+1

Je crois que le problème est que vous essayez d'imprimer dans un fichier . Le code ci-dessus nécessite un fichier contenant uniquement du code PCL et que vous souhaitez envoyer directement à une imprimante sans interférence de Windows. En d'autres termes, vous semblez tenter d'imprimer pour archiver un fichier déjà imprimé dans un fichier. –

Questions connexes