Как преобразовать драйвер принтера в автономное консольное приложение, которое может генерировать файл принтера, содержащий байты для отправки на принтер?

У меня есть ситуация, когда единственный способ генерировать определенный файл данных - это распечатать его вручную в FILE: под Windows и сохранить его в файле для дальнейшей обработки.

Мне бы очень хотелось иметь небольшую автономную программу, в которую встроен этот двоичный драйвер принтера, поэтому я могу запустить его из командного файла и создать для него этот двоичный файл, так как мы можем полностью автоматизировать "сохранить файл в Visio," распечатайте "его и загрузите в конечный пункт назначения и вызовите удаленный тест".

Возможно ли это с подходящим Windows SDK? Я программист на Java, поэтому я еще не знаю Visual Studio и возможности с MSDN. - но я буду признателен за указатели.


EDIT: У меня есть установочные файлы для этого драйвера принтера, как 32, так и 64 бит. Более старые версии могут включать 16-битный драйвер.


EDIT: функциональность "print to FILE:" - это то, что было рекомендовано в документации. Я немного поиграл с LPR-протоколом, чтобы посмотреть, что он может сделать. Я бы предпочел использовать метод "invoke small binary".

Ответы

Ответ 1

Общая проблема, которую вы формулируете, трудно решить. В основном драйвер принтера состоит из некоторых известных компонентов, таких как Print Monitor, Print Processor и т.д., Которые хорошо документированы в наборе драйверов Windows http://msdn.microsoft.com/en-us/library/ff560885%28v=VS.85%29.aspx. Несколько лет назад я написал "Монитор печати". Он работал много лет у клиента. Поэтому я точно знаю, о чем пишу. Монитор печати - это не что иное, как DLL с хорошо документированными функциями. То же самое касается большинства других компонентов принтера. Эти DLL файлы будут загружены и вызваны из Spooler. Если у вас современный драйвер принтера, у него нет компонентов, которые запускаются в режиме ядра. Таким образом, можно загрузить большинство DLL, из которых состоят все драйверы принтера, и вызывать соответствующую функцию.

Вам интересен использовать один драйвер для конференц-принтера. Итак, первое, что нужно сделать, - это изучить как этот драйвер. Если вы узнаете, какой компонент выполняет задание, в котором вы нуждаетесь, вы, вероятно, сможете загрузить эту DLL в свой процесс и создать нужный вам результат. Возможно, вы публикуете URL-адрес, где я могу загрузить этот драйвер?

ОБНОВЛЕНО. Я немного подробнее о ваших требованиях. Мне кажется, вы можете идти по пути, предложенному разработчиком драйвера принтера. Если драйвер может печатать на локальном порту FILE, он может печатать в любом порт принтера. Таким образом, вы можете предоставить src драйвера Port Monitor Server из C:\WinDDK\7600.16385.1\src\print\monitors\localmon (см. Также http://msdn.microsoft.com/en-us/library/ff556478%28v=VS.85%29.aspx, http://msdn.microsoft.com/en-us/library/ff549405%28v=VS.85%29.aspx и http://msdn.microsoft.com/en-us/library/ff563806%28v=VS.85%29.aspx), (Я - DLL 32/64 Windows, а не настоящий драйвер) и делает небольшую модификацию. Вместо сохранения результатов в файл вы можете отправить результаты в свое приложение. Это будет работать со 100% без каких-либо трюков. Если у вас возникнет проблема с пониманием localmon, я могу дать вам несколько советов. Это действительно не сложно. Основные изменения, которые вам нужно сделать, это изменить LcmStartDocPort LcmWritePort LcmReadPort LcmEndDocPort функции из localmon.c. Некоторая легкая вещь, которая отличает DLL Port от типичной DLL, которая вместо экспорта всех DLL-функций экспортирует только один InitializePrintMonitor2 с указателями на все остальные функции.

ОБНОВЛЕНО 2. Еще один совет для использования монитора "Local Port". Если в настройках принтера выберите "Добавить порт...", выберите "Локальный порт" и нажмите "Новый порт...", вы можете ввести любое имя файла, например "C:\temp\my.bin". Затем все, что вы печатаете через принтер, будет напечатано в этом файле без какой-либо итерации пользователя. Имя может быть любым именем файла win32 (имена UNC или именованные каналы также разрешены). Таким образом, вы можете реализовать некоторые сценарии без программирования с помощью DDK.

ОБНОВЛЕНО 3. Я посмотрел на драйвер принтера с разных сторон и снова посмотрел в API в DDK. Теперь я хочу порекомендовать вам выбрать самый простой способ и способ, который будет полностью поддерживаться производителем драйверов. Я предлагаю следующее:

Вы устанавливаете принтер с нужным драйвером и выбираете в качестве выходного порта локальный порт с фиксированным именем файла (см. обновление 2). Я назвал здесь имя файла назначения как C:\TEMP\Output.afp. Таким образом, вы получаете точно такую ​​же ситуацию, как рекомендуете производителя драйвера. Фиксированное имя файла абсолютно совпадает с файлом FILE:. Поэтому, если вы печатаете на принтере, вы получаете файл Output.afp в каталоге C:\TEMP. Чтобы закончить запись, вы можете использовать функции ReadDirectoryChangesW или FindNextChangeNotification/FindFirstChangeNotification с dwNotifyFilter равным FILE_NOTIFY_CHANGE_LAST_WRITE. Затем вы получаете уведомление после последнего времени записи файла. Это означает, что после окончания записи и после FileClose и после достаточного покраски кеша. Таким образом, файл Output.afp не заблокирован, и вы можете действительно безопасно читать результаты.

Для печати простых документов вы можете использовать функцию WritePrinter (см. http://msdn.microsoft.com/en-us/library/dd162959%28VS.85%29.aspx и примечание в документации http://msdn.microsoft.com/en-us/library/dd145226%28VS.85%29.aspx). Написание сложных файлов с растровыми изображениями, цветом и разными шрифтами вы должны использовать типичный API GDI, подобный этому в Windows (см. http://msdn.microsoft.com/en-us/library/dd162865%28v=VS.85%29.aspx).

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

Ответ 2

(Прошло 10 лет с тех пор, как я сделал что-то подобное, но я не думаю, что общие концепции все изменили:)

Что вы хотите сделать, это реализовать собственный процессор печати. Процессор печати представляет собой фрагмент кода, который выводит на выходе драйвер принтера и переносит его на устройство вывода. Процессоры печати реализованы как обычные пользовательские библиотеки DLL. Вы должны быть в состоянии найти все, что вам нужно, включая образцы, в Windows DDK.

Ответ 3

Недавно мы создали коммерческое приложение, которое захватило потоки печати из любого приложения Windows и преобразовало результат в XML и tiff images
Мы сделали прототип с DDK, но закончили тем, что купили SDK для захвата печати
SDK был от BlackIce. Хотя это был не бесплатный SDK, распределение времени выполнения было бесплатным.

Реализация выполнялась с помощью Visual C (неуправляемый) и VB6. Драйвер принтера должен был быть установлен на сервере/ПК, который запустил процесс печати. ​​
Я помню, что сложной задачей было управлять настройками принтера во время выполнения (сохранять сжатые файлы tiffs, выводить каталог для файлов, размер бумаги: A4 или Letter и другие параметры, которые были определены в DEVMODE структура управления печатью).

ОБНОВЛЕНИЕ: (Ваш комментарий к @Oleg о MO: DCA P запустил мою память. Хотя речь идет не о драйвере принтера...)
Для нашего коммерческого продукта нам также пришлось выполнить настройку для конвертации документов MO: DCA (AFP) в tiffs и XML.
Этот SDK должен был иметь возможность извлекать оба изображения и текст ascii, чтобы включить последующие преобразования
Преобразование, которое затем производится в пакете из документов AFP в одной папке для XML и tiff.
Мы решили преобразовать файл AFP после его печати (не во время печати).
SDK SnowBound RasterMaster и доступен в разных вариантах (мы использовали API Windows с ActiveX, и теперь я вижу, что он доступен для Java)
Поэтому, если ваше требование заключается в преобразовании документа AFP в другое (извлечение изображений и извлечение текста ascii), вы можете попробовать программное обеспечение SnowBound. Убедитесь, что вы также получаете Необязательный параметр, чтобы иметь возможность извлекать текст ASCII из документов MO DCA.
Этот SDK программного обеспечения дороже, но он выполнил эту работу.
Они предлагают пробную версию здесь.

Ответ 4

В настоящий момент у меня есть одно недостающее звено в вашем объяснении, поэтому позвольте мне перефразировать то, что я понял:

  • У вас есть специальный драйвер принтера в вашей системе Windows, который настроен для печати в файл.
  • Вам нравится иметь простую пакетную программу, которая может дать что-то этому драйверу принтера для вывода двоичного файла.
  • У вас есть инструментальная цепочка, в которой этот файл может быть дополнительно обработан.

Теперь моя недостающая часть, что вы хотите отдать своей маленькой серии script, чтобы она создавала ваш двоичный файл? У вас есть файл Visio, который должен быть автоматически распечатан с помощью этого драйвера?

Если да, вы должны изучить этот маленький пакет script. Он может взять любой файл с зарегистрированным расширением файла и отправить его на принтер по умолчанию с настройками по умолчанию. Используя эти настройки, вы можете изменить настройки принтера в своей системе Windows из командного файла, чтобы сделать ваш специальный драйвер по умолчанию и поставить вывод в файл.

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

Update

Хорошо, прочитав ваш комментарий, я полностью понял, чего вы хотите достичь. Чтобы заставить это работать, вы должны следовать рекомендациям Per Larsens, чтобы написать собственный драйвер с окнами ddk (или, точнее, набор драйверов для Windows [WDK]) и инкапсулируйте уже существующий драйвер.

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

Некоторые примеры для запуска также можно найти в MSDN как обзор или более точно здесь.

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

Ответ 5

Я могу жить с "Когда пользователь печатает любой файл на этом конкретном принтере Windows, затем автоматически фиксирует байты, которые были отправлены на принтер".

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

Ответ 6

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

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

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

Образец LocalMon в наборе драйверов Windows является отправной точкой для записи монитора порта. Тем не менее, он управляет всеми локальными портами системы и довольно немного сложнее, чем вам нужно. На самом деле, большая часть этого, скорее всего, вас смущает. Я бы рекомендовал вам начать с LocalMon и сравнить его с источником Redmon, что намного проще, потому что он управляет выделенным портом. Остерегайтесь того, что источник Redmon был взят из localmon давно и, похоже, имеет несколько ошибок, поэтому используйте Redmon в качестве ссылки и отбросьте код LocalMon на то, что нужно было просто написать вывод в файл.

Ответ 7

Вы не вставляете драйверы в исполняемые файлы - драйверы предназначены для операционной системы для связи с оборудованием.

Вы печатаете через операционную систему.

Ваша "партия" должна выбрать правильный принтер и распечатать...