Compartilhar via


Como: Programmatically Print XPS Files

Você pode usar uma sobrecarga do método AddJob para imprimir arquivos XML Paper Specification (XPS) sem abrir um PrintDialog ou, no princípio, qualquer um dos interface do usuário (UI).

Pode-se também imprimir arquivos XML Paper Specification (XPS) usando os muitos métodos Write e WriteAsync do XpsDocumentWriter. Para obter mais informações sobre isso, Impressão um documento XPS.

Outra maneira de impressão XML Paper Specification (XPS) é usar os métodos PrintDocument ou PrintVisual do controle PrintDialog. Consulte Como: Chamar um diálogo de impressão.

Exemplo

As principais etapas para usar o método AddJob(String, String, Boolean) de três parâmetros são da seguinte maneira. O exemplo a seguir fornece detalhes.

  1. Determine se a impressora é uma impressora XPSDrv. (Consulte Visão Geral de Impressão para obter mais informações sobre XPSDrv.)

  2. Se a impressora não for uma impressora XPSDrv, defina o apartment do thread como thread único.

  3. Criar uma instância de um servidor de impressão e objeto de fila de impressão.

  4. Chame o método, especificando um nome de trabalho, o arquivo a ser impresso e um sinalizador Boolean indicando se a impressora é uma impressora XPSDrv ou não.

O exemplo a seguir mostra como imprimir em lote todos os arquivos XPS em um diretório. Embora o aplicativo solicite ao usuário especificar a pasta, o método AddJob(String, String, Boolean) de três parâmetros não requer um interface do usuário (UI). Ele pode ser usado em qualquer caminho de código no qual exista um nome de arquivo XPS e o caminho que você pode passar para ele.

A sobrecarga AddJob(String, String, Boolean) de três-parâmetros de AddJob deve ser executado em um single thread apartment sempre que o parâmetro Boolean for false, que deve ser quando uma impressora não XPSDrv está sendo usada. No entanto, o estado apartment padrão para Microsoft .NET é de vários threads. Esse padrão deve ser revertido já que o exemplo supõe uma impressora não XPSDrv.

Há duas maneiras para alterar o padrão. Uma maneira é simplesmente adicionar a STAThreadAttribute (isto é, "[System.STAThreadAttribute()]") apenas acima da primeira linha do método Main do aplicativo (geralmente "static void Main(string[] args)"). No entanto, muitos aplicativos requerem que o Main método têm um estado de apartment multissegmentado, para que haja um segundo método: colocar a telefonar para AddJob(String, String, Boolean) em um thread separado cujo estado apartment é definido para STA com SetApartmentState. O exemplo a seguir usa essa segunda técnica.

Da mesma forma, o exemplo começa por instanciar um objeto Thread e passando-o um método PrintXPS como o parâmetro ThreadStart. (O método PrintXPS é definido posteriormente no exemplo). Em seguida o thread é definido como um single thread apartment. O código restante somente do método Main inicia o novo thread.

O ponto central do exemplo está no método static BatchXPSPrinter.PrintXPS. Depois de criar um servidor de impressão e fila, o método encaminha o usuário a um diretório que contém arquivos XPS. Após validar a existência do diretório e a presença de arquivos *.xps nele, o método adiciona cada arquivo desses para a fila de impressão. O exemplo pressupõe que a impressora é não XPSDrv, portanto, passa-se false para o último parâmetro do método AddJob(String, String, Boolean). Por esse motivo, o método validará a marcação XPS no arquivo antes de ele tentar convertê-lo em linguagem de descrição de página da impressora. Se a validação falhar, será apresentada uma exceção. O código de exemplo será pegar a exceção, notificar o usuário sobre ela e então prosseguir para processar o próximo arquivo 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

Se você estiver usando uma impressora XPSDrv, pode-se então definir o parâmetro final para true. Nesse caso, como XPS é a linguagem de descrição de página da impressora, o método será enviar o arquivo para a impressora sem validá-lo ou convertê-lo para outra linguagem de descrição de página. Se não tiver certeza no tempo de design se o aplicativo estará usando uma impressora XPSDrv, é possível modificar o aplicativo para que ele leia a propriedade IsXpsDevice e prosseguir de acordo com o que encontrar.

Como inicialmente haverá poucas impressoras XPSDrv disponíveis imediatamente após o lançamento do Windows Vista e Microsoft .NET Framework, talvez seja preciso disfarçar uma impressora não XPSDrv como uma impressora XPSDrv. Para fazer isso, adicione Pipelineconfig.xml à lista de arquivos na seguinte chave de registro do computador que executa o seu aplicativo:

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

onde < PseudoXPSPrinter > é qualquer fila de impressão. A máquina, em seguida, deve ser reinicializada.

Este disfarce permitirá que você passar true como o parâmetro final de AddJob(String, String, Boolean) sem causar uma exceção, mas como < PseudoXPSPrinter > realmente não é uma impressora XPSDrv, somente lixo será impresso.

Nota Para simplificar, o exemplo acima usa a presença de uma extensão *.xps como seu teste que um arquivo é XPS. No entanto, arquivos XPS não necessitam dessa extensão. O Ferramenta de conformidade isXPS é uma maneira de testar um arquivo para validação XPS.

Consulte também

Tarefas

Impressão um documento XPS

Conceitos

Threading gerenciado e não gerenciado

Ferramenta de conformidade isXPS

Documentos em Windows Presentation Foundation

Visão Geral de Impressão

Referência

PrintQueue

AddJob

ApartmentState

STAThreadAttribute

Outros recursos

XPS

Exemplos de impressão