使用后台工作者在Windows服务中打印

时间:2011-11-04 13:01:45

标签: c# printing windows-services backgroundworker

我正在开发一种必须在网络打印机上打印一些标签的Windows服务。 这里http://msdn.microsoft.com/en-us/library/5ekk3hse.aspx表示不支持使用System.Drawing.Printing类在Windows服务中打印(或者不应该这样做)。

这个Print html document from Windows Service in C# without print dialog似乎是解决方案,但他们说它需要.Net Framework 4.0,我必须使用2.0(或者我可以将它改为3.5,如果我真的,真的必须,但那么客户端必须升级我想避免的。)

我还读到要从网络打印机上的Windows服务打印,该服务需要域帐户,我正在使用,所以这不是问题。

打印机的每个设置都将在.config文件中设置,我希望因此不会出现/需要用户对话框。

我的问题:

我是否可以使用BackgroundWorker直接从Windows服务打印?或者我是否需要从我的服务内部调用另一个应用程序(例如控制台应用程序)并在那里进行打印(我在网上看到有些人使用此解决方案,但我没有找到任何代码示例)

此外,我不擅长使用线程并与BackgroundWorkers合作,所以有人可以给我一些示例我该怎么做(我有异步打印请求。如何打印它们而不丢失任何东西?)。 BackgroundWorker是最好的解决方案还是有更好的方法来实现它?

1 个答案:

答案 0 :(得分: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);
    }
相关问题