Show / Hide Table of Contents

Практическое руководство. Печать XPS-файлов программным способом

Можно использовать перегрузку AddJob способ печати Формат XPS (XML Paper Specification) файлы, не открывая PrintDialog или, в принципе, все UI вообще.

Можно также распечатать Формат XPS (XML Paper Specification) файлов с помощью многочисленных Write и WriteAsync методы XpsDocumentWriter. Дополнительные сведения см. в разделе Печать документа XPS.

Еще один способ печати Формат XPS (XML Paper Specification) заключается в использовании PrintDocument или PrintVisual методы PrintDialog элемента управления. См. раздел Вызов диалогового окна печати.

Пример

Основные действия с помощью с тремя параметрами AddJob(String, String, Boolean) метод, как показано ниже. Подробные сведения см. в примере.

  1. Определите, является ли принтер принтером XPSDrv. (Дополнительные сведения о XPSDrv см. в разделе Обзор печати.)

  2. Если принтер не является принтером XPSDrv, задайте однопотоковое подразделение потока.

  3. Создайте экземпляр сервера печати и объект очереди печати.

  4. Вызовите метод, указав имя задания, файл для печати и Boolean флаг, указывающий, будет ли принтер принтером XPSDrv.

В приведенном ниже примере показано, как выполнить пакетную печать всех файлов XPS в каталоге. Несмотря на то, что приложение предлагает пользователю указать каталог, с тремя параметрами AddJob(String, String, Boolean) метод не требует UI . Его можно использовать в любом пути кода при условии, что вы знаете имя файла XPS и путь, который вы можете ему передать.

С тремя параметрами AddJob(String, String, Boolean) перегрузки AddJob должна выполняться в однопотоковом подразделении всякий раз, когда Boolean параметр false, который он должен быть, если используется принтер XPSDrv. Однако по умолчанию состояние подразделения для Microsoft .NET многопотоковое. Данное значение по умолчанию должно быть обращено, поскольку в этом примере предполагается, что принтер не является принтером XPSDrv.

Изменить значение по умолчанию можно одним из двух способов. Первый способ — просто добавьте STAThreadAttribute (то есть "[System.STAThreadAttribute()]«) непосредственно над первой строки приложения Main метод (обычно"static void Main(string[] args)«). Тем не менее, многие приложения требуют Main метод имеют состояние многопотокового подразделения, поэтому второй метод: поместить вызов AddJob(String, String, Boolean) в отдельном потоке, имеющий состояние подразделения присваивается STA с SetApartmentState. В следующем примере используется второй метод.

Соответственно, пример начинается с создания экземпляра Thread объекта и его передачи PrintXPS метод как ThreadStart параметр. (Метод PrintXPS определяется ниже в этом примере.) Затем для потока устанавливается однопотоковое подразделение. Остальной код метода Main начинается с нового потока.

Основу этого примера составляет метод static BatchXPSPrinter.PrintXPS. После создания сервера и очереди печати метод предлагает пользователю выбрать каталог, содержащий файлы XPS. После проверки существования каталога и наличие *.xps файлы в ней, метод добавляет каждый такой файл в очередь печати. В примере предполагается, что принтер не является принтером XPSDrv, поэтому мы передаем false для последнего параметра AddJob(String, String, Boolean) метод. В связи с этим метод проверит разметку XPS в файле и только после этого конвертирует его в язык описания страниц принтера. Если проверка завершается ошибкой, выдается исключение. Код в примере перехватит исключение, сообщит о нем пользователю, а затем перейдет к обработке следующего файла XPS.

class Program
{
    [System.MTAThreadAttribute()] // Added for clarity, but this line is redundant because MTA is the default.
    static void Main(string[] args)
    {
        // Create the secondary thread and pass the printing method for
        // the constructor's ThreadStart delegate parameter. The BatchXPSPrinter
        // class is defined below.
        Thread printingThread = new Thread(BatchXPSPrinter.PrintXPS);

        // Set the thread that will use PrintQueue.AddJob to single threading.
        printingThread.SetApartmentState(ApartmentState.STA);

        // Start the printing thread. The method passed to the Thread
        // constructor will execute.
        printingThread.Start();
    }//end Main
}//end Program class

public class BatchXPSPrinter
{
    public static void PrintXPS()
    {
        // Create print server and print queue.
        LocalPrintServer localPrintServer = new LocalPrintServer();
        PrintQueue defaultPrintQueue = LocalPrintServer.GetDefaultPrintQueue();

        // Prompt user to identify the directory, and then create the directory object.
        Console.Write("Enter the directory containing the XPS files: ");
        String directoryPath = Console.ReadLine();
        DirectoryInfo dir = new DirectoryInfo(directoryPath);

        // If the user mistyped, end the thread and return to the Main thread.
        if (!dir.Exists)
        {
            Console.WriteLine("There is no such directory.");
        }
        else
        {
            // If there are no XPS files in the directory, end the thread
            // and return to the Main thread.
            if (dir.GetFiles("*.xps").Length == 0)
            {
                Console.WriteLine("There are no XPS files in the directory.");
            }
            else
            {
                Console.WriteLine("\nJobs will now be added to the print queue.");
                Console.WriteLine("If the queue is not paused and the printer is working, jobs will begin printing.");

                // Batch process all XPS files in the directory.
                foreach (FileInfo f in dir.GetFiles("*.xps"))
                {
                    String nextFile = directoryPath + "\\" + f.Name;
                    Console.WriteLine("Adding {0} to queue.", nextFile);

                    try
                    {
                        // Print the Xps file while providing XPS validation and progress notifications.
                        PrintSystemJobInfo xpsPrintJob = defaultPrintQueue.AddJob(f.Name, nextFile, false);
                    }
                    catch (PrintJobException e)
                    {
                        Console.WriteLine("\n\t{0} could not be added to the print queue.", f.Name);
                        if (e.InnerException.Message == "File contains corrupted data.")
                        {
                            Console.WriteLine("\tIt is not a valid XPS file. Use the isXPS Conformance Tool to debug it.");
                        }
                        Console.WriteLine("\tContinuing with next XPS file.\n");
                    }
                }// end for each XPS file
            }//end if there are no XPS files in the directory
        }//end if the directory does not exist

        Console.WriteLine("Press Enter to end program.");
        Console.ReadLine();
    }// end PrintXPS method
}// end BatchXPSPrinter class

Если вы используете принтер XPSDrv, последнему параметру можно присвоить значение true. В этом случае, поскольку XPS является языком описания страниц принтера, метод отправляет файл на принтер без проверки или преобразования в другой язык описания страниц. Если вы не уверены во время разработки ли приложение будет использовать принтер XPSDrv, можно изменить приложение, чтобы оно считывало IsXpsDevice свойство и ветви, оно читало.

Так как изначально потребуется всего несколько принтеров доступны сразу же после выпуска Windows Vista и Microsoft .NET Framework, может потребоваться маскировка принтер XPSDrv, как принтер XPSDrv. Для этого добавьте файл Pipelineconfig.xml в список файлов в следующем разделе реестра компьютера, на котором выполняется ваше приложение:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Environments\Windows NT x86\Drivers\Version-3\<PseudoXPSPrinter> \DependentFiles

где <PseudoXPSPrinter>  — это любая очередь печати. После этого компьютер необходимо перезагрузить.

Эта маскировка позволит передавать true как последний параметр AddJob(String, String, Boolean) без возникновения исключения, но поскольку <PseudoXPSPrinter > деле не является принтером XPSDrv, будет распечатан только мусор.

Примечание для простоты в примере выше используется наличие *.xps расширения в качестве проверки того, что файл XPS. При этом файлы XPS не обязательно должны иметь такое расширение. isXPS.exe (isXPS Conformance Tool) является одним из способов проверки файла на соответствие XPS.

См. также

  • PrintQueue
  • AddJob
  • ApartmentState
  • STAThreadAttribute
  • XPS-документы
  • Печать документа XPS
  • Управляемые и неуправляемые потоки
  • isXPS.exe (средство проверки соответствия isXPS)
  • Документы в WPF
  • Общие сведения о печати
Back to top Неофициальная документация по .NET на русском языке. Лицензия: CC-BY 4.0. Основано на документации по .NET с Microsoft Docs
Generated by DocFX