Печать в службе Windows с использованием фонового рабочего - PullRequest
0 голосов
/ 04 ноября 2011

Я разрабатываю службу Windows, которая должна печатать некоторые этикетки на сетевом принтере. Здесь http://msdn.microsoft.com/en-us/library/5ekk3hse.aspx говорит, что печать в службе Windows с использованием классов System.Drawing.Printing не поддерживается (или, скорее, не должна выполняться).

Это Печать HTML-документа из Windows Service в C # без диалогового окна печати похоже на решение, но там говорится, что для этого требуется .Net Framework 4.0, и мне нужно использовать 2.0 (или я могу изменить его) до 3.5, если я действительно, действительно должен, но тогда клиенту придется обновить, чего я хочу избежать).

Я также прочитал, что для печати из службы Windows на сетевом принтере необходима учетная запись домена для службы, которую я в любом случае использую, так что это не проблема.

Каждая настройка для принтера будет установлена ​​в файле .config, и я надеюсь, что из-за этого пользовательский диалог не появится / не понадобится.

Мои вопросы:

Смогу ли я печатать напрямую из службы Windows, используя BackgroundWorker? Или мне нужно вызвать другое приложение (например, консольное приложение) изнутри моего сервиса и выполнить там печать (я читал в сети, что некоторые люди используют это решение, но я не нашел ни одного примера кода)

Кроме того, я не очень хорошо разбираюсь в потоках и работаю с BackgroundWorkers, поэтому кто-нибудь может дать мне пример, как я могу это сделать (у меня есть запросы на печать, поступающие асинхронно. Как я могу напечатать их, не теряя их?) Является ли BackgroundWorker лучшим решением или есть несколько лучших способов сделать это?

1 Ответ

1 голос
/ 04 ноября 2011

Я не тестировал печать из другого потока, но один из этих двух вариантов должен работать.Возможно, вам придется изменить код для работы с .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);
    }
...