2011-11-04 26 views
0

我正在開發一個Windows服務,它必須在網絡打印機上打印一些標籤。 這裏http://msdn.microsoft.com/en-us/library/5ekk3hse.aspx它說不支持使用System.Drawing.Printing類在Windows服務中打印(或者不應該這樣做)。在使用後臺工作的Windows服務中打印

Print html document from Windows Service in C# without print dialog似乎是解決方案,但他們說,它需要。NET Framework 4.0,我必須使用2.0(或者如果我真的必須使用2.0,我可以將其更改爲3.5),但客戶端將必須升級,我想避免)。

我還讀到,要從網絡打印機的Windows服務打印域帳戶是服務所需的,我仍在使用,所以這不是問題。

打印機的每個設置都將在.config文件中設置,我希望因此不會出現/需要用戶對話框。

我的問題:

我能使用的BackgroundWorker從Windows服務直接打印?或者我需要從我的服務內部調用另一個應用程序(例如控制檯應用程序)並在那裏進行打印(我在網上讀過一些人使用此解決方案,但我沒有找到任何代碼示例)

另外我不太擅長線程和BackgroundWorkers的工作,所以有人可以給我一些例子,我該怎麼做(我有異步打印請求,我怎樣才能打印它們而不會丟失任何?)。 BackgroundWorker是最好的解決方案還是有一些更好的方法來做到這一點?

+0

該代碼目前的工作沒有一個後臺工/其他線程? – John

+1

*任何*從服務打印是非常不推薦。問題是打印機驅動程序,他們認爲他們將有一個可見的用戶界面。告訴用戶在當前裝滿墨盒時預先訂購墨粉盒。在服務中無法正常工作,沒有人點擊「謝謝」按鈕。 –

+0

沒有打印的代碼就像一個魅力:)而且我知道從服務打印不建議,但我有點必須這樣做:(我希望這個:printer.PrintController = new StandardPrintController();將照顧任何不需要的用戶對話框 - 現在沒有任何顯示,但是我沒有在真實的打印機上測試過我的當前打印代碼,只能在Microsoft XPS Document Writer上進行測試 – Arie

回答

1

我還沒有測試從另一個線程打印,但這兩個選項之一應該工作。您可能需要修改代碼與.net 2的工作,因爲我只用3.5 SP1或4

假設你有一個Print方法和Queue<ItemToPrint>其中ItemToPrint是類持有的打印設置/信息

public Queue<ItemToPrint> PrintQueue = new Queue<ItemToPrint>(); 
    private BackgroundWorker bgwPrintWatcher; 

    public void SetupBackgroundWorker() 
    { 
     bgwPrintWatcher = new BackgroundWorker(); 
     bgwPrintWatcher.WorkerSupportsCancellation = true; 
     bgwPrintWatcher.ProgressChanged += new ProgressChangedEventHandler(bgwPrintWatcher_ProgressChanged); 
     bgwPrintWatcher.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgwPrintWatcher_RunWorkerCompleted); 
     bgwPrintWatcher.DoWork += new DoWorkEventHandler(bgwPrintWatcher_DoWork); 
     bgwPrintWatcher.RunWorkerAsync(); 
    } 

    void bgwPrintWatcher_DoWork(object sender, DoWorkEventArgs e) 
    { 
     BackgroundWorker worker = sender as BackgroundWorker; 
     while (!worker.CancellationPending) 
     { 
      // Prevent writing to queue while we are reading/editing it 
      lock (PrintQueue) 
      { 
       if (PrintQueue.Count > 0) 
       { 
        ItemToPrint item = PrintQueue.Dequeue(); 
        // Two options here, you can either sent it back to the main thread to print 
        worker.ReportProgress(PrintQueue.Count + 1, item); 
        // or print from the background thread 
        Print(item); 
       } 
      } 
     } 
    } 

    private void Print(ItemToPrint item) 
    { 
     // Print it here 
    } 

    private void AddItemToPrint(ItemToPrint item) 
    { 
     lock (PrintQueue) 
     { 
      PrintQueue.Enqueue(item); 
     } 
    } 

    void bgwPrintWatcher_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     // Anything here will run from the main/original thread 
     // PrintQueue will no longer be watched 
    } 

    void bgwPrintWatcher_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     // Anything here will run from the main/original thread 
     ItemToPrint item = e.UserState as ItemToPrint; 
     // e.ProgressPercentage holds the int value passed as the first param 
     Print(item); 
    } 
+0

我修改了一下你的代碼,現在它工作了。 – Arie

相關問題