Печать из службы .NET

Прямо сейчас я работаю над проектом, который включает получение сообщения из другого приложения, форматирование содержимого этого сообщения и отправку его на принтер. Выбранная технология - служба Windows C #. Полагаю, вывод можно было бы назвать отчетом, но механизм отчетов не нужен. Подойдет простой механизм шаблонов, такой как StringTemplate, или даже XSLT, выводящий HTML. Проблема, с которой я столкнулся, заключается в том, чтобы найти бесплатный способ распечатать такой вывод из службы. Поскольку кажется, что это сработает, я работаю над прототипом, используя Microsoft RDLC, заполняя локальный отчет и затем визуализируя его как изображение в потоке памяти, которое я затем распечатаю. Проблемы с этим:

  • Многостраничная печать будет большой головной болью.
  • По-прежнему нужно использовать PrintDocument для печати потока памяти, который не поддерживается в службе Windows (хотя он может работать - еще не дошел до этого с прототипом)
  • Если данные меняются, мне нужно изменить набор данных и класс, в который данные десериализуются. плохо плохо плохо.

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

Любая помощь приветствуется.

РЕДАКТИРОВАТЬ: мы находимся на версии 2.0 платформы .NET.


person Chris Marasti-Georg    schedule 11.08.2008    source источник


Ответы (11)


Поверьте, вы потратите больше денег, пытаясь найти / разработать решение для этого, по сравнению с покупкой стороннего компонента. Не изобретайте велосипед и выбирайте платное решение.

Печать - сложная проблема, и я хотел бы увидеть день, когда для этого будет добавлена ​​улучшенная поддержка фреймворка.

person Vaibhav    schedule 11.08.2008

Печать из службы Windows действительно болезненна. Кажется, что это работает ... иногда ... но, в конце концов, время от времени возникает ошибка или исключение без какой-либо явной причины. Это действительно безнадежно. Официально он даже не поддерживается , без каких-либо объяснений или предложений по альтернативному решению.

Недавно я столкнулся с проблемой, и после нескольких безуспешных испытаний и экспериментов я, наконец, пришел к двум жизнеспособным решениям:

  • Напишите свою собственную DLL печати с помощью Win32 API (например, в C / C ++), а затем используйте ее из своей службы с помощью P / Invoke (отлично работает)
  • Напишите свой собственный компонент печати COM +, а затем используйте его из своей службы. Недавно я с успехом выбрал это решение (но это был компонент COM + стороннего производителя, а не собственный написанный). Оно также работает абсолютно нормально.
person Yann Trevin    schedule 11.08.2008
comment
GDI + никогда не разрабатывался / не тестировался для работы в контексте обслуживания. Вот почему это не работает. Вы должны использовать GDI и его функцию для рисования. Обратитесь к этому документу, чтобы найти эквивалентные вызовы Win32: msdn.microsoft.com/ en-us / library / - person Signcodeindie; 17.07.2010
comment
@Yann Trevin, я работаю над аналогичным требованием. Не могли бы вы предложить, какой сторонний компонент COM + вы использовали. Было бы здорово - person SharmaPattar; 10.08.2020

Я сделал это. Это заноза в заднице. Проблема в том, что для печати требуется наличие этого механизма GDI, что обычно означает, что у вас должен быть рабочий стол, который загружается только при входе в систему. Если вы пытаетесь сделать это из службы на сервере, тогда вы обычно не авторизуетесь.

Итак, сначала вы не можете работать как обычный пользователь службы, а вместо этого как настоящий пользователь с правами интерактивного входа в систему. Затем вам нужно настроить записи реестра службы (я забыл, как в данный момент мне нужно было бы найти код, который я могу сделать сегодня вечером, если вам действительно интересно). Наконец, вы должны молиться.

Самая большая головная боль в долгосрочной перспективе связана с драйверами принтера. Если вы работаете как служба без вошедшего в систему пользователя, некоторые драйверы печати любят время от времени открывать всплывающие диалоговые окна. Что произойдет, если в вашем принтере закончится тонер? Или закончилась бумага? Драйвер может открыть диалоговое окно, которое никогда не будет отображаться, и задержит очередь принтера, потому что никто не вошел в систему!

person Nick    schedule 07.10.2008

Чтобы ответить на ваш первый вопрос, это может быть довольно просто, в зависимости от данных. У нас есть множество сервисных приложений, которые делают именно то, что вы просите. Обычно мы анализируем входящий файл и оборачиваем его собственным Postscript или PCL. Если ваш макет довольно прост, то есть несколько очень простых кодов PCL, которыми вы можете обернуть его, чтобы предоставить желаемый макет шрифта / печати (я был бы более чем счастлив дать вам некоторые рекомендации здесь, в автономном режиме).

Если у вас есть готовый к печати файл, вы можете отправить его на общий принтер UNC, непосредственно на локально установленный принтер или даже на IP-адрес устройства (данные типа RAW или LPR).

Однако, если вы идете по пути PDF, самый простой способ - отправить вывод PDF на принтер, который поддерживает прямую печать PDF (многие сейчас это делают). В этом случае вы просто отправляете PDF-файл на устройство, и он печатается.

Другой вариант - запустить Ghostscript, который должен быть бесплатным для ваших нужд (проверьте лицензирование как у них есть несколько разных версий, немного GNU, немного GPL и т. д.) и либо используют встроенную функцию печати, либо просто конвертируют в Postscript и отправляют на устройство. Я много раз использовал Ghostscript в служебных приложениях, но не большой поклонник, так как вы в основном будете обстреливать и запускать приложение командной строки для преобразования. При этом, это стабильное приложение, которое, как правило, изящно дает сбой.

person Douglas Anderson    schedule 07.10.2008

Печать из сервиса - плохая идея. Сетевые принтеры подключаются «на пользователя». Вы можете пометить службу для запуска от имени конкретного пользователя, но я считаю это плохой практикой безопасности. Возможно, вы сможете подключиться к локальному принтеру, но я все равно колеблюсь, прежде чем идти по этому пути.

Лучше всего, чтобы служба сохраняла данные, а приложение, запускаемое пользователем, выполняло печать, запрашивая данные у службы. Или обычное место, где хранятся данные, например, база данных.

Если вам нужно, чтобы данные распечатывались через равные промежутки времени, настройте событие задачи через планировщик задач. Для запуска процесса из службы потребуется знать имя пользователя и пароль, что снова является плохой практикой безопасности.

Что касается самой печати, то использовать сторонний инструмент для создания отчета будет проще всего.

person Joel Lucsy    schedule 11.08.2008

Возможно, это не то, что вы ищете, но если бы мне нужно было сделать это быстро и грязно, я бы:

  1. Создайте отдельное приложение WPF (чтобы я мог использовать встроенную обработку документов)
  2. Предоставьте службе возможность взаимодействовать с рабочим столом (обратите внимание, что вам на самом деле не нужно ничего показывать на рабочем столе или входить в систему, чтобы это работало)
  3. Пусть служба запустит приложение и передаст ему данные для печати.

Вы, вероятно, также могли бы использовать это для печати из веб-браузера, который вы запускаете из службы (хотя я бы рекомендовал создать свой собственный IE оболочки, а не использовать полный браузер).

Для более подробного (также бесплатного) решения лучше всего вручную отформатировать документ (используя GDI + для создания макета за вас). Это утомительно, подвержено ошибкам, требует много времени и тратит впустую много бумаги во время разработки, но также дает вам максимальный контроль над тем, что будет печататься на принтере.

person TheSmurf    schedule 11.08.2008

Если вы можете выводить в post-скрипт, некоторые принтеры будут печатать все, что попадает по FTP в определенный каталог на них.

Мы использовали это, чтобы обойтись без печатных кредитов, которые наш университет предоставил нам, но если ваша служба выводит на ps, вы можете просто ftp-файл ps на принтер.

person Omar Kooheji    schedule 07.10.2008

Мы используем DevExpress 'XtraReports для беспроблемной печати из службы. Их модель отчета аналогична модели Windows Forms, поэтому вы можете динамически вставлять текстовые элементы, а затем выдавать команду печати.

person Jason Z    schedule 27.08.2009

Думаю, мы пойдем сторонним путем. Мне нравится XSL -> HTML -> PDF -> Процесс печати ... HTML в PDF от Winnovative выглядит хорошо для первой части, но я столкнулся с трудностями при поиске хорошего решения для печати PDF ... есть предложения? В идеале лицензия должна быть на основе разработчика, а не на основе развернутой среды выполнения.

person Chris Marasti-Georg    schedule 11.08.2008

Отвечая на ваш вопрос о печати PDF, я не нашел элегантного решения. Я «шел через оболочку» в Adobe, что было ненадежно и требовало, чтобы пользователь постоянно входил в систему. Чтобы решить эту конкретную проблему, я попросил, чтобы файлы, которые мы обрабатываем (счета-фактуры), были отформатированы как многостраничные файлы Tiff, которые можно разделить на части и распечатать с помощью встроенных функций печати .NET. Позиция Adobe, похоже, такова: «Заставьте пользователя просмотреть файл в Adobe Reader, и он сможет нажать кнопку« Печать »». Бесполезный.

Я все еще стремлюсь найти хороший способ создания отчетов о качестве, которые можно было бы выводить с веб-сервера ...

person Community    schedule 21.10.2008

Печать с использованием System.Drawing.Printing не поддерживается MS, согласно ответу Яна Тревина. Однако вы могли бы использовать новый, основанный на WPF, System.Printing (я думаю)

person John Rusk    schedule 14.07.2009