У нас есть консольное приложение, которое использует PrintDocument в C # для создания PDF с помощью встроенного принтера «Microsoft Print to PDF» в Windows 10 / Server 2016. Мы используем пакет HPC от Microsoft, поэтому это приложение может запускаться несколько раз наодин и тот же сервер - оба приложения пытаются одновременно печатать на одном принтере. Время от времени один из файлов будет иметь размер 0 байт. Я также могу найти несколько ошибок в журнале событий.
Я попытался удалить все другие принтеры, кроме Microsoft Print to PDF. Я попытался установить различные дополнительные параметры в настройках принтера (например, спулинг - так, чтобы он ожидал, пока последняя страница не будет помещена в буфер).
В нашем коде в настоящее время я проверяю размер файла после того, как считаю, что он должен быть сгенерирован - и если он равен 0 байтам, я повторяю до 3 раз. Это работает, но мне было интересно, есть ли лучшее решение для этого.
Я также пытался изменить уровень изоляции драйвера принтера - но этот параметр был отключен для этого принтера.
Следующий код должен повторить проблему. Перед запуском необходимо открыть «Просмотр событий» и перейти к «Журналы приложений и служб» -> Microsoft -> Windows -> PrintService. Щелкните правой кнопкой мыши на журнале «Оперативный» и выберите «включить» его. Журнал «Администратор» и «Оперативный» будут содержать записи в случае сбоя.
static class Program
{
static void Main()
{
var tester = new PrintPdfTest();
tester.CleanupPrev(@"C:\temp\");
tester.Run(@"C:\temp\", 5);
}
}
public class PrintPdfTest
{
private EventWaitHandle m_waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset);
public void CleanupPrev(string dir)
{
foreach (var file in Directory.GetFiles(dir, "file*.pdf"))
File.Delete(file);
}
public void Run(string dir, int nbrOfFiles)
{
var threads = new List<Thread>();
m_waitHandle.Reset();
for (int i = 0; i < nbrOfFiles; i++)
{
var fileName = Path.Combine(dir, $"file{i}.pdf");
var t = new Thread(ThreadMethod);
threads.Add(t);
t.Start(fileName);
}
// All threads created -- let them go
Thread.Sleep(1000);
m_waitHandle.Set();
foreach (var thread in threads)
thread.Join();
threads.Clear();
m_waitHandle.Dispose();
m_waitHandle = null;
Thread.Sleep(1000);
for (int i = 0; i < nbrOfFiles; i++)
{
var fileName = Path.Combine(dir, $"file{i}.pdf");
if (File.Exists(fileName))
{
var info = new FileInfo(fileName);
System.Diagnostics.Debug.WriteLine($"File {fileName} has size: {info.Length}");
}
}
}
private void ThreadMethod(object state)
{
using (var printDoc = new PrintDocument())
{
printDoc.PrintPage += PrintDoc_PrintPage;
printDoc.DefaultPageSettings.Landscape = true;
var settings = printDoc.PrinterSettings;
settings.PrinterName = "Microsoft Print to PDF";
settings.PrintToFile = true;
settings.PrintFileName = (string)state;
m_waitHandle.WaitOne();
printDoc.Print();
}
}
private void PrintDoc_PrintPage(object sender, PrintPageEventArgs e)
{
e.Graphics.DrawString(
"This is a test",
new System.Drawing.Font("Arial", 8),
System.Drawing.Brushes.Black,
30f, 30f);
}
}
После запуска кода найдите в папке C: \ Temp файлы с именем «file * .pdf». - если какой-либо из них имеет размер 0 байт, значит, проблема возникла.
При возникновении проблемы в журнале регистрируются следующие типы событий:
Идентификатор события: 824 Категория задачи: Выполнение фильтров печати в конвейере очереди печати Уровень: ошибка Произошла фатальная ошибка припечать документа задания, идентификатор 6 в очереди печати Microsoft Print to PDF. Процесс конвейера фильтра печати был прерван. Информация об ошибке: 0x88985006.
Код события: 842 Категория задачи: Изоляция драйверов принтера и других подключаемых модулей Уровень: информация Задание печати 6 было отправлено через процессор печати MS_XPS_PROC на принтер Microsoft Печать в PDF, драйвер Microsoft PrintВ PDF, в режиме изоляции 0 (0 - загружен в спулер, 1 - загружен в общую песочницу, 2 - загружен в изолированную песочницу). Код ошибки Win32, возвращенный процессором печати: 0x88985006.
Не удалось напечатать документ Print Document, принадлежащий {username}, на принтере Microsoft Print to PDF. Попробуйте распечатать документ еще раз или перезапустите диспетчер очереди печати. Тип данных: RAW. Размер файла спула в байтах: 80201. Количество напечатанных байтов: 80201. Общее количество страниц в документе: 1. Количество напечатанных страниц: 0. Клиентский компьютер: \ имя_компьютера. Код ошибки Win32, возвращенный процессором печати: 2291683334. Указанный интерфейс уже зарегистрирован.