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

У меня есть ситуация, где единственный способ генерировать определенный файл данных состоит в том, чтобы распечатать ее вручную в ФАЙЛ: в соответствии с Windows и сохраняют его в файле для последующей обработки.

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

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


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


Править: "Печать в ФАЙЛ": функциональность, что рекомендовалось документацией. Я играл немного с использованием протокола LPR для наблюдения то, что это может сделать. Я все еще предпочел бы, "вызывают маленький двоичный" подход.

14
задан Thorbjørn Ravn Andersen 29 April 2010 в 08:05
поделиться

7 ответов

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

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

UPDATED: Я немного больше узнал о ваших требованиях. Мне кажется, что вы можете пойти по пути, предложенному разработчиком драйвера принтера. Если драйвер может печатать в ФАЙЛ локального порта, то он может печатать в любом порту принтера. Поэтому можно привести 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 для windows 32/64, а не настоящий драйвер) и вносит небольшие изменения. Вместо сохранения результатов в файл вы можете отправлять результаты в ваше приложение. Это будет работать на 100% без каких-либо ухищрений. Если у вас возникнут проблемы с пониманием localmon, я могу дать вам несколько советов. Это действительно не сложно. Основные изменения, которые вам нужно сделать, это модифицировать LcmStartDocPort LcmWritePort LcmReadPort LcmEndDocPort функции из localmon.c. Некоторая простая вещь, которая отличает Port DLL от обычной DLL, что вместо экспорта всех функций DLL она экспортирует только одну InitializePrintMonitor2 с указателями на все остальные функции.

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

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

Вы устанавливаете принтер с нужным вам драйвером и выбираете в качестве выходного порта Local Port с фиксированным именем файла (см. Update 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). Для записи сложных файлов с растровыми изображениями, цветом и различными шрифтами необходимо использовать типичный GDI API, как это сделано в Windows (см. http://msdn.microsoft.com/en-us/library/dd162865%28v=VS.85%29.aspx).

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

12
ответ дан 1 December 2019 в 09:31
поделиться

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

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

7
ответ дан 1 December 2019 в 09:31
поделиться

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

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

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

-2
ответ дан 1 December 2019 в 09:31
поделиться

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

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

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

4
ответ дан 1 December 2019 в 09:31
поделиться

На данный момент мне не хватает одного звена в вашем объяснении, поэтому позвольте мне перефразировать то, что я понял:

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

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

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

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

Обновление

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

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

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

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

3
ответ дан 1 December 2019 в 09:31
поделиться

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

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

2
ответ дан 1 December 2019 в 09:31
поделиться

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

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

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

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

2
ответ дан 1 December 2019 в 09:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: