2010-08-18 20 views
3

我試圖在c#中以編程方式打印一個pcl文件。在c#中打印pcl文件不工作,建議?

我使用以下Microsoft鏈接作爲參考。 (請注意這是在VB)

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

不幸的是,它不工作的印刷..我只得到空白頁。

請注意,如果我只是從提示 - 即複製文件名打印機複製pcl文件到打印機。頁面得到正確打印。

對此提出建議?

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

出於某種原因,對StartDocPrinter的調用失敗,Win32錯誤代碼爲1804,無效的數據類型。 – vicsz 2010-08-18 22:12:50

+0

這裏是一個鏈接到您在頂部引用的代碼的C#版本:http://support.microsoft.com/kb/322091 – 2010-09-12 23:29:31

回答

2

好的,好像我在使用的數據類型在這個例子中是無效的。我將它更新爲以下內容(注意Charset的設置),並解決了問題。

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