Share via


Procedura: stampa di file XPS a livello di codice

Aggiornamento: novembre 2007

È possibile utilizzare un overload del metodo AddJob per stampare file XML Paper Specification (XPS) senza aprire un controllo PrintDialog o, in generale, alcuna interfaccia utente.

È inoltre possibile stampare file XML Paper Specification (XPS) utilizzando i diversi metodi Write e WriteAsync dell'oggetto XpsDocumentWriter. Per ulteriori informazioni, vedere Stampa di documenti XPS.

Un altro modo disponibile per stampare i file XML Paper Specification (XPS) consiste nell'utilizzare il metodo PrintDocument o PrintVisual del controllo PrintDialog. Vedere Procedura: richiamare una finestra di dialogo di stampa.

Esempio

Di seguito sono elencati i passaggi principali da eseguire per utilizzare il metodo AddJob(String, String, Boolean) con tre parametri. Nell'esempio riportato di seguito vengono forniti i dettagli.

  1. Determinare se la stampante è una stampante XPSDrv. (Per ulteriori informazioni su XPSDrv, vedere Cenni preliminari sulla stampa.)

  2. Se la stampante non è una stampante XPSDrv, impostare l'apartment del thread su un thread singolo.

  3. Creare un'istanza di un server di stampa e di un oggetto coda di stampa.

  4. Chiamare il metodo, specificando un nome di processo, il file da stampare e un flag Boolean per indicare se la stampante è o meno una stampante XPSDrv.

Nell'esempio riportato di seguito viene illustrato come stampare in modalità batch tutti i file XPS contenuti in una directory. Sebbene venga richiesto all'utente di specificare la directory, il metodo AddJob(String, String, Boolean) con tre parametri non richiede un'interfaccia utente. Può essere utilizzato in qualsiasi percorso di codice in cui sia presente il nome di un file XPS e un percorso da passare a esso.

L'overload del metodo AddJob(String, String, Boolean) con tre parametri di AddJob deve essere eseguito in un apartment a thread singolo ogni volta che il parametro Boolean è false, ovvero ogni volta che viene utilizzata una stampante non XPSDrv. Tuttavia, lo stato dell'apartment predefinito per Microsoft .NET è a più thread. Questa impostazione predefinita deve essere invertita in quanto nell'esempio si presuppone che venga utilizzata una stampante non XPSDrv.

Sono disponibili due modi per modificare l'impostazione predefinita. Un modo consiste semplicemente nell'aggiungere STAThreadAttribute (ovvero "[System.STAThreadAttribute()]") appena sopra la prima riga del metodo Main dell'applicazione, in genere "static void Main(string[] args)". Tuttavia, poiché molte applicazioni richiedono che per il metodo Main lo stato dell'apartment sia a più thread, è disponibile un secondo modo che consiste nell'inserire la chiamata a AddJob(String, String, Boolean) in un thread separato il cui stato dell'apartment sia impostato su STA con il metodo SetApartmentState. Nell'esempio riportato di seguito viene utilizzata la seconda tecnica.

Di conseguenza, l'esempio prevede innanzitutto la creazione di un'istanza di un oggetto Thread e il relativo passaggo al metodo PrintXPS come parametro ThreadStart. (Il metodo PrintXPS verrà definito più avanti nell'esempio.) In secondo luogo, il thread viene impostato su un apartment a thread singolo. Il nuovo thread verrà avviato tramite il codice rimanente del metodo Main.

La parte fondamentale dell'esempio è rappresentata dal metodo staticBatchXPSPrinter.PrintXPS. Dopo avere creato un server di stampa e una coda, viene richiesto all'utente di specificare una directory contenente i file XPS. Dopo che l'esistenza della directory e la presenza di file xps sono state accertate, ognuno di questi file viene aggiunto alla coda di stampa. Poiché nell'esempio si presuppone che la stampante non sia XPSDrv, false viene passato all'ultimo parametro del metodo AddJob(String, String, Boolean). Per questo motivo, il markup XPS verrà convalidato nel file prima che venga convertito nel linguaggio di descrizione della pagina della stampante. Se la convalida ha esito negativo, viene generata un'eccezione. Nel codice di esempio l'eccezione viene rilevata e l'utente viene notificato, dopodiché viene elaborato il file XPS successivo.

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 si utilizza una stampante XPSDrv, è possibile impostare il parametro finale su true. In questo caso, poiché XPS è il linguaggio di descrizione della pagina della stampante, il file verrà inviato alla stampante senza essere convalidato né convertito a un altro linguaggio di descrizione della pagina. Se in fase di progettazione non si è certi se verrà effettivamente utilizzata una stampante XPSDrv, è possibile modificare l'applicazione affinché venga letta la proprietà IsXpsDevice e la diramazione secondo quanto rilevato.

Poiché saranno poche le stampanti XPSDrv immediatamente disponibili dopo il rilascio di Windows Vista e Microsoft .NET Framework, potrebbe essere necessario fare passare una stampante non XPSDrv per una stampante XPSDrv. A tale scopo, aggiungere Pipelineconfig.xml all'elenco di file nella seguente chiave del Registro di sistema del computer che esegue l'applicazione:

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

in cui <PseudoXPSPrinter> è una coda di stampa qualsiasi. Riavviare il computer.

In questo modo, sarà possibile passare true come parametro finale del metodo AddJob(String, String, Boolean) senza causare un'eccezione, tuttavia poiché <PseudoXPSPrinter> non è realmente una stampante XPSDrv, verrà stampato contenuto privo di significato.

Nota   Per semplicità, nell'esempio viene utilizzata la presenza di un'estensione xps per stabilire se un file è XPS. I file XPS non devono necessariamente avere questa estensione. Strumento di Conformità isXPS rappresenta un modo per stabilire la validità dei file XPS.

Vedere anche

Attività

Stampa di documenti XPS

Concetti

Threading gestito e non gestito

Strumento di Conformità isXPS

Documenti di Windows Presentation Foundation

Cenni preliminari sulla stampa

Riferimenti

PrintQueue

AddJob

ApartmentState

STAThreadAttribute

Altre risorse

XPS

Esempi relativi alla stampa