Перехват печати на принтер (Windows XP и старше)

freezer

Требуется перехватить печать на принтер, сохранить в журнале информацию (что за принтер, какой документ, юзер и т.д.) - в принципе, с этим я уже разобрался ( http://msdn.microsoft.com/en-us/library/windows/desktop/dd16... ), но заказчику ещё надо, чтобы на печатаемых страницах ставились отметки (надписи в определённых местах), да ещё чтобы в определённых случаях у инициировавшего печать юзера вылезал диалог для ввода дополнительной информации, которая шла бы в журнал и использовалась для печати отметок. Куда вообще копать, где найти рабочие примеры и т.д.?

AlexV769

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

Dasar

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

freezer

Кстати насчёт стопить. Нашёл целую либу - System.Printing.dll
Тестовый код:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Printing;
using System.Text;

namespace PrinterTest
{
class Program
{
static void Main(string[] args)
{
var lps = new LocalPrintServer(PrintSystemDesiredAccess.AdministratePrinter);
var queues = lps.GetPrintQueues();
foreach(var queue in queues)
{
Console.WriteLine("Queue {0}:", queue.FullName);
try
{
queue.Pause();
}
catch(Exception e) { Console.WriteLine("Pause failed! \r\n{0}", e); }
foreach (var job in queue.GetPrintJobInfoCollection())
Console.WriteLine(" Job: {0}, pages={1}, user={2}, time={3}", job.Name, job.NumberOfPages, job.Submitter, job.TimeJobSubmitted);
}
}
}
}

Падает прям на конструкторе:
 
Необработанное исключение: System.Printing.PrintServerException: Исключение при создании объекта PrintServer. Ошибка Win32: Отказано в доступе.

в System.Printing.PrintServer.Initialize(String path, String[] propertiesFilter, PrinterDefaults printerDefaults)
в System.Printing.PrintServer..ctor(String path, PrintSystemDesiredAccess desiredAccess)
в System.Printing.LocalPrintServer..ctor(PrintSystemDesiredAccess desiredAccess)
в PrinterTest.Program.Main(String[] args) в d:\work\PrinterTest\PrinterTest\Program.cs:строка 13

При том, что юзер - админ, UAC отключён, из панели управления поставить на паузу очередь получилось :(

freezer

если в конструктор передавать PrintSystemDesiredAccess.AdministrateServer, то исключение летит на

queue.Pause();

причём, это... NullReferenceException

freezer

Переписал на плюсы (с б-жьей помощью ILSpy):

#include <Windows.h>
#include <stdio.h>

void main()
{
HANDLE hPrinter = NULL;
PRINTER_DEFAULTS pd = { NULL, NULL, PRINTER_ACCESS_ADMINISTER };
BOOL res = OpenPrinter(NULL, &hPrinter, &pd);
if (!res)
{
int err = GetLastError();
printf("Error: %d\r\n", err);
}
ClosePrinter(hPrinter);
}

тоже выдаёт ERROR_ACCESS_DENIED, а вот если задать конкретный принтер - то открывается :confused:

Dasar

поставь какой-нибудь PRINTER_ALL_ACCESS | JOB_ALL_ACCESS | SERVER_ALL_ACCESS

freezer

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