2010-08-18 12 views
3

J'essaie d'imprimer un fichier pcl par programmation en C#. J'utilise le lien Microsoft suivant pour référence. (Notez qu'il est en VB)L'impression d'un fichier pcl dans C# ne fonctionne pas, suggestions?

http://support.microsoft.com/kb/298141

Unfortunatly, ça fonctionne pas .. Je suis seulement obtenir des pages blanches imprimées.

Notez que si je copie simplement le fichier pcl sur l'imprimante à partir de l'invite - c'est-à-dire copie de l'imprimante de nom de fichier. La page est imprimée correctement.

Suggestions?

public class PrintRaw 
    { 
    [StructLayout(LayoutKind.Sequential)] 
    public class DocInfo 
    { 
     [MarshalAs(UnmanagedType.LPWStr)] public String docName; 
     [MarshalAs(UnmanagedType.LPWStr)] public String outputFile; 
     [MarshalAs(UnmanagedType.LPWStr)] public String dataType; 
    } 

    [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)] DocInfo 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); 

    public void Print(String printerName, String filename) 
    { 
     IntPtr lhPrinter; 
     OpenPrinter(printerName, out lhPrinter, new IntPtr(0)); 

     if (lhPrinter.ToInt32() == 0) 
     return; //Printer not found!! 

     var rawPrinter = new DocInfo() {docName = "My Document", dataType = "RAW"}; 

     StartDocPrinter(lhPrinter, 1, rawPrinter); 

     using (var b = new BinaryReader(File.Open(filename, FileMode.Open))) 
     { 
     var length = (int) b.BaseStream.Length; 
     const int bufferSize = 8192; 

     var numLoops = length/bufferSize; 
     var leftOver = length%bufferSize; 


     for (int i = 0; i < numLoops; i++) 
     { 
      var buffer = new byte[bufferSize]; 
      int dwWritten; 

      b.Read(buffer, 0, bufferSize); 
      IntPtr unmanagedPointer = Marshal.AllocHGlobal(buffer.Length); 
      Marshal.Copy(buffer, 0, unmanagedPointer, buffer.Length); 
      WritePrinter(lhPrinter, unmanagedPointer, bufferSize, out dwWritten); 
      Marshal.FreeHGlobal(unmanagedPointer); 
     } 

     if (leftOver > 0) 
     { 
      var buffer = new byte[leftOver]; 
      int dwWritten; 

      b.Read(buffer, 0, leftOver); 
      IntPtr unmanagedPointer = Marshal.AllocHGlobal(buffer.Length); 
      Marshal.Copy(buffer, 0, unmanagedPointer, buffer.Length); 
      WritePrinter(lhPrinter, unmanagedPointer, leftOver, out dwWritten); 
      Marshal.FreeHGlobal(unmanagedPointer); 
     } 
     } 

     EndDocPrinter(lhPrinter); 
     ClosePrinter(lhPrinter); 
    } 
    } 
+0

Pour une raison quelconque, l'appel de StartDocPrinter échoue, le code d'erreur Win32 est 1804, type de données non valide. – vicsz

+0

Voici un lien vers la version C# du code que vous référencez en haut: http://support.microsoft.com/kb/322091 –

Répondre

2

Ok, il semble que le type de données que j'utilisais n'était pas valide dans l'exemple. Je l'ai mis à jour à la suivante (notez le réglage de Charset) et il a résolu le problème.

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
public class DOC_INFO_1 
{ 
    [MarshalAs(UnmanagedType.LPStr)] 
    public string pDocName; 
    [MarshalAs(UnmanagedType.LPStr)] 
    public string pOutputFile; 
    [MarshalAs(UnmanagedType.LPStr)] 
    public string pDataType; 
}