2012-11-02 37 views
0

我想在我的項目中使用iTextSharp dll打印Windows應用程序中的pdf ..通過c#.net代碼打印pdf時的線程問題?

但是,我迄今使用的方法似乎並不可靠。 (有時它工作,有時它不)

我在一個Process類中組合整個過程並編寫以下代碼。

      printProcess = new Process[noOfCopies]; 
// Print number of copies specified in configuration file 
          for (int counter = 0; counter < noOfCopies; counter++) 
          { 
           printProcess[counter] = new Process(); 

           // Set the process information 
           printProcess[counter].StartInfo = new ProcessStartInfo() 
           { 
            CreateNoWindow = true, 
            Verb = "Print", 
            FileName = pdfFilePath, 
            ErrorDialog = false, 
            WindowStyle = ProcessWindowStyle.Hidden, 
            UseShellExecute = true, 
           }; 


    // Start the printing process and wait for exit for 7 seconds 
            printProcess[counter].Start(); 

            // printProcess[counter].WaitForInputIdle(waitTimeForPrintOut); 
            printProcess[counter].WaitForExit(waitTimeForPrintOut); //<--**This is line for discussion** 

            if (!printProcess[counter].HasExited) 
            { 
             printProcess[counter].Kill(); 
            } 
           } 
    // Delete the file before showing any message for security reason 
         File.Delete(pdfFilePath); 

的問題是,如果沒有PDF被打開,則過程正常工作......(它打印好),但如果任何PDF是開放的,然後WaitForExit(..)方法就是不等待進程退出..因此該過程運行得太快,因爲我在打印後刪除文件,如果打印報告的計數器(次數..)超過一次,會給出錯誤..

我也使用Timer來緩慢這個過程,但它不起作用。我不知道爲什麼。 也使用睡眠命令..但它使主線程去睡覺,因此也不適合我。

請建議我一些非常可靠的方法,這樣做.. :)

+0

什麼應用是聯想與打印命令?我問,因爲我們在使用Adobe Reader時遇到類似問題,並轉移到福昕閱讀器。然後我們使用它的命令行而不是動詞來開始一個進程。似乎工作,我相信它榮幸WaitForExit。 –

回答

0

試試這個,你需要.NET 4級或以上。而System.Threading.Tasks

printProcess = new Process[noOfCopies]; 
    // Print number of copies specified in configuration file 
    Parallel.For(0, noOfCopies, i => 
    { 
    printProcess[i] = new Process(); 

    // Set the process information 
    printProcess[i].StartInfo = new ProcessStartInfo() 
    { 
     CreateNoWindow = true, 
     Verb = "Print", 
     FileName = pdfFilePath, 
     ErrorDialog = false, 
     WindowStyle = ProcessWindowStyle.Hidden, 
     UseShellExecute = true, 
    }; 


    // Start the printing process and wait for exit for 7 seconds 
    printProcess[i].Start(); 

    // printProcess[counter].WaitForInputIdle(waitTimeForPrintOut); 
    printProcess[counter].WaitForExit(waitTimeForPrintOut); //<--**This is line for discussion** 

    if(!printProcess[i].HasExited) 
    { 
     printProcess[i].Kill(); 
    } 
    }); 
    // Delete the file before showing any message for security reason 
    File.Delete(pdfFilePath); 
+0

如果abobe閱讀器尚未打開,它工作正常。如果adobe reader已經打開,那麼它不會等待WaitForExit()。你的意思是 –

+0

,「如果abobe閱讀器沒有打開,它工作正常」 –

+0

是的..正是這種情況.. !! –

1

我不知道你正試圖從打印,但真正簡單的方法來打印文檔或PDF是簡單地將文件複製到打印機隊列什麼樣的應用,它會爲你處理一切。非常可靠。只需在機器打印上安裝Adobe Reader併爲打印機安裝正確的驅動程序。示例代碼:

 var printer = PrinterHelper.GetAllPrinters().FirstOrDefault(p => p.Default); 
     PrinterHelper.SendFileToPrinter("C:\\Users\\Public\\Documents\\Form - Career Advancement Request.pdf", printer.Name); 

打印機助手代碼:

public static class PrinterHelper 
    { 
     public class PrinterSettings 
     { 
      public string Name { get; set; } 
      public string ServerName { get; set; } 
      public string DeviceId { get; set; } 
      public string ShareName { get; set; } 
      public string Comment { get; set; } 
      public bool Default { get; set; } 
     } 

    /// <summary> 
    /// Sends the file to printer. 
    /// </summary> 
    /// <param name="filePathAndName">Name of the file path and Name of File.</param> 
    /// <param name="printerName">Name of the printer with Path. E.I. \\PRINT2.company.net\P14401</param> 
     public static void SendFileToPrinter(string filePathAndName, string printerName) 
     { 
      FileInfo file = new FileInfo(filePathAndName); 
      file.CopyTo(printerName); 
     } 

     /// <summary> 
     /// Gets all printers that have drivers installed on the calling machine. 
     /// </summary> 
     /// <returns></returns> 
     public static List<PrinterSettings> GetAllPrinters() 
     { 
      ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_Printer"); 
      ManagementObjectSearcher mos = new ManagementObjectSearcher(query); 
      List<PrinterSettings> printers = new List<PrinterSettings>(); 

      foreach (ManagementObject mo in mos.Get()) 
      { 
       PrinterSettings printer = new PrinterSettings(); 
       foreach (PropertyData property in mo.Properties) 
       { 
        if (property.Name == "Name") 
         printer.Name = property.Value == null ? "" : property.Value.ToString(); 

        if (property.Name == "ServerName") 
         printer.ServerName = property.Value == null ? "" : property.Value.ToString(); 

        if (property.Name == "DeviceId") 
         printer.DeviceId = property.Value == null ? "" : property.Value.ToString(); 

        if (property.Name == "ShareName") 
         printer.ShareName = property.Value == null ? "" : property.Value.ToString(); 

        if (property.Name == "Comment") 
         printer.Comment = property.Value == null ? "" : property.Value.ToString(); 

        if (property.Name == "Default") 
         printer.Default = (bool)property.Value; 
       } 
       printers.Add(printer); 
      } 

      return printers; 
     }  
} 
+0

你的SendFileToPrinter(..)方法的第一個參數在定義中說'filePathAndName',但你已經在開始時傳遞了打印機名稱..這很混亂.... !! 請在這方面澄清.. –

+0

進一步調查後的好點ops我有parms交換。 filePathAndName是要打印的PDF,名稱是打印機的名稱。抱歉! – retslig

+0

感謝您的快速響應..但它給出了'未經授權的訪問'的錯誤,因爲它是一個網絡打印機... :( –